00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "precompiled_starmath.hxx"
00038
00039
00040 #include <vector>
00041
00042 #ifndef _OSL_MUTEX_HXX_
00043 #include <osl/mutex.hxx>
00044 #endif
00045 #ifndef _UCBHELPER_CONTENT_HXX
00046 #include <ucbhelper/content.hxx>
00047 #endif
00048 #ifndef _SV_MSGBOX_HXX //autogen
00049 #include <vcl/msgbox.hxx>
00050 #endif
00051
00052 #ifndef _SV_RESARY_HXX
00053 #include <tools/resary.hxx>
00054 #endif
00055
00056 #ifndef _SFXDISPATCH_HXX //autogen
00057 #include <sfx2/dispatch.hxx>
00058 #endif
00059 #ifndef _SFXDOCFILE_HXX
00060 #include <sfx2/docfile.hxx>
00061 #endif
00062
00063 #include "symbol.hxx"
00064 #include "view.hxx"
00065 #include "utility.hxx"
00066 #include "dialog.hxx"
00067 #include "config.hxx"
00068 #include "cfgitem.hxx"
00069 #include "smmod.hxx"
00070 #include "starmath.hrc"
00071
00072
00073 using namespace ::com::sun::star;
00074 using namespace ::com::sun::star::ucb;
00075 using namespace ::com::sun::star::uno;
00076 using namespace ::rtl;
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 #define SF_SM20IDENT 0x03031963L
00091 #define SF_IDENT 0x30334D53L
00092
00093
00094 SV_IMPL_PTRARR( SymbolArray, SmSym * );
00095
00096
00097
00098
00099
00100
00101
00102
00103 long SF_Ident = SF_IDENT;
00104
00105
00106
00107
00108
00109
00110
00111
00112 SmSym::SmSym() :
00113 Name(C2S("unknown")),
00114 aSetName(C2S("unknown")),
00115 pHashNext(0),
00116 pSymSetManager(0),
00117 Character('\0'),
00118 bPredefined(FALSE),
00119 bDocSymbol(FALSE)
00120 {
00121 aExportName = Name;
00122 Face.SetTransparent(TRUE);
00123 Face.SetAlign(ALIGN_BASELINE);
00124 }
00125
00126
00127 SmSym::SmSym(const SmSym& rSymbol)
00128 {
00129 pSymSetManager = 0;
00130 *this = rSymbol;
00131 }
00132
00133
00134 SmSym::SmSym(const String& rName, const Font& rFont, sal_Unicode aChar,
00135 const String& rSet, BOOL bIsPredefined)
00136 {
00137 Name = aExportName = rName;
00138
00139 Face = rFont;
00140 Face.SetTransparent(TRUE);
00141 Face.SetAlign(ALIGN_BASELINE);
00142
00143 Character = aChar;
00152
00153
00154
00155 aSetName = rSet;
00156 bPredefined = bIsPredefined;
00157 bDocSymbol = FALSE;
00158
00159 pHashNext = 0;
00160 pSymSetManager = 0;
00161 }
00162
00163
00164 SmSym& SmSym::operator = (const SmSym& rSymbol)
00165 {
00166 Name = rSymbol.Name;
00167 Face = rSymbol.Face;
00168 Character = rSymbol.Character;
00169 aSetName = rSymbol.aSetName;
00170 bPredefined = rSymbol.bPredefined;
00171 bDocSymbol = rSymbol.bDocSymbol;
00172 aExportName = rSymbol.aExportName;
00173
00174 pHashNext = 0;
00175
00176 if (pSymSetManager)
00177 pSymSetManager->SetModified(TRUE);
00178
00179 return *this;
00180 }
00181
00182
00183
00184 SmSymSet::SmSymSet() :
00185 Name(C2S("unknown")),
00186 pSymSetManager(0)
00187 {
00188 SymbolList.Clear();
00189 }
00190
00191 SmSymSet::SmSymSet(const SmSymSet& rSymbolSet)
00192 {
00193 pSymSetManager = 0;
00194 *this = rSymbolSet;
00195 }
00196
00197 SmSymSet::SmSymSet(const String& rName)
00198 {
00199 Name = rName;
00200 SymbolList.Clear();
00201
00202 pSymSetManager = 0;
00203 }
00204
00205 SmSymSet::~SmSymSet()
00206 {
00207 for (USHORT i = 0; i < GetCount(); i++)
00208 delete SymbolList.GetObject(i);
00209 }
00210
00211 SmSymSet& SmSymSet::operator = (const SmSymSet& rSymbolSet)
00212 {
00213 USHORT i;
00214 for (i = 0; i < GetCount(); i++)
00215 delete SymbolList.GetObject(i);
00216
00217 Name = rSymbolSet.Name;
00218 SymbolList.Clear();
00219 for (i = 0; i < rSymbolSet.GetCount(); i++)
00220 AddSymbol(new SmSym(rSymbolSet.GetSymbol(i)));
00221
00222 if (pSymSetManager)
00223 pSymSetManager->SetModified(TRUE);
00224
00225 return *this;
00226 }
00227
00228 void SmSymSet::SetName(String& rName)
00229 {
00230 Name = rName;
00231
00232 if (pSymSetManager)
00233 pSymSetManager->SetModified(TRUE);
00234 }
00235
00236 USHORT SmSymSet::AddSymbol(SmSym* pSymbol)
00237 {
00238 DBG_ASSERT(pSymbol, "Kein Symbol");
00239
00240 if (pSymbol)
00241 pSymbol->SetSetName( GetName() );
00242 SymbolList.Insert(pSymbol, LIST_APPEND);
00243 DBG_ASSERT(SymbolList.GetPos(pSymbol) == SymbolList.Count() - 1,
00244 "Sm : ... ergibt falschen return Wert");
00245
00246 if (pSymSetManager)
00247 pSymSetManager->SetModified(TRUE);
00248
00249 return (USHORT) SymbolList.Count() - 1;
00250 }
00251
00252 void SmSymSet::DeleteSymbol(USHORT SymbolNo)
00253 {
00254 delete RemoveSymbol(SymbolNo);
00255 }
00256
00257 SmSym * SmSymSet::RemoveSymbol(USHORT SymbolNo)
00258 {
00259 DBG_ASSERT(SymbolList.GetObject(SymbolNo), "Symbol nicht vorhanden");
00260
00261 SmSym *pSym = SymbolList.GetObject(SymbolNo);
00262 SymbolList.Remove(SymbolNo);
00263
00264 if (pSymSetManager)
00265 pSymSetManager->SetModified(TRUE);
00266
00267 return pSym;
00268 }
00269
00270 USHORT SmSymSet::GetSymbolPos(const String& rName)
00271 {
00272 for (USHORT i = 0; i < GetCount(); i++)
00273 if (SymbolList.GetObject(i)->GetName() == rName)
00274 return (i);
00275
00276 return SYMBOL_NONE;
00277 }
00278
00279
00280
00281 SmSymSetManager_Impl::SmSymSetManager_Impl(
00282 SmSymSetManager &rMgr, USHORT HashTableSize ) :
00283
00284 rSymSetMgr (rMgr)
00285 {
00286 NoSymbolSets = 0;
00287 NoHashEntries = HashTableSize;
00288 HashEntries = new SmSym *[NoHashEntries];
00289 memset( HashEntries, 0, sizeof(SmSym *) * NoHashEntries );
00290 Modified = FALSE;
00291 }
00292
00293
00294 SmSymSetManager_Impl::~SmSymSetManager_Impl()
00295 {
00296 for (USHORT i = 0; i < NoSymbolSets; ++i)
00297 delete SymbolSets.Get(i);
00298 SymbolSets.Clear();
00299
00300 NoSymbolSets = 0;
00301 if (HashEntries)
00302 {
00303 delete[] HashEntries;
00304 HashEntries = 0;
00305 }
00306 NoHashEntries = 0;
00307 Modified = FALSE;
00308 }
00309
00310
00311 SmSymSetManager_Impl & SmSymSetManager_Impl::operator = ( const SmSymSetManager_Impl &rImpl )
00312 {
00314
00315 NoHashEntries = rImpl.NoHashEntries;
00316 if (HashEntries)
00317 delete [] HashEntries;
00318 HashEntries = new SmSym *[NoHashEntries];
00319 memset( HashEntries, 0, sizeof(SmSym *) * NoHashEntries );
00320
00321 NoSymbolSets = 0;
00322 SymbolSets.Clear();
00323 for (USHORT i = 0; i < rImpl.NoSymbolSets; ++i)
00324 {
00325 rSymSetMgr.AddSymbolSet( new SmSymSet( *rImpl.rSymSetMgr.GetSymbolSet(i) ) );
00326 }
00327 DBG_ASSERT( NoSymbolSets == rImpl.NoSymbolSets,
00328 "incorrect number of symbolsets" );
00329
00330 Modified = TRUE;
00331 return *this;
00332 }
00333
00334
00335
00336 void SmSymSetManager::SFX_NOTIFY(SfxBroadcaster& , const TypeId& rBCType,
00337 const SfxHint& , const TypeId& rHintType)
00338 {
00339 }
00340
00341
00342 UINT32 SmSymSetManager::GetHashIndex(const String& rSymbolName)
00343 {
00344 UINT32 x = 1;
00345 for (xub_StrLen i = 0; i < rSymbolName.Len(); i++)
00346 x += x * rSymbolName.GetChar(i) + i;
00347
00348 return x % pImpl->NoHashEntries;
00349 }
00350
00351
00352 void SmSymSetManager::EnterHashTable(SmSym& rSymbol)
00353 {
00354 int j = GetHashIndex( rSymbol.GetName() );
00355 if (pImpl->HashEntries[j] == 0)
00356 pImpl->HashEntries[j] = &rSymbol;
00357 else
00358 {
00359 SmSym *p = pImpl->HashEntries[j];
00360 while (p->pHashNext)
00361 p = p->pHashNext;
00362 p->pHashNext = &rSymbol;
00363 }
00364 rSymbol.pHashNext = 0;
00365 }
00366
00367
00368 void SmSymSetManager::EnterHashTable(SmSymSet& rSymbolSet)
00369 {
00370 for (USHORT i = 0; i < rSymbolSet.GetCount(); i++)
00371 EnterHashTable( *rSymbolSet.SymbolList.GetObject(i) );
00372 }
00373
00374 void SmSymSetManager::FillHashTable()
00375 {
00376 if (pImpl->HashEntries)
00377 {
00378 memset( pImpl->HashEntries, 0, pImpl->NoHashEntries * sizeof(SmSym *) );
00379
00380 for (UINT32 i = 0; i < pImpl->NoSymbolSets; i++)
00381 EnterHashTable( *GetSymbolSet( (USHORT) i ) );
00382 }
00383 }
00384
00385 void SmSymSetManager::Init()
00386 {
00387 SmModule *pp = SM_MOD1();
00388 StartListening(*pp->GetConfig());
00389 }
00390
00391
00392 void SmSymSetManager::Exit()
00393 {
00394 SmModule *pp = SM_MOD1();
00395 EndListening(*pp->GetConfig());
00396 }
00397
00398
00399 SmSymSetManager::SmSymSetManager(USHORT HashTableSize)
00400 {
00401 pImpl = new SmSymSetManager_Impl( *this, HashTableSize );
00402 }
00403
00404
00405 SmSymSetManager::SmSymSetManager(const SmSymSetManager& rSymbolSetManager) :
00406 SfxListener()
00407 {
00408 pImpl = new SmSymSetManager_Impl( *this, rSymbolSetManager.pImpl->NoHashEntries );
00409 *pImpl = *rSymbolSetManager.pImpl;
00410 }
00411
00412
00413 SmSymSetManager::~SmSymSetManager()
00414 {
00415 delete pImpl;
00416 pImpl = 0;
00417 }
00418
00419 SmSymSetManager& SmSymSetManager::operator = (const SmSymSetManager& rSymbolSetManager)
00420 {
00421 *pImpl = *rSymbolSetManager.pImpl;
00422 return *this;
00423 }
00424
00425 USHORT SmSymSetManager::AddSymbolSet(SmSymSet* pSymbolSet)
00426 {
00427 if (pImpl->NoSymbolSets >= pImpl->SymbolSets.GetSize())
00428 pImpl->SymbolSets.SetSize(pImpl->NoSymbolSets + 1);
00429
00430 pImpl->SymbolSets.Put(pImpl->NoSymbolSets++, pSymbolSet);
00431
00432 pSymbolSet->pSymSetManager = this;
00433
00434 for (USHORT i = 0; i < pSymbolSet->GetCount(); i++)
00435 pSymbolSet->SymbolList.GetObject(i)->pSymSetManager = this;
00436
00437 FillHashTable();
00438 pImpl->Modified = TRUE;
00439
00440 return (USHORT) (pImpl->NoSymbolSets - 1);
00441 }
00442
00443 void SmSymSetManager::ChangeSymbolSet(SmSymSet* pSymbolSet)
00444 {
00445 if (pSymbolSet)
00446 {
00447 FillHashTable();
00448 pImpl->Modified = TRUE;
00449 }
00450 }
00451
00452 void SmSymSetManager::DeleteSymbolSet(USHORT SymbolSetNo)
00453 {
00454 delete pImpl->SymbolSets.Get(SymbolSetNo);
00455 pImpl->NoSymbolSets--;
00456
00457 for (UINT32 i = SymbolSetNo; i < pImpl->NoSymbolSets; i++)
00458 pImpl->SymbolSets.Put(i, pImpl->SymbolSets.Get(i + 1));
00459
00460 FillHashTable();
00461
00462 pImpl->Modified = TRUE;
00463 }
00464
00465
00466 USHORT SmSymSetManager::GetSymbolSetPos(const String& rSymbolSetName) const
00467 {
00468 for (USHORT i = 0; i < pImpl->NoSymbolSets; i++)
00469 if (pImpl->SymbolSets.Get(i)->GetName() == rSymbolSetName)
00470 return (i);
00471
00472 return SYMBOLSET_NONE;
00473 }
00474
00475 SmSym *SmSymSetManager::GetSymbolByName(const String& rSymbolName)
00476 {
00477 SmSym *pSym = pImpl->HashEntries[GetHashIndex(rSymbolName)];
00478 while (pSym)
00479 {
00480 if (pSym->Name == rSymbolName)
00481 break;
00482 pSym = pSym->pHashNext;
00483 }
00484
00485 return pSym;
00486 }
00487
00488
00489 void SmSymSetManager::AddReplaceSymbol( const SmSym &rSymbol )
00490 {
00491 SmSym *pSym = GetSymbolByName( rSymbol.GetName() );
00492 if (pSym)
00493 {
00494 *pSym = rSymbol;
00495 }
00496 else
00497 {
00498 USHORT nPos = GetSymbolSetPos( rSymbol.GetSetName() );
00499 if (SYMBOLSET_NONE == nPos)
00500 {
00501 AddSymbolSet( new SmSymSet( rSymbol.GetSetName() ) );
00502 nPos = GetSymbolSetPos( rSymbol.GetSetName() );
00503 }
00504 DBG_ASSERT( nPos != SYMBOLSET_NONE, "SymbolSet not found");
00505 SmSym *pTmpSym = new SmSym( rSymbol );
00506 GetSymbolSet( nPos )->AddSymbol( pTmpSym );
00507 EnterHashTable( *pTmpSym );
00508 }
00509 SetModified( TRUE );
00510 }
00511
00512
00513 USHORT SmSymSetManager::GetSymbolCount() const
00514 {
00515 USHORT nRes = 0;
00516 USHORT nSets = GetSymbolSetCount();
00517 for (USHORT i = 0; i < nSets; ++i)
00518 nRes = nRes + GetSymbolSet(i)->GetCount();
00519 return nRes;
00520 }
00521
00522
00523 const SmSym * SmSymSetManager::GetSymbolByPos( USHORT nPos ) const
00524 {
00525 const SmSym *pRes = 0;
00526
00527 INT16 nIdx = 0;
00528 USHORT nSets = GetSymbolSetCount();
00529 USHORT i = 0;
00530 while (i < nSets && !pRes)
00531 {
00532 USHORT nEntries = GetSymbolSet(i)->GetCount();
00533 if (nPos < nIdx + nEntries)
00534 pRes = &GetSymbolSet(i)->GetSymbol( nPos - nIdx );
00535 else
00536 nIdx = nIdx + nEntries;
00537 ++i;
00538 }
00539
00540 return pRes;
00541 }
00542
00543
00544 void SmSymSetManager::GetSymbols( std::vector< SmSym > &rSymbols ) const
00545 {
00546 INT32 nCount = GetSymbolCount();
00547 rSymbols.resize( nCount );
00548 USHORT nPos = 0;
00549 std::vector< SmSym >::iterator aIt( rSymbols.begin() );
00550 std::vector< SmSym >::iterator aEnd( rSymbols.end() );
00551 while (aIt != aEnd)
00552 {
00553 const SmSym *pSym = GetSymbolByPos( nPos++ );
00554 DBG_ASSERT( pSym, "symbol missing" );
00555 if (pSym)
00556 *aIt++ = *pSym;
00557 }
00558 DBG_ASSERT( nPos == nCount, "index out of range?" );
00559 }
00560
00561
00562 void SmSymSetManager::Load()
00563 {
00564 std::vector< SmSym > aSymbols;
00565 SmMathConfig &rCfg = *SM_MOD1()->GetConfig();
00566 rCfg.GetSymbols( aSymbols );
00567 INT32 nSymbolCount = aSymbols.size();
00568
00569 USHORT i;
00570 for (i = 0; i < nSymbolCount; ++i)
00571 {
00572 const SmSym &rSym = aSymbols[i];
00573 DBG_ASSERT( rSym.Name.Len() > 0, "symbol without name!" );
00574 if (rSym.Name.Len() > 0)
00575 {
00576 SmSymSet *pSymSet = 0;
00577 const String &rSetName = rSym.GetSetName();
00578 USHORT nSetPos = GetSymbolSetPos( rSetName );
00579 if (SYMBOLSET_NONE != nSetPos)
00580 pSymSet = GetSymbolSet( nSetPos );
00581 else
00582 {
00583 pSymSet = new SmSymSet( rSetName );
00584 AddSymbolSet( pSymSet );
00585 }
00586
00587 pSymSet->AddSymbol( new SmSym( rSym ) );
00588 }
00589 }
00590
00591 INT32 nSymbolSetCount = GetSymbolSetCount();
00592 for (i = 0; i < nSymbolSetCount; ++i)
00593 ChangeSymbolSet( GetSymbolSet( i ) );
00594
00595 if (0 == nSymbolCount)
00596 {
00597 DBG_ERROR( "no symbol set found" );
00598 pImpl->Modified = FALSE;
00599 }
00600 }
00601
00602 void SmSymSetManager::Save()
00603 {
00604 SmMathConfig &rCfg = *SM_MOD1()->GetConfig();
00605
00606
00607 USHORT nSymbolCount = 0;
00608 USHORT nSetCount = GetSymbolSetCount();
00609 USHORT i;
00610 for (i = 0; i < nSetCount; ++i)
00611 nSymbolCount = nSymbolCount + GetSymbolSet( i )->GetCount();
00612
00613 if (nSymbolCount)
00614 {
00615 USHORT nSaveSymbolCnt = 0;
00616 const SmSym **pSymbols = new const SmSym* [ nSymbolCount ];
00617 const SmSym **pSym = pSymbols;
00618 for (i = 0; i < nSetCount; ++i)
00619 {
00620 const SmSymSet *pSymSet = GetSymbolSet( i );
00621 USHORT n = pSymSet->GetCount();
00622 for (USHORT j = 0; j < n; ++j)
00623 {
00624 const SmSym &rSym = pSymSet->GetSymbol( j );
00625 if (!rSym.IsDocSymbol())
00626 {
00627 *pSym++ = &rSym;
00628 ++nSaveSymbolCnt;
00629 }
00630 }
00631 }
00632 DBG_ASSERT(pSym - pSymbols == nSaveSymbolCnt, "wrong number of symbols" );
00633
00634 std::vector< SmSym > aSymbols;
00635 GetSymbols( aSymbols );
00636 rCfg.SetSymbols( aSymbols );
00637 delete [] pSymbols;
00638 }
00639 }
00640
00641