xref: /aoo42x/main/starmath/source/symbol.cxx (revision d107581f)
1*d107581fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*d107581fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*d107581fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*d107581fSAndrew Rist  * distributed with this work for additional information
6*d107581fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*d107581fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*d107581fSAndrew Rist  * "License"); you may not use this file except in compliance
9*d107581fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*d107581fSAndrew Rist  *
11*d107581fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*d107581fSAndrew Rist  *
13*d107581fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*d107581fSAndrew Rist  * software distributed under the License is distributed on an
15*d107581fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*d107581fSAndrew Rist  * KIND, either express or implied.  See the License for the
17*d107581fSAndrew Rist  * specific language governing permissions and limitations
18*d107581fSAndrew Rist  * under the License.
19*d107581fSAndrew Rist  *
20*d107581fSAndrew Rist  *************************************************************/
21*d107581fSAndrew Rist 
22*d107581fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_starmath.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include <vector>
29cdf0e10cSrcweir #include <osl/mutex.hxx>
30cdf0e10cSrcweir #include <ucbhelper/content.hxx>
31cdf0e10cSrcweir #include <vcl/msgbox.hxx>
32cdf0e10cSrcweir 
33cdf0e10cSrcweir #include <sfx2/dispatch.hxx>
34cdf0e10cSrcweir #include <sfx2/docfile.hxx>
35cdf0e10cSrcweir 
36cdf0e10cSrcweir #include <map>
37cdf0e10cSrcweir #include <vector>
38cdf0e10cSrcweir #include <iterator>
39cdf0e10cSrcweir 
40cdf0e10cSrcweir #include "symbol.hxx"
41cdf0e10cSrcweir #include "view.hxx"
42cdf0e10cSrcweir #include "utility.hxx"
43cdf0e10cSrcweir #include "dialog.hxx"
44cdf0e10cSrcweir #include "config.hxx"
45cdf0e10cSrcweir #include "cfgitem.hxx"
46cdf0e10cSrcweir #include "smmod.hxx"
47cdf0e10cSrcweir #include "starmath.hrc"
48cdf0e10cSrcweir 
49cdf0e10cSrcweir 
50cdf0e10cSrcweir using namespace ::com::sun::star;
51cdf0e10cSrcweir using namespace ::com::sun::star::ucb;
52cdf0e10cSrcweir using namespace ::com::sun::star::uno;
53cdf0e10cSrcweir using namespace ::rtl;
54cdf0e10cSrcweir 
55cdf0e10cSrcweir 
56cdf0e10cSrcweir /**************************************************************************/
57cdf0e10cSrcweir 
SmSym()58cdf0e10cSrcweir SmSym::SmSym() :
59cdf0e10cSrcweir     m_aName(C2S("unknown")),
60cdf0e10cSrcweir     m_aSetName(C2S("unknown")),
61cdf0e10cSrcweir     m_cChar('\0'),
62cdf0e10cSrcweir     m_bPredefined(sal_False),
63cdf0e10cSrcweir     m_bDocSymbol(sal_False)
64cdf0e10cSrcweir {
65cdf0e10cSrcweir     m_aExportName = m_aName;
66cdf0e10cSrcweir     m_aFace.SetTransparent(sal_True);
67cdf0e10cSrcweir     m_aFace.SetAlign(ALIGN_BASELINE);
68cdf0e10cSrcweir }
69cdf0e10cSrcweir 
70cdf0e10cSrcweir 
SmSym(const SmSym & rSymbol)71cdf0e10cSrcweir SmSym::SmSym(const SmSym& rSymbol)
72cdf0e10cSrcweir {
73cdf0e10cSrcweir     *this = rSymbol;
74cdf0e10cSrcweir }
75cdf0e10cSrcweir 
76cdf0e10cSrcweir 
SmSym(const String & rName,const Font & rFont,sal_UCS4 cChar,const String & rSet,sal_Bool bIsPredefined)77cdf0e10cSrcweir SmSym::SmSym(const String& rName, const Font& rFont, sal_UCS4 cChar,
78cdf0e10cSrcweir 			 const String& rSet, sal_Bool bIsPredefined)
79cdf0e10cSrcweir {
80cdf0e10cSrcweir     m_aName     = m_aExportName   = rName;
81cdf0e10cSrcweir 
82cdf0e10cSrcweir     m_aFace     = rFont;
83cdf0e10cSrcweir     m_aFace.SetTransparent(sal_True);
84cdf0e10cSrcweir     m_aFace.SetAlign(ALIGN_BASELINE);
85cdf0e10cSrcweir 
86cdf0e10cSrcweir     m_cChar   = cChar;
87cdf0e10cSrcweir //! according to HDU this should not be used anymore now
88cdf0e10cSrcweir //! since this was necessary in the early days but should
89cdf0e10cSrcweir //! not be done now since this is handled now at a more
90cdf0e10cSrcweir //! bottom layer by HDU.
91cdf0e10cSrcweir //! He can still imagine scenarios where this will be wrong
92cdf0e10cSrcweir //! now though, for example when importing *some* old documents.
93cdf0e10cSrcweir //! But overall it should be a large improvement, and
94cdf0e10cSrcweir //! likely everything will still work... #_- (eyes shut and "go"!)
95cdf0e10cSrcweir //
96cdf0e10cSrcweir //    if (RTL_TEXTENCODING_SYMBOL == rFont.GetCharSet())
97cdf0e10cSrcweir //        Character |= 0xF000;
98cdf0e10cSrcweir     m_aSetName      = rSet;
99cdf0e10cSrcweir     m_bPredefined   = bIsPredefined;
100cdf0e10cSrcweir     m_bDocSymbol    = sal_False;
101cdf0e10cSrcweir }
102cdf0e10cSrcweir 
103cdf0e10cSrcweir 
operator =(const SmSym & rSymbol)104cdf0e10cSrcweir SmSym& SmSym::operator = (const SmSym& rSymbol)
105cdf0e10cSrcweir {
106cdf0e10cSrcweir     m_aName         = rSymbol.m_aName;
107cdf0e10cSrcweir     m_aExportName   = rSymbol.m_aExportName;
108cdf0e10cSrcweir     m_cChar         = rSymbol.m_cChar;
109cdf0e10cSrcweir     m_aFace         = rSymbol.m_aFace;
110cdf0e10cSrcweir     m_aSetName      = rSymbol.m_aSetName;
111cdf0e10cSrcweir     m_bPredefined   = rSymbol.m_bPredefined;
112cdf0e10cSrcweir     m_bDocSymbol    = rSymbol.m_bDocSymbol;
113cdf0e10cSrcweir 
114cdf0e10cSrcweir     SmSymbolManager * pSymSetManager = &SM_MOD()->GetSymbolManager();
115cdf0e10cSrcweir     if (pSymSetManager)
116cdf0e10cSrcweir         pSymSetManager->SetModified(true);
117cdf0e10cSrcweir 
118cdf0e10cSrcweir 	return *this;
119cdf0e10cSrcweir }
120cdf0e10cSrcweir 
121cdf0e10cSrcweir 
IsEqualInUI(const SmSym & rSymbol) const122cdf0e10cSrcweir bool SmSym::IsEqualInUI( const SmSym& rSymbol ) const
123cdf0e10cSrcweir {
124cdf0e10cSrcweir     return  m_aName == rSymbol.m_aName &&
125cdf0e10cSrcweir             m_aFace == rSymbol.m_aFace &&
126cdf0e10cSrcweir             m_cChar == rSymbol.m_cChar;
127cdf0e10cSrcweir }
128cdf0e10cSrcweir 
129cdf0e10cSrcweir /**************************************************************************/
130cdf0e10cSrcweir 
SFX_NOTIFY(SfxBroadcaster &,const TypeId & rBCType,const SfxHint &,const TypeId & rHintType)131cdf0e10cSrcweir void SmSymbolManager::SFX_NOTIFY(SfxBroadcaster& /*rBC*/, const TypeId& rBCType,
132cdf0e10cSrcweir                               const SfxHint& /*rHint*/, const TypeId& rHintType)
133cdf0e10cSrcweir {
134cdf0e10cSrcweir }
135cdf0e10cSrcweir 
136cdf0e10cSrcweir 
Init()137cdf0e10cSrcweir void SmSymbolManager::Init()
138cdf0e10cSrcweir {
139cdf0e10cSrcweir     SmModule *pp = SM_MOD();
140cdf0e10cSrcweir 	StartListening(*pp->GetConfig());
141cdf0e10cSrcweir }
142cdf0e10cSrcweir 
143cdf0e10cSrcweir 
Exit()144cdf0e10cSrcweir void SmSymbolManager::Exit()
145cdf0e10cSrcweir {
146cdf0e10cSrcweir     SmModule *pp = SM_MOD();
147cdf0e10cSrcweir 	EndListening(*pp->GetConfig());
148cdf0e10cSrcweir }
149cdf0e10cSrcweir 
150cdf0e10cSrcweir 
SmSymbolManager()151cdf0e10cSrcweir SmSymbolManager::SmSymbolManager()
152cdf0e10cSrcweir {
153cdf0e10cSrcweir     m_bModified     = false;
154cdf0e10cSrcweir }
155cdf0e10cSrcweir 
156cdf0e10cSrcweir 
SmSymbolManager(const SmSymbolManager & rSymbolSetManager)157cdf0e10cSrcweir SmSymbolManager::SmSymbolManager(const SmSymbolManager& rSymbolSetManager) :
158cdf0e10cSrcweir     SfxListener()
159cdf0e10cSrcweir {
160cdf0e10cSrcweir     m_aSymbols      = rSymbolSetManager.m_aSymbols;
161cdf0e10cSrcweir     m_bModified     = true;
162cdf0e10cSrcweir }
163cdf0e10cSrcweir 
164cdf0e10cSrcweir 
~SmSymbolManager()165cdf0e10cSrcweir SmSymbolManager::~SmSymbolManager()
166cdf0e10cSrcweir {
167cdf0e10cSrcweir }
168cdf0e10cSrcweir 
169cdf0e10cSrcweir 
operator =(const SmSymbolManager & rSymbolSetManager)170cdf0e10cSrcweir SmSymbolManager& SmSymbolManager::operator = (const SmSymbolManager& rSymbolSetManager)
171cdf0e10cSrcweir {
172cdf0e10cSrcweir     m_aSymbols      = rSymbolSetManager.m_aSymbols;
173cdf0e10cSrcweir     m_bModified     = true;
174cdf0e10cSrcweir 	return *this;
175cdf0e10cSrcweir }
176cdf0e10cSrcweir 
177cdf0e10cSrcweir 
GetSymbolByName(const String & rSymbolName)178cdf0e10cSrcweir SmSym *SmSymbolManager::GetSymbolByName(const String& rSymbolName)
179cdf0e10cSrcweir {
180cdf0e10cSrcweir     SmSym *pRes = NULL;
181cdf0e10cSrcweir     SymbolMap_t::iterator aIt( m_aSymbols.find( rSymbolName ) );
182cdf0e10cSrcweir     if (aIt != m_aSymbols.end())
183cdf0e10cSrcweir         pRes = &aIt->second;
184cdf0e10cSrcweir     return pRes;
185cdf0e10cSrcweir }
186cdf0e10cSrcweir 
187cdf0e10cSrcweir 
GetSymbols() const188cdf0e10cSrcweir const SymbolPtrVec_t SmSymbolManager::GetSymbols() const
189cdf0e10cSrcweir {
190cdf0e10cSrcweir     SymbolPtrVec_t aRes;
191cdf0e10cSrcweir     SymbolMap_t::const_iterator aIt( m_aSymbols.begin() );
192cdf0e10cSrcweir     for ( ; aIt != m_aSymbols.end(); ++aIt)
193cdf0e10cSrcweir         aRes.push_back( &aIt->second );
194cdf0e10cSrcweir //    DBG_ASSERT( sSymbols.size() == m_aSymbols.size(), "number of symbols mismatch " );
195cdf0e10cSrcweir     return aRes;
196cdf0e10cSrcweir }
197cdf0e10cSrcweir 
198cdf0e10cSrcweir 
AddOrReplaceSymbol(const SmSym & rSymbol,bool bForceChange)199cdf0e10cSrcweir bool SmSymbolManager::AddOrReplaceSymbol( const SmSym &rSymbol, bool bForceChange )
200cdf0e10cSrcweir {
201cdf0e10cSrcweir     bool bAdded = false;
202cdf0e10cSrcweir 
203cdf0e10cSrcweir     const String aSymbolName( rSymbol.GetName() );
204cdf0e10cSrcweir     if (aSymbolName.Len() > 0 && rSymbol.GetSymbolSetName().Len() > 0)
205cdf0e10cSrcweir     {
206cdf0e10cSrcweir         const SmSym *pFound = GetSymbolByName( aSymbolName );
207cdf0e10cSrcweir         const bool bSymbolConflict = pFound && !pFound->IsEqualInUI( rSymbol );
208cdf0e10cSrcweir 
209cdf0e10cSrcweir         // avoid having the same symbol name twice but with different symbols in use
210cdf0e10cSrcweir         if (!pFound || bForceChange)
211cdf0e10cSrcweir         {
212cdf0e10cSrcweir             m_aSymbols[ aSymbolName ] = rSymbol;
213cdf0e10cSrcweir             bAdded = true;
214cdf0e10cSrcweir         }
215cdf0e10cSrcweir         else if (pFound && !bForceChange && bSymbolConflict)
216cdf0e10cSrcweir         {
217cdf0e10cSrcweir             // TODO: to solve this a document owned symbol manager would be required ...
218cdf0e10cSrcweir             // But for now we have a global one to easily support availability of all
219cdf0e10cSrcweir             // symbols in all formulas. A copy of the global one would be needed here
220cdf0e10cSrcweir             // and then the new symbol has to be forcefully applied. This would keep
221cdf0e10cSrcweir             // the current formula intact but will leave the set of symbols in the
222cdf0e10cSrcweir             // global symbol manager somewhat to chance.
223cdf0e10cSrcweir             DBG_ASSERT( 0, "symbol conflict, different symbol with same name found!" );
224cdf0e10cSrcweir         }
225cdf0e10cSrcweir 
226cdf0e10cSrcweir         if (bAdded)
227cdf0e10cSrcweir             m_bModified = true;
228cdf0e10cSrcweir         DBG_ASSERT( bAdded || (pFound && !bSymbolConflict), "AddOrReplaceSymbol: unresolved symbol conflict" );
229cdf0e10cSrcweir     }
230cdf0e10cSrcweir 
231cdf0e10cSrcweir     return bAdded;
232cdf0e10cSrcweir }
233cdf0e10cSrcweir 
234cdf0e10cSrcweir 
RemoveSymbol(const String & rSymbolName)235cdf0e10cSrcweir void SmSymbolManager::RemoveSymbol( const String & rSymbolName )
236cdf0e10cSrcweir {
237cdf0e10cSrcweir     if (rSymbolName.Len() > 0)
238cdf0e10cSrcweir     {
239cdf0e10cSrcweir         size_t nOldSize = m_aSymbols.size();
240cdf0e10cSrcweir         m_aSymbols.erase( rSymbolName );
241cdf0e10cSrcweir         m_bModified = nOldSize != m_aSymbols.size();
242cdf0e10cSrcweir     }
243cdf0e10cSrcweir }
244cdf0e10cSrcweir 
245cdf0e10cSrcweir 
GetSymbolSetNames() const246cdf0e10cSrcweir std::set< String > SmSymbolManager::GetSymbolSetNames() const
247cdf0e10cSrcweir {
248cdf0e10cSrcweir     std::set< String >  aRes;
249cdf0e10cSrcweir     SymbolMap_t::const_iterator aIt( m_aSymbols.begin() );
250cdf0e10cSrcweir     for ( ; aIt != m_aSymbols.end(); ++aIt )
251cdf0e10cSrcweir         aRes.insert( aIt->second.GetSymbolSetName() );
252cdf0e10cSrcweir     return aRes;
253cdf0e10cSrcweir }
254cdf0e10cSrcweir 
255cdf0e10cSrcweir 
GetSymbolSet(const String & rSymbolSetName)256cdf0e10cSrcweir const SymbolPtrVec_t SmSymbolManager::GetSymbolSet( const String& rSymbolSetName )
257cdf0e10cSrcweir {
258cdf0e10cSrcweir     SymbolPtrVec_t aRes;
259cdf0e10cSrcweir     if (rSymbolSetName.Len() > 0)
260cdf0e10cSrcweir     {
261cdf0e10cSrcweir         SymbolMap_t::const_iterator aIt( m_aSymbols.begin() );
262cdf0e10cSrcweir         for ( ; aIt != m_aSymbols.end(); ++aIt )
263cdf0e10cSrcweir         {
264cdf0e10cSrcweir             if (aIt->second.GetSymbolSetName() == rSymbolSetName)
265cdf0e10cSrcweir                 aRes.push_back( &aIt->second );
266cdf0e10cSrcweir         }
267cdf0e10cSrcweir     }
268cdf0e10cSrcweir     return aRes;
269cdf0e10cSrcweir }
270cdf0e10cSrcweir 
271cdf0e10cSrcweir 
Load()272cdf0e10cSrcweir void SmSymbolManager::Load()
273cdf0e10cSrcweir {
274cdf0e10cSrcweir     std::vector< SmSym > aSymbols;
275cdf0e10cSrcweir     SmMathConfig &rCfg = *SM_MOD()->GetConfig();
276cdf0e10cSrcweir     rCfg.GetSymbols( aSymbols );
277cdf0e10cSrcweir     size_t nSymbolCount = aSymbols.size();
278cdf0e10cSrcweir 
279cdf0e10cSrcweir     m_aSymbols.clear();
280cdf0e10cSrcweir     for (size_t i = 0;  i < nSymbolCount;  ++i)
281cdf0e10cSrcweir     {
282cdf0e10cSrcweir         const SmSym &rSym = aSymbols[i];
283cdf0e10cSrcweir         DBG_ASSERT( rSym.GetName().Len() > 0, "symbol without name!" );
284cdf0e10cSrcweir         if (rSym.GetName().Len() > 0)
285cdf0e10cSrcweir             AddOrReplaceSymbol( rSym );
286cdf0e10cSrcweir     }
287cdf0e10cSrcweir     m_bModified = true;
288cdf0e10cSrcweir 
289cdf0e10cSrcweir     if (0 == nSymbolCount)
290cdf0e10cSrcweir     {
291cdf0e10cSrcweir         DBG_ERROR( "no symbol set found" );
292cdf0e10cSrcweir         m_bModified = false;
293cdf0e10cSrcweir     }
294cdf0e10cSrcweir 
295cdf0e10cSrcweir     // now add a %i... symbol to the 'iGreek' set for every symbol found in the 'Greek' set.
296cdf0e10cSrcweir     SmLocalizedSymbolData   aLocalizedData;
297cdf0e10cSrcweir     const String aGreekSymbolSetName( aLocalizedData.GetUiSymbolSetName( A2OU("Greek") ) );
298cdf0e10cSrcweir     const SymbolPtrVec_t    aGreekSymbols( GetSymbolSet( aGreekSymbolSetName ) );
299cdf0e10cSrcweir     String aSymbolSetName( (sal_Unicode) 'i' );
300cdf0e10cSrcweir     aSymbolSetName += aGreekSymbolSetName;
301cdf0e10cSrcweir     size_t nSymbols = aGreekSymbols.size();
302cdf0e10cSrcweir     for (size_t i = 0;  i < nSymbols;  ++i)
303cdf0e10cSrcweir     {
304cdf0e10cSrcweir         // make the new symbol a copy but with ITALIC_NORMAL, and add it to iGreek
305cdf0e10cSrcweir         const SmSym &rSym = *aGreekSymbols[i];
306cdf0e10cSrcweir         Font aFont( rSym.GetFace() );
307cdf0e10cSrcweir         DBG_ASSERT( aFont.GetItalic() == ITALIC_NONE, "expected Font with ITALIC_NONE, failed." );
308cdf0e10cSrcweir         aFont.SetItalic( ITALIC_NORMAL );
309cdf0e10cSrcweir         String aSymbolName( (sal_Unicode)'i' );
310cdf0e10cSrcweir         aSymbolName += rSym.GetName();
311cdf0e10cSrcweir         SmSym aSymbol( aSymbolName, aFont, rSym.GetCharacter(),
312cdf0e10cSrcweir 		        aSymbolSetName, sal_True /*bIsPredefined*/ );
313cdf0e10cSrcweir 
314cdf0e10cSrcweir         AddOrReplaceSymbol( aSymbol );
315cdf0e10cSrcweir     }
316cdf0e10cSrcweir }
317cdf0e10cSrcweir 
Save()318cdf0e10cSrcweir void SmSymbolManager::Save()
319cdf0e10cSrcweir {
320cdf0e10cSrcweir     if (m_bModified)
321cdf0e10cSrcweir     {
322cdf0e10cSrcweir         SmMathConfig &rCfg = *SM_MOD()->GetConfig();
323cdf0e10cSrcweir 
324cdf0e10cSrcweir #if 0
325cdf0e10cSrcweir         sal_uInt16 nSymbolCount     = GetSymbolCount();
326cdf0e10cSrcweir         sal_uInt16 nSaveSymbolCnt   = 0;
327cdf0e10cSrcweir         const SmSym **pSymbols  = new const SmSym* [ nSymbolCount ];
328cdf0e10cSrcweir         const SmSym **pSym      = pSymbols;
329cdf0e10cSrcweir         for (sal_uInt16 j = 0;  j < nSymbolCount;  ++j)
330cdf0e10cSrcweir         {
331cdf0e10cSrcweir             const SmSym &rSym = *pSymSet->GetSymbol( j );
332cdf0e10cSrcweir             if (!rSym.IsDocSymbol())
333cdf0e10cSrcweir             {
334cdf0e10cSrcweir                 *pSym++ = &rSym;
335cdf0e10cSrcweir                 ++nSaveSymbolCnt;
336cdf0e10cSrcweir             }
337cdf0e10cSrcweir         }
338cdf0e10cSrcweir         DBG_ASSERT(pSym - pSymbols == nSaveSymbolCnt, "wrong number of symbols" );
339cdf0e10cSrcweir #endif
340cdf0e10cSrcweir 
341cdf0e10cSrcweir         // prepare to skip symbols from iGreek on saving
342cdf0e10cSrcweir         SmLocalizedSymbolData   aLocalizedData;
343cdf0e10cSrcweir         String aSymbolSetName( (sal_Unicode) 'i' );
344cdf0e10cSrcweir         aSymbolSetName += aLocalizedData.GetUiSymbolSetName( A2OU("Greek") );
345cdf0e10cSrcweir 
346cdf0e10cSrcweir         SymbolPtrVec_t aTmp( GetSymbols() );
347cdf0e10cSrcweir         std::vector< SmSym > aSymbols;
348cdf0e10cSrcweir         for (size_t i = 0; i < aTmp.size(); ++i)
349cdf0e10cSrcweir         {
350cdf0e10cSrcweir             // skip symbols from iGreek set since those symbols always get added
351cdf0e10cSrcweir             // by computational means in SmSymbolManager::Load
352cdf0e10cSrcweir             if (aTmp[i]->GetSymbolSetName() != aSymbolSetName)
353cdf0e10cSrcweir                 aSymbols.push_back( *aTmp[i] );
354cdf0e10cSrcweir         }
355cdf0e10cSrcweir         rCfg.SetSymbols( aSymbols );
356cdf0e10cSrcweir #if 0
357cdf0e10cSrcweir         delete [] pSymbols;
358cdf0e10cSrcweir #endif
359cdf0e10cSrcweir 
360cdf0e10cSrcweir         m_bModified = false;
361cdf0e10cSrcweir     }
362cdf0e10cSrcweir }
363cdf0e10cSrcweir 
364cdf0e10cSrcweir 
365