/Users/ericb/Desktop/SRC680_m247/starmath/source/symbol.cxx

Go to the documentation of this file.
00001 /*************************************************************************
00002  *
00003  *  OpenOffice.org - a multi-platform office productivity suite
00004  *
00005  *  $RCSfile: symbol.cxx,v $
00006  *
00007  *  $Revision: 1.29 $
00008  *
00009  *  last change: $Author: vg $ $Date: 2007/05/25 12:15:27 $
00010  *
00011  *  The Contents of this file are made available subject to
00012  *  the terms of GNU Lesser General Public License Version 2.1.
00013  *
00014  *
00015  *    GNU Lesser General Public License Version 2.1
00016  *    =============================================
00017  *    Copyright 2005 by Sun Microsystems, Inc.
00018  *    901 San Antonio Road, Palo Alto, CA 94303, USA
00019  *
00020  *    This library is free software; you can redistribute it and/or
00021  *    modify it under the terms of the GNU Lesser General Public
00022  *    License version 2.1, as published by the Free Software Foundation.
00023  *
00024  *    This library is distributed in the hope that it will be useful,
00025  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00026  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00027  *    Lesser General Public License for more details.
00028  *
00029  *    You should have received a copy of the GNU Lesser General Public
00030  *    License along with this library; if not, write to the Free Software
00031  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00032  *    MA  02111-1307  USA
00033  *
00034  ************************************************************************/
00035 
00036 // MARKER(update_precomp.py): autogen include statement, do not remove
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 // Das hier muss auch mal alles "uberarbeitet werden. Insbesondere die nicht
00079 // funktionierende und bei l"oschen/"andern von Symbolen nicht gepflegte
00080 // Hash Tabelle!!!  Diese aktualisert sich erst im Wertzuweisungsoperator
00081 // beim Verlassen des 'SmSymDefineDialog's!
00082 
00083 /**************************************************************************/
00084 /*
00085 **
00086 **      MACRO DEFINTION
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 **      DATA DEFINITION
00100 **
00101 **/
00102 
00103 long                            SF_Ident = SF_IDENT;
00104 
00105 /**************************************************************************/
00106 /*
00107 **
00108 **      CLASS IMPLEMENTATION
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 //    if (RTL_TEXTENCODING_SYMBOL == rFont.GetCharSet())
00154 //        Character |= 0xF000;
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& /*rBC*/, const TypeId& rBCType,
00337                               const SfxHint& /*rHint*/, 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     // build HashTables
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     // get number of Symbols
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 

Generated on Wed Feb 20 17:21:57 2008 for maths by  doxygen 1.5.1