1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
25 #include "utility.hxx"
27 #include "cfgitem.hxx"
29 #include "starmath.hrc"
33 m_aName(OUString("unknown")),
34 m_aSetName(OUString("unknown")),
39 m_aExportName
= m_aName
;
40 m_aFace
.SetTransparent(true);
41 m_aFace
.SetAlignment(ALIGN_BASELINE
);
45 SmSym::SmSym(const SmSym
& rSymbol
)
51 SmSym::SmSym(const OUString
& rName
, const vcl::Font
& rFont
, sal_UCS4 cChar
,
52 const OUString
& rSet
, bool bIsPredefined
)
54 m_aName
= m_aExportName
= rName
;
57 m_aFace
.SetTransparent(true);
58 m_aFace
.SetAlignment(ALIGN_BASELINE
);
62 m_bPredefined
= bIsPredefined
;
67 SmSym
& SmSym::operator = (const SmSym
& rSymbol
)
69 m_aName
= rSymbol
.m_aName
;
70 m_aExportName
= rSymbol
.m_aExportName
;
71 m_cChar
= rSymbol
.m_cChar
;
72 m_aFace
= rSymbol
.m_aFace
;
73 m_aSetName
= rSymbol
.m_aSetName
;
74 m_bPredefined
= rSymbol
.m_bPredefined
;
75 m_bDocSymbol
= rSymbol
.m_bDocSymbol
;
77 SmSymbolManager
* pSymSetManager
= &SM_MOD()->GetSymbolManager();
79 pSymSetManager
->SetModified(true);
85 bool SmSym::IsEqualInUI( const SmSym
& rSymbol
) const
87 return m_aName
== rSymbol
.m_aName
&&
88 m_aFace
== rSymbol
.m_aFace
&&
89 m_cChar
== rSymbol
.m_cChar
;
92 /**************************************************************************/
95 SmSymbolManager::SmSymbolManager()
101 SmSymbolManager::SmSymbolManager(const SmSymbolManager
& rSymbolSetManager
)
103 m_aSymbols
= rSymbolSetManager
.m_aSymbols
;
108 SmSymbolManager::~SmSymbolManager()
113 SmSymbolManager
& SmSymbolManager::operator = (const SmSymbolManager
& rSymbolSetManager
)
115 m_aSymbols
= rSymbolSetManager
.m_aSymbols
;
121 SmSym
*SmSymbolManager::GetSymbolByName(const OUString
& rSymbolName
)
123 SmSym
*pRes
= nullptr;
124 SymbolMap_t::iterator
aIt( m_aSymbols
.find( rSymbolName
) );
125 if (aIt
!= m_aSymbols
.end())
131 const SymbolPtrVec_t
SmSymbolManager::GetSymbols() const
134 SymbolMap_t::const_iterator
aIt( m_aSymbols
.begin() );
135 for ( ; aIt
!= m_aSymbols
.end(); ++aIt
)
136 aRes
.push_back( &aIt
->second
);
137 // OSL_ENSURE( sSymbols.size() == m_aSymbols.size(), "number of symbols mismatch " );
142 bool SmSymbolManager::AddOrReplaceSymbol( const SmSym
&rSymbol
, bool bForceChange
)
146 const OUString
& aSymbolName( rSymbol
.GetName() );
147 if (aSymbolName
.getLength() > 0 && rSymbol
.GetSymbolSetName().getLength() > 0)
149 const SmSym
*pFound
= GetSymbolByName( aSymbolName
);
150 const bool bSymbolConflict
= pFound
&& !pFound
->IsEqualInUI( rSymbol
);
152 // avoid having the same symbol name twice but with different symbols in use
153 if (!pFound
|| bForceChange
)
155 m_aSymbols
[ aSymbolName
] = rSymbol
;
158 else if (pFound
&& !bForceChange
&& bSymbolConflict
)
160 // TODO: to solve this a document owned symbol manager would be required ...
161 SAL_WARN("starmath", "symbol conflict, different symbol with same name found!");
162 // symbols in all formulas. A copy of the global one would be needed here
163 // and then the new symbol has to be forcefully applied. This would keep
164 // the current formula intact but will leave the set of symbols in the
165 // global symbol manager somewhat to chance.
168 OSL_ENSURE( bAdded
, "failed to add symbol" );
171 OSL_ENSURE( bAdded
|| (pFound
&& !bSymbolConflict
), "AddOrReplaceSymbol: unresolved symbol conflict" );
178 void SmSymbolManager::RemoveSymbol( const OUString
& rSymbolName
)
180 if (rSymbolName
.getLength() > 0)
182 size_t nOldSize
= m_aSymbols
.size();
183 m_aSymbols
.erase( rSymbolName
);
184 m_bModified
= nOldSize
!= m_aSymbols
.size();
189 std::set
< OUString
> SmSymbolManager::GetSymbolSetNames() const
191 std::set
< OUString
> aRes
;
192 SymbolMap_t::const_iterator
aIt( m_aSymbols
.begin() );
193 for ( ; aIt
!= m_aSymbols
.end(); ++aIt
)
194 aRes
.insert( aIt
->second
.GetSymbolSetName() );
199 const SymbolPtrVec_t
SmSymbolManager::GetSymbolSet( const OUString
& rSymbolSetName
)
202 if (rSymbolSetName
.getLength() > 0)
204 SymbolMap_t::const_iterator
aIt( m_aSymbols
.begin() );
205 for ( ; aIt
!= m_aSymbols
.end(); ++aIt
)
207 if (aIt
->second
.GetSymbolSetName() == rSymbolSetName
)
208 aRes
.push_back( &aIt
->second
);
215 void SmSymbolManager::Load()
217 std::vector
< SmSym
> aSymbols
;
218 SmMathConfig
&rCfg
= *SM_MOD()->GetConfig();
219 rCfg
.GetSymbols( aSymbols
);
220 size_t nSymbolCount
= aSymbols
.size();
223 for (size_t i
= 0; i
< nSymbolCount
; ++i
)
225 const SmSym
&rSym
= aSymbols
[i
];
226 OSL_ENSURE( rSym
.GetName().getLength() > 0, "symbol without name!" );
227 if (rSym
.GetName().getLength() > 0)
228 AddOrReplaceSymbol( rSym
);
232 if (0 == nSymbolCount
)
234 SAL_WARN("starmath", "no symbol set found");
238 // now add a %i... symbol to the 'iGreek' set for every symbol found in the 'Greek' set.
239 const OUString
aGreekSymbolSetName(SmLocalizedSymbolData::GetUiSymbolSetName("Greek"));
240 const SymbolPtrVec_t
aGreekSymbols( GetSymbolSet( aGreekSymbolSetName
) );
241 OUString
aSymbolSetName('i');
242 aSymbolSetName
+= aGreekSymbolSetName
;
243 size_t nSymbols
= aGreekSymbols
.size();
244 for (size_t i
= 0; i
< nSymbols
; ++i
)
246 // make the new symbol a copy but with ITALIC_NORMAL, and add it to iGreek
247 const SmSym
&rSym
= *aGreekSymbols
[i
];
248 vcl::Font
aFont( rSym
.GetFace() );
249 OSL_ENSURE( aFont
.GetItalic() == ITALIC_NONE
, "expected Font with ITALIC_NONE, failed." );
250 aFont
.SetItalic( ITALIC_NORMAL
);
251 OUString
aSymbolName('i');
252 aSymbolName
+= rSym
.GetName();
253 SmSym
aSymbol( aSymbolName
, aFont
, rSym
.GetCharacter(),
254 aSymbolSetName
, true /*bIsPredefined*/ );
256 AddOrReplaceSymbol( aSymbol
);
260 void SmSymbolManager::Save()
264 SmMathConfig
&rCfg
= *SM_MOD()->GetConfig();
266 // prepare to skip symbols from iGreek on saving
267 OUString
aSymbolSetName('i');
268 aSymbolSetName
+= SmLocalizedSymbolData::GetUiSymbolSetName("Greek");
270 SymbolPtrVec_t
aTmp( GetSymbols() );
271 std::vector
< SmSym
> aSymbols
;
272 for (const SmSym
* i
: aTmp
)
274 // skip symbols from iGreek set since those symbols always get added
275 // by computational means in SmSymbolManager::Load
276 if (i
->GetSymbolSetName() != aSymbolSetName
)
277 aSymbols
.push_back( *i
);
279 rCfg
.SetSymbols( aSymbols
);
286 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */