tdf#130857 qt weld: Support mail merge "Server Auth" dialog
[LibreOffice.git] / starmath / source / symbol.cxx
blob5d5be5deb93a40b7fb93d8f9895cd29eda617397
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <symbol.hxx>
21 #include <utility.hxx>
22 #include <cfgitem.hxx>
23 #include <smmod.hxx>
24 #include <format.hxx>
25 #include <sal/log.hxx>
26 #include <osl/diagnose.h>
29 SmSym::SmSym() :
30 m_aUiName(u"unknown"_ustr),
31 m_aSetName(u"unknown"_ustr),
32 m_cChar('\0'),
33 m_bPredefined(false)
35 m_aExportName = m_aUiName;
36 m_aFace.SetTransparent(true);
37 m_aFace.SetAlignment(ALIGN_BASELINE);
41 SmSym::SmSym(const SmSym& rSymbol)
43 *this = rSymbol;
47 SmSym::SmSym(const OUString& rName, const vcl::Font& rFont, sal_UCS4 cChar,
48 const OUString& rSet, bool bIsPredefined)
50 m_aUiName = m_aExportName = rName;
52 m_aFace = SmFace(rFont);
53 m_aFace.SetTransparent(true);
54 m_aFace.SetAlignment(ALIGN_BASELINE);
56 m_cChar = cChar;
57 m_aSetName = rSet;
58 m_bPredefined = bIsPredefined;
62 SmSym& SmSym::operator = (const SmSym& rSymbol)
64 m_aUiName = rSymbol.m_aUiName;
65 m_aExportName = rSymbol.m_aExportName;
66 m_cChar = rSymbol.m_cChar;
67 m_aFace = rSymbol.m_aFace;
68 m_aSetName = rSymbol.m_aSetName;
69 m_bPredefined = rSymbol.m_bPredefined;
71 SmModule::get()->GetSymbolManager().SetModified(true);
73 return *this;
77 bool SmSym::IsEqualInUI( const SmSym& rSymbol ) const
79 return m_aUiName == rSymbol.m_aUiName &&
80 m_aFace == rSymbol.m_aFace &&
81 m_cChar == rSymbol.m_cChar;
84 const vcl::Font& SmSym::GetFace(const SmFormat* pFormat) const
86 if (m_aFace.GetFamilyName().isEmpty())
88 if (!pFormat)
89 pFormat = &SmModule::get()->GetConfig()->GetStandardFormat();
90 return pFormat->GetFont(FNT_VARIABLE);
92 return m_aFace;
95 /**************************************************************************/
98 SmSymbolManager::SmSymbolManager()
100 m_bModified = false;
104 SmSymbolManager::SmSymbolManager(const SmSymbolManager& rSymbolSetManager)
106 m_aSymbols = rSymbolSetManager.m_aSymbols;
107 m_bModified = true;
111 SmSymbolManager::~SmSymbolManager()
116 SmSymbolManager& SmSymbolManager::operator = (const SmSymbolManager& rSymbolSetManager)
118 m_aSymbols = rSymbolSetManager.m_aSymbols;
119 m_bModified = true;
120 return *this;
123 SmSym* SmSymbolManager::GetSymbolByName(std::u16string_view rSymbolName)
125 SmSym* pRes = GetSymbolByUiName(rSymbolName);
126 if (!pRes)
127 pRes = GetSymbolByExportName(rSymbolName);
128 return pRes;
131 SmSym *SmSymbolManager::GetSymbolByUiName(std::u16string_view rSymbolName)
133 OUString aSymbolName(rSymbolName);
134 SmSym *pRes = nullptr;
135 SymbolMap_t::iterator aIt( m_aSymbols.find( aSymbolName ) );
136 if (aIt != m_aSymbols.end())
137 pRes = &aIt->second;
138 return pRes;
141 SmSym* SmSymbolManager::GetSymbolByExportName(std::u16string_view rSymbolName)
143 SmSym* pRes = nullptr;
144 for (auto& rPair : m_aSymbols)
146 SmSym& rSymbol = rPair.second;
147 if (rSymbol.GetExportName() == rSymbolName)
149 pRes = &rSymbol;
150 break;
153 return pRes;
157 SymbolPtrVec_t SmSymbolManager::GetSymbols() const
159 SymbolPtrVec_t aRes;
160 aRes.reserve(m_aSymbols.size());
161 for (const auto& rEntry : m_aSymbols)
162 aRes.push_back( &rEntry.second );
163 // OSL_ENSURE( sSymbols.size() == m_aSymbols.size(), "number of symbols mismatch " );
164 return aRes;
168 bool SmSymbolManager::AddOrReplaceSymbol( const SmSym &rSymbol, bool bForceChange )
170 bool bAdded = false;
172 const OUString& aSymbolName( rSymbol.GetUiName() );
173 if (!aSymbolName.isEmpty() && !rSymbol.GetSymbolSetName().isEmpty())
175 const SmSym *pFound = GetSymbolByUiName( aSymbolName );
176 const bool bSymbolConflict = pFound && !pFound->IsEqualInUI( rSymbol );
178 // avoid having the same symbol name twice but with different symbols in use
179 if (!pFound || bForceChange)
181 m_aSymbols[ aSymbolName ] = rSymbol;
182 bAdded = true;
184 else if (bSymbolConflict)
186 // TODO: to solve this a document owned symbol manager would be required ...
187 SAL_WARN("starmath", "symbol conflict, different symbol with same name found!");
188 // symbols in all formulas. A copy of the global one would be needed here
189 // and then the new symbol has to be forcefully applied. This would keep
190 // the current formula intact but will leave the set of symbols in the
191 // global symbol manager somewhat to chance.
194 OSL_ENSURE( bAdded, "failed to add symbol" );
195 if (bAdded)
196 m_bModified = true;
197 OSL_ENSURE( bAdded || (pFound && !bSymbolConflict), "AddOrReplaceSymbol: unresolved symbol conflict" );
200 return bAdded;
204 void SmSymbolManager::RemoveSymbol( const OUString & rSymbolName )
206 if (!rSymbolName.isEmpty())
208 size_t nOldSize = m_aSymbols.size();
209 m_aSymbols.erase( rSymbolName );
210 m_bModified = nOldSize != m_aSymbols.size();
215 std::set< OUString > SmSymbolManager::GetSymbolSetNames() const
217 std::set< OUString > aRes;
218 for (const auto& rEntry : m_aSymbols)
219 aRes.insert( rEntry.second.GetSymbolSetName() );
220 return aRes;
224 SymbolPtrVec_t SmSymbolManager::GetSymbolSet( std::u16string_view rSymbolSetName )
226 SymbolPtrVec_t aRes;
227 if (!rSymbolSetName.empty())
229 for (const auto& rEntry : m_aSymbols)
231 if (rEntry.second.GetSymbolSetName() == rSymbolSetName)
232 aRes.push_back( &rEntry.second );
235 return aRes;
239 void SmSymbolManager::Load()
241 std::vector< SmSym > aSymbols;
242 SmModule::get()->GetConfig()->GetSymbols(aSymbols);
243 size_t nSymbolCount = aSymbols.size();
245 m_aSymbols.clear();
246 for (size_t i = 0; i < nSymbolCount; ++i)
248 const SmSym &rSym = aSymbols[i];
249 OSL_ENSURE( !rSym.GetUiName().isEmpty(), "symbol without name!" );
250 if (!rSym.GetUiName().isEmpty())
251 AddOrReplaceSymbol( rSym );
253 m_bModified = true;
255 if (0 == nSymbolCount)
257 SAL_WARN("starmath", "no symbol set found");
258 m_bModified = false;
261 // now add a %i... symbol to the 'iGreek' set for every symbol found in the 'Greek' set.
262 const OUString aGreekSymbolSetName(SmLocalizedSymbolData::GetUiSymbolSetName(u"Greek"));
263 const SymbolPtrVec_t aGreekSymbols( GetSymbolSet( aGreekSymbolSetName ) );
264 OUString aSymbolSetName = "i" + aGreekSymbolSetName;
265 size_t nSymbols = aGreekSymbols.size();
266 for (size_t i = 0; i < nSymbols; ++i)
268 // make the new symbol a copy but with ITALIC_NORMAL, and add it to iGreek
269 const SmSym &rSym = *aGreekSymbols[i];
270 vcl::Font aFont( rSym.GetFace() );
271 OSL_ENSURE( aFont.GetItalic() == ITALIC_NONE, "expected Font with ITALIC_NONE, failed." );
272 aFont.SetItalic( ITALIC_NORMAL );
273 OUString aSymbolName = "i" + rSym.GetUiName();
274 SmSym aSymbol( aSymbolName, aFont, rSym.GetCharacter(),
275 aSymbolSetName, true /*bIsPredefined*/ );
276 aSymbol.SetExportName("i" + rSym.GetExportName());
278 AddOrReplaceSymbol( aSymbol );
282 void SmSymbolManager::Save()
284 if (!m_bModified)
285 return;
287 // prepare to skip symbols from iGreek on saving
288 OUString aSymbolSetName = "i" +
289 SmLocalizedSymbolData::GetUiSymbolSetName(u"Greek");
291 SymbolPtrVec_t aTmp( GetSymbols() );
292 std::vector< SmSym > aSymbols;
293 for (const SmSym* i : aTmp)
295 // skip symbols from iGreek set since those symbols always get added
296 // by computational means in SmSymbolManager::Load
297 if (i->GetSymbolSetName() != aSymbolSetName)
298 aSymbols.push_back( *i );
300 SmModule::get()->GetConfig()->SetSymbols(aSymbols);
302 m_bModified = false;
306 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */