Version 6.1.4.1, tag libreoffice-6.1.4.1
[LibreOffice.git] / starmath / source / cfgitem.cxx
blob883f6f6d120b036d71e086a81bcf8ad8ff96cb0f
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 <cassert>
21 #include <memory>
22 #include <vector>
24 #include <svl/itemset.hxx>
25 #include <svl/intitem.hxx>
26 #include <svl/itempool.hxx>
27 #include <svl/eitem.hxx>
28 #include <svl/languageoptions.hxx>
29 #include <vcl/outdev.hxx>
30 #include <vcl/svapp.hxx>
31 #include <vcl/settings.hxx>
33 #include <officecfg/Office/Math.hxx>
34 #include "cfgitem.hxx"
36 #include <starmath.hrc>
37 #include <smmod.hxx>
38 #include <symbol.hxx>
39 #include <format.hxx>
41 using namespace com::sun::star::uno;
42 using namespace com::sun::star::beans;
44 #define SYMBOL_LIST "SymbolList"
45 #define FONT_FORMAT_LIST "FontFormatList"
47 static Sequence< OUString > lcl_GetFontPropertyNames()
49 return Sequence< OUString > {
50 "Name",
51 "CharSet",
52 "Family",
53 "Pitch",
54 "Weight",
55 "Italic"
59 static Sequence< OUString > lcl_GetSymbolPropertyNames()
61 return Sequence< OUString > {
62 "Char",
63 "Set",
64 "Predefined",
65 "FontFormatId"
69 static Sequence< OUString > lcl_GetFormatPropertyNames()
71 //! Beware of order according to *_BEGIN *_END defines in format.hxx !
72 //! see respective load/save routines here
73 return Sequence< OUString > {
74 "StandardFormat/Textmode",
75 "StandardFormat/GreekCharStyle",
76 "StandardFormat/ScaleNormalBracket",
77 "StandardFormat/HorizontalAlignment",
78 "StandardFormat/BaseSize",
79 "StandardFormat/TextSize",
80 "StandardFormat/IndexSize",
81 "StandardFormat/FunctionSize",
82 "StandardFormat/OperatorSize",
83 "StandardFormat/LimitsSize",
84 "StandardFormat/Distance/Horizontal",
85 "StandardFormat/Distance/Vertical",
86 "StandardFormat/Distance/Root",
87 "StandardFormat/Distance/SuperScript",
88 "StandardFormat/Distance/SubScript",
89 "StandardFormat/Distance/Numerator",
90 "StandardFormat/Distance/Denominator",
91 "StandardFormat/Distance/Fraction",
92 "StandardFormat/Distance/StrokeWidth",
93 "StandardFormat/Distance/UpperLimit",
94 "StandardFormat/Distance/LowerLimit",
95 "StandardFormat/Distance/BracketSize",
96 "StandardFormat/Distance/BracketSpace",
97 "StandardFormat/Distance/MatrixRow",
98 "StandardFormat/Distance/MatrixColumn",
99 "StandardFormat/Distance/OrnamentSize",
100 "StandardFormat/Distance/OrnamentSpace",
101 "StandardFormat/Distance/OperatorSize",
102 "StandardFormat/Distance/OperatorSpace",
103 "StandardFormat/Distance/LeftSpace",
104 "StandardFormat/Distance/RightSpace",
105 "StandardFormat/Distance/TopSpace",
106 "StandardFormat/Distance/BottomSpace",
107 "StandardFormat/Distance/NormalBracketSize",
108 "StandardFormat/VariableFont",
109 "StandardFormat/FunctionFont",
110 "StandardFormat/NumberFont",
111 "StandardFormat/TextFont",
112 "StandardFormat/SerifFont",
113 "StandardFormat/SansFont",
114 "StandardFormat/FixedFont"
118 struct SmCfgOther
120 SmPrintSize ePrintSize;
121 sal_uInt16 nPrintZoomFactor;
122 bool bPrintTitle;
123 bool bPrintFormulaText;
124 bool bPrintFrame;
125 bool bIsSaveOnlyUsedSymbols;
126 bool bIsAutoCloseBrackets;
127 bool bIgnoreSpacesRight;
128 bool bToolboxVisible;
129 bool bAutoRedraw;
130 bool bFormulaCursor;
132 SmCfgOther();
136 SmCfgOther::SmCfgOther()
137 : ePrintSize(PRINT_SIZE_NORMAL)
138 , nPrintZoomFactor(100)
139 , bPrintTitle(true)
140 , bPrintFormulaText(true)
141 , bPrintFrame(true)
142 , bIsSaveOnlyUsedSymbols(true)
143 , bIsAutoCloseBrackets(true)
144 , bIgnoreSpacesRight(true)
145 , bToolboxVisible(true)
146 , bAutoRedraw(true)
147 , bFormulaCursor(true)
152 SmFontFormat::SmFontFormat()
153 : aName(FONTNAME_MATH)
154 , nCharSet(RTL_TEXTENCODING_UNICODE)
155 , nFamily(FAMILY_DONTKNOW)
156 , nPitch(PITCH_DONTKNOW)
157 , nWeight(WEIGHT_DONTKNOW)
158 , nItalic(ITALIC_NONE)
163 SmFontFormat::SmFontFormat( const vcl::Font &rFont )
164 : aName(rFont.GetFamilyName())
165 , nCharSet(static_cast<sal_Int16>(rFont.GetCharSet()))
166 , nFamily(static_cast<sal_Int16>(rFont.GetFamilyType()))
167 , nPitch(static_cast<sal_Int16>(rFont.GetPitch()))
168 , nWeight(static_cast<sal_Int16>(rFont.GetWeight()))
169 , nItalic(static_cast<sal_Int16>(rFont.GetItalic()))
174 const vcl::Font SmFontFormat::GetFont() const
176 vcl::Font aRes;
177 aRes.SetFamilyName( aName );
178 aRes.SetCharSet( static_cast<rtl_TextEncoding>(nCharSet) );
179 aRes.SetFamily( static_cast<FontFamily>(nFamily) );
180 aRes.SetPitch( static_cast<FontPitch>(nPitch) );
181 aRes.SetWeight( static_cast<FontWeight>(nWeight) );
182 aRes.SetItalic( static_cast<FontItalic>(nItalic) );
183 return aRes;
187 bool SmFontFormat::operator == ( const SmFontFormat &rFntFmt ) const
189 return aName == rFntFmt.aName &&
190 nCharSet == rFntFmt.nCharSet &&
191 nFamily == rFntFmt.nFamily &&
192 nPitch == rFntFmt.nPitch &&
193 nWeight == rFntFmt.nWeight &&
194 nItalic == rFntFmt.nItalic;
198 SmFntFmtListEntry::SmFntFmtListEntry( const OUString &rId, const SmFontFormat &rFntFmt ) :
199 aId (rId),
200 aFntFmt (rFntFmt)
205 SmFontFormatList::SmFontFormatList()
206 : bModified(false)
211 void SmFontFormatList::Clear()
213 if (!aEntries.empty())
215 aEntries.clear();
216 SetModified( true );
221 void SmFontFormatList::AddFontFormat( const OUString &rFntFmtId,
222 const SmFontFormat &rFntFmt )
224 const SmFontFormat *pFntFmt = GetFontFormat( rFntFmtId );
225 OSL_ENSURE( !pFntFmt, "FontFormatId already exists" );
226 if (!pFntFmt)
228 SmFntFmtListEntry aEntry( rFntFmtId, rFntFmt );
229 aEntries.push_back( aEntry );
230 SetModified( true );
235 void SmFontFormatList::RemoveFontFormat( const OUString &rFntFmtId )
238 // search for entry
239 for (size_t i = 0; i < aEntries.size(); ++i)
241 if (aEntries[i].aId == rFntFmtId)
243 // remove entry if found
244 aEntries.erase( aEntries.begin() + i );
245 SetModified( true );
246 break;
252 const SmFontFormat * SmFontFormatList::GetFontFormat( const OUString &rFntFmtId ) const
254 const SmFontFormat *pRes = nullptr;
256 for (const auto & rEntry : aEntries)
258 if (rEntry.aId == rFntFmtId)
260 pRes = &rEntry.aFntFmt;
261 break;
265 return pRes;
269 const SmFontFormat * SmFontFormatList::GetFontFormat( size_t nPos ) const
271 const SmFontFormat *pRes = nullptr;
272 if (nPos < aEntries.size())
273 pRes = &aEntries[nPos].aFntFmt;
274 return pRes;
278 const OUString SmFontFormatList::GetFontFormatId( const SmFontFormat &rFntFmt ) const
280 OUString aRes;
282 for (const auto & rEntry : aEntries)
284 if (rEntry.aFntFmt == rFntFmt)
286 aRes = rEntry.aId;
287 break;
291 return aRes;
295 const OUString SmFontFormatList::GetFontFormatId( const SmFontFormat &rFntFmt, bool bAdd )
297 OUString aRes( GetFontFormatId( rFntFmt) );
298 if (aRes.isEmpty() && bAdd)
300 aRes = GetNewFontFormatId();
301 AddFontFormat( aRes, rFntFmt );
303 return aRes;
307 const OUString SmFontFormatList::GetFontFormatId( size_t nPos ) const
309 OUString aRes;
310 if (nPos < aEntries.size())
311 aRes = aEntries[nPos].aId;
312 return aRes;
316 const OUString SmFontFormatList::GetNewFontFormatId() const
318 // returns first unused FormatId
320 sal_Int32 nCnt = GetCount();
321 for (sal_Int32 i = 1; i <= nCnt + 1; ++i)
323 OUString aTmpId = "Id" + OUString::number(i);
324 if (!GetFontFormat(aTmpId))
325 return aTmpId;
327 OSL_ENSURE( false, "failed to create new FontFormatId" );
329 return OUString();
333 SmMathConfig::SmMathConfig() :
334 ConfigItem("Office.Math")
335 , pFormat()
336 , pOther()
337 , pFontFormatList()
338 , pSymbolMgr()
339 , bIsOtherModified(false)
340 , bIsFormatModified(false)
345 SmMathConfig::~SmMathConfig()
347 Save();
351 void SmMathConfig::SetOtherModified( bool bVal )
353 bIsOtherModified = bVal;
357 void SmMathConfig::SetFormatModified( bool bVal )
359 bIsFormatModified = bVal;
363 void SmMathConfig::ReadSymbol( SmSym &rSymbol,
364 const OUString &rSymbolName,
365 const OUString &rBaseNode ) const
367 Sequence< OUString > aNames = lcl_GetSymbolPropertyNames();
368 sal_Int32 nProps = aNames.getLength();
370 OUString aDelim( "/" );
371 OUString *pName = aNames.getArray();
372 for (sal_Int32 i = 0; i < nProps; ++i)
374 OUString &rName = pName[i];
375 OUString aTmp( rName );
376 rName = rBaseNode;
377 rName += aDelim;
378 rName += rSymbolName;
379 rName += aDelim;
380 rName += aTmp;
383 const Sequence< Any > aValues = const_cast<SmMathConfig*>(this)->GetProperties(aNames);
385 if (nProps && aValues.getLength() == nProps)
387 const Any * pValue = aValues.getConstArray();
388 vcl::Font aFont;
389 sal_UCS4 cChar = '\0';
390 OUString aSet;
391 bool bPredefined = false;
393 OUString aTmpStr;
394 sal_Int32 nTmp32 = 0;
395 bool bTmp = false;
397 bool bOK = true;
398 if (pValue->hasValue() && (*pValue >>= nTmp32))
399 cChar = static_cast< sal_UCS4 >( nTmp32 );
400 else
401 bOK = false;
402 ++pValue;
403 if (pValue->hasValue() && (*pValue >>= aTmpStr))
404 aSet = aTmpStr;
405 else
406 bOK = false;
407 ++pValue;
408 if (pValue->hasValue() && (*pValue >>= bTmp))
409 bPredefined = bTmp;
410 else
411 bOK = false;
412 ++pValue;
413 if (pValue->hasValue() && (*pValue >>= aTmpStr))
415 const SmFontFormat *pFntFmt = GetFontFormatList().GetFontFormat( aTmpStr );
416 OSL_ENSURE( pFntFmt, "unknown FontFormat" );
417 if (pFntFmt)
418 aFont = pFntFmt->GetFont();
420 else
421 bOK = false;
422 ++pValue;
424 if (bOK)
426 OUString aUiName( rSymbolName );
427 OUString aUiSetName( aSet );
428 if (bPredefined)
430 OUString aTmp;
431 aTmp = SmLocalizedSymbolData::GetUiSymbolName( rSymbolName );
432 OSL_ENSURE( !aTmp.isEmpty(), "localized symbol-name not found" );
433 if (!aTmp.isEmpty())
434 aUiName = aTmp;
435 aTmp = SmLocalizedSymbolData::GetUiSymbolSetName( aSet );
436 OSL_ENSURE( !aTmp.isEmpty(), "localized symbolset-name not found" );
437 if (!aTmp.isEmpty())
438 aUiSetName = aTmp;
441 rSymbol = SmSym( aUiName, aFont, cChar, aUiSetName, bPredefined );
442 if (aUiName != rSymbolName)
443 rSymbol.SetExportName( rSymbolName );
445 else
447 SAL_WARN("starmath", "symbol read error");
453 SmSymbolManager & SmMathConfig::GetSymbolManager()
455 if (!pSymbolMgr)
457 pSymbolMgr.reset(new SmSymbolManager);
458 pSymbolMgr->Load();
460 return *pSymbolMgr;
464 void SmMathConfig::ImplCommit()
466 Save();
470 void SmMathConfig::Save()
472 SaveOther();
473 SaveFormat();
474 SaveFontFormatList();
478 void SmMathConfig::GetSymbols( std::vector< SmSym > &rSymbols ) const
480 Sequence< OUString > aNodes(const_cast<SmMathConfig*>(this)->GetNodeNames(SYMBOL_LIST));
481 const OUString *pNode = aNodes.getConstArray();
482 sal_Int32 nNodes = aNodes.getLength();
484 rSymbols.resize( nNodes );
485 std::vector< SmSym >::iterator aIt( rSymbols.begin() );
486 std::vector< SmSym >::iterator aEnd( rSymbols.end() );
487 while (aIt != aEnd)
489 ReadSymbol( *aIt++, *pNode++, SYMBOL_LIST );
494 void SmMathConfig::SetSymbols( const std::vector< SmSym > &rNewSymbols )
496 auto nCount = sal::static_int_cast<sal_Int32>(rNewSymbols.size());
498 Sequence< OUString > aNames = lcl_GetSymbolPropertyNames();
499 const OUString *pNames = aNames.getConstArray();
500 sal_Int32 nSymbolProps = aNames.getLength();
502 Sequence< PropertyValue > aValues( nCount * nSymbolProps );
503 PropertyValue *pValues = aValues.getArray();
505 PropertyValue *pVal = pValues;
506 OUString aDelim( "/" );
507 std::vector< SmSym >::const_iterator aIt( rNewSymbols.begin() );
508 std::vector< SmSym >::const_iterator aEnd( rNewSymbols.end() );
509 while (aIt != aEnd)
511 const SmSym &rSymbol = *aIt++;
512 OUString aNodeNameDelim( SYMBOL_LIST );
513 aNodeNameDelim += aDelim;
514 aNodeNameDelim += rSymbol.GetExportName();
515 aNodeNameDelim += aDelim;
517 const OUString *pName = pNames;
519 // Char
520 pVal->Name = aNodeNameDelim;
521 pVal->Name += *pName++;
522 pVal->Value <<= rSymbol.GetCharacter();
523 pVal++;
524 // Set
525 pVal->Name = aNodeNameDelim;
526 pVal->Name += *pName++;
527 OUString aTmp( rSymbol.GetSymbolSetName() );
528 if (rSymbol.IsPredefined())
529 aTmp = SmLocalizedSymbolData::GetExportSymbolSetName( aTmp );
530 pVal->Value <<= aTmp;
531 pVal++;
532 // Predefined
533 pVal->Name = aNodeNameDelim;
534 pVal->Name += *pName++;
535 pVal->Value <<= rSymbol.IsPredefined();
536 pVal++;
537 // FontFormatId
538 SmFontFormat aFntFmt( rSymbol.GetFace() );
539 OUString aFntFmtId( GetFontFormatList().GetFontFormatId( aFntFmt, true ) );
540 OSL_ENSURE( !aFntFmtId.isEmpty(), "FontFormatId not found" );
541 pVal->Name = aNodeNameDelim;
542 pVal->Name += *pName++;
543 pVal->Value <<= aFntFmtId;
544 pVal++;
546 OSL_ENSURE( pVal - pValues == sal::static_int_cast< ptrdiff_t >(nCount * nSymbolProps), "properties missing" );
547 ReplaceSetProperties( SYMBOL_LIST, aValues );
549 StripFontFormatList( rNewSymbols );
550 SaveFontFormatList();
554 SmFontFormatList & SmMathConfig::GetFontFormatList()
556 if (!pFontFormatList)
558 LoadFontFormatList();
560 return *pFontFormatList;
564 void SmMathConfig::LoadFontFormatList()
566 if (!pFontFormatList)
567 pFontFormatList.reset(new SmFontFormatList);
568 else
569 pFontFormatList->Clear();
571 Sequence< OUString > aNodes( GetNodeNames( FONT_FORMAT_LIST ) );
572 const OUString *pNode = aNodes.getConstArray();
573 sal_Int32 nNodes = aNodes.getLength();
575 for (sal_Int32 i = 0; i < nNodes; ++i)
577 SmFontFormat aFntFmt;
578 ReadFontFormat( aFntFmt, pNode[i], FONT_FORMAT_LIST );
579 if (!pFontFormatList->GetFontFormat( pNode[i] ))
580 pFontFormatList->AddFontFormat( pNode[i], aFntFmt );
582 pFontFormatList->SetModified( false );
586 void SmMathConfig::ReadFontFormat( SmFontFormat &rFontFormat,
587 const OUString &rSymbolName, const OUString &rBaseNode ) const
589 Sequence< OUString > aNames = lcl_GetFontPropertyNames();
590 sal_Int32 nProps = aNames.getLength();
592 OUString aDelim( "/" );
593 OUString *pName = aNames.getArray();
594 for (sal_Int32 i = 0; i < nProps; ++i)
596 OUString &rName = pName[i];
597 OUString aTmp( rName );
598 rName = rBaseNode;
599 rName += aDelim;
600 rName += rSymbolName;
601 rName += aDelim;
602 rName += aTmp;
605 const Sequence< Any > aValues = const_cast<SmMathConfig*>(this)->GetProperties(aNames);
607 if (nProps && aValues.getLength() == nProps)
609 const Any * pValue = aValues.getConstArray();
611 OUString aTmpStr;
612 sal_Int16 nTmp16 = 0;
614 bool bOK = true;
615 if (pValue->hasValue() && (*pValue >>= aTmpStr))
616 rFontFormat.aName = aTmpStr;
617 else
618 bOK = false;
619 ++pValue;
620 if (pValue->hasValue() && (*pValue >>= nTmp16))
621 rFontFormat.nCharSet = nTmp16; // 6.0 file-format GetSOLoadTextEncoding not needed
622 else
623 bOK = false;
624 ++pValue;
625 if (pValue->hasValue() && (*pValue >>= nTmp16))
626 rFontFormat.nFamily = nTmp16;
627 else
628 bOK = false;
629 ++pValue;
630 if (pValue->hasValue() && (*pValue >>= nTmp16))
631 rFontFormat.nPitch = nTmp16;
632 else
633 bOK = false;
634 ++pValue;
635 if (pValue->hasValue() && (*pValue >>= nTmp16))
636 rFontFormat.nWeight = nTmp16;
637 else
638 bOK = false;
639 ++pValue;
640 if (pValue->hasValue() && (*pValue >>= nTmp16))
641 rFontFormat.nItalic = nTmp16;
642 else
643 bOK = false;
644 ++pValue;
646 OSL_ENSURE( bOK, "read FontFormat failed" );
651 void SmMathConfig::SaveFontFormatList()
653 SmFontFormatList &rFntFmtList = GetFontFormatList();
655 if (!rFntFmtList.IsModified())
656 return;
658 Sequence< OUString > aNames = lcl_GetFontPropertyNames();
659 sal_Int32 nSymbolProps = aNames.getLength();
661 size_t nCount = rFntFmtList.GetCount();
663 Sequence< PropertyValue > aValues( nCount * nSymbolProps );
664 PropertyValue *pValues = aValues.getArray();
666 PropertyValue *pVal = pValues;
667 OUString aDelim( "/" );
668 for (size_t i = 0; i < nCount; ++i)
670 OUString aFntFmtId(rFntFmtList.GetFontFormatId(i));
671 const SmFontFormat *pFntFmt = rFntFmtList.GetFontFormat(i);
672 assert(pFntFmt);
673 const SmFontFormat aFntFmt(*pFntFmt);
675 OUString aNodeNameDelim( FONT_FORMAT_LIST );
676 aNodeNameDelim += aDelim;
677 aNodeNameDelim += aFntFmtId;
678 aNodeNameDelim += aDelim;
680 const OUString *pName = aNames.getConstArray();
682 // Name
683 pVal->Name = aNodeNameDelim;
684 pVal->Name += *pName++;
685 pVal->Value <<= aFntFmt.aName;
686 pVal++;
687 // CharSet
688 pVal->Name = aNodeNameDelim;
689 pVal->Name += *pName++;
690 pVal->Value <<= static_cast<sal_Int16>(aFntFmt.nCharSet); // 6.0 file-format GetSOStoreTextEncoding not needed
691 pVal++;
692 // Family
693 pVal->Name = aNodeNameDelim;
694 pVal->Name += *pName++;
695 pVal->Value <<= static_cast<sal_Int16>(aFntFmt.nFamily);
696 pVal++;
697 // Pitch
698 pVal->Name = aNodeNameDelim;
699 pVal->Name += *pName++;
700 pVal->Value <<= static_cast<sal_Int16>(aFntFmt.nPitch);
701 pVal++;
702 // Weight
703 pVal->Name = aNodeNameDelim;
704 pVal->Name += *pName++;
705 pVal->Value <<= static_cast<sal_Int16>(aFntFmt.nWeight);
706 pVal++;
707 // Italic
708 pVal->Name = aNodeNameDelim;
709 pVal->Name += *pName++;
710 pVal->Value <<= static_cast<sal_Int16>(aFntFmt.nItalic);
711 pVal++;
713 OSL_ENSURE( sal::static_int_cast<size_t>(pVal - pValues) == nCount * nSymbolProps, "properties missing" );
714 ReplaceSetProperties( FONT_FORMAT_LIST, aValues );
716 rFntFmtList.SetModified( false );
720 void SmMathConfig::StripFontFormatList( const std::vector< SmSym > &rSymbols )
722 size_t i;
724 // build list of used font-formats only
725 //!! font-format IDs may be different !!
726 SmFontFormatList aUsedList;
727 for (i = 0; i < rSymbols.size(); ++i)
729 OSL_ENSURE( rSymbols[i].GetName().getLength() > 0, "non named symbol" );
730 aUsedList.GetFontFormatId( SmFontFormat( rSymbols[i].GetFace() ) , true );
732 const SmFormat & rStdFmt = GetStandardFormat();
733 for (i = FNT_BEGIN; i <= FNT_END; ++i)
735 aUsedList.GetFontFormatId( SmFontFormat( rStdFmt.GetFont( i ) ) , true );
738 // remove unused font-formats from list
739 SmFontFormatList &rFntFmtList = GetFontFormatList();
740 size_t nCnt = rFntFmtList.GetCount();
741 std::unique_ptr<SmFontFormat[]> pTmpFormat(new SmFontFormat[ nCnt ]);
742 std::unique_ptr<OUString[]> pId(new OUString[ nCnt ]);
743 size_t k;
744 for (k = 0; k < nCnt; ++k)
746 pTmpFormat[k] = *rFntFmtList.GetFontFormat( k );
747 pId[k] = rFntFmtList.GetFontFormatId( k );
749 for (k = 0; k < nCnt; ++k)
751 if (aUsedList.GetFontFormatId( pTmpFormat[k] ).isEmpty())
753 rFntFmtList.RemoveFontFormat( pId[k] );
759 void SmMathConfig::LoadOther()
761 if (!pOther)
762 pOther.reset(new SmCfgOther);
764 pOther->bPrintTitle = officecfg::Office::Math::Print::Title::get();
765 pOther->bPrintFormulaText = officecfg::Office::Math::Print::FormulaText::get();
766 pOther->bPrintFrame = officecfg::Office::Math::Print::Frame::get();
767 pOther->ePrintSize = static_cast<SmPrintSize>(officecfg::Office::Math::Print::Size::get());
768 pOther->nPrintZoomFactor = officecfg::Office::Math::Print::ZoomFactor::get();
769 pOther->bIsSaveOnlyUsedSymbols = officecfg::Office::Math::LoadSave::IsSaveOnlyUsedSymbols::get();
770 pOther->bIsAutoCloseBrackets = officecfg::Office::Math::Misc::AutoCloseBrackets::get();
771 pOther->bIgnoreSpacesRight = officecfg::Office::Math::Misc::IgnoreSpacesRight::get();
772 pOther->bToolboxVisible = officecfg::Office::Math::View::ToolboxVisible::get();
773 pOther->bAutoRedraw = officecfg::Office::Math::View::AutoRedraw::get();
774 pOther->bFormulaCursor = officecfg::Office::Math::View::FormulaCursor::get();
775 SetOtherModified( false );
779 void SmMathConfig::SaveOther()
781 if (!pOther || !IsOtherModified())
782 return;
784 std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
786 officecfg::Office::Math::Print::Title::set(pOther->bPrintTitle, batch);
787 officecfg::Office::Math::Print::FormulaText::set(pOther->bPrintFormulaText, batch);
788 officecfg::Office::Math::Print::Frame::set(pOther->bPrintFrame, batch);
789 officecfg::Office::Math::Print::Size::set(pOther->ePrintSize, batch);
790 officecfg::Office::Math::Print::ZoomFactor::set(pOther->nPrintZoomFactor, batch);
791 officecfg::Office::Math::LoadSave::IsSaveOnlyUsedSymbols::set(pOther->bIsSaveOnlyUsedSymbols, batch);
792 officecfg::Office::Math::Misc::AutoCloseBrackets::set(pOther->bIsAutoCloseBrackets, batch);
793 officecfg::Office::Math::Misc::IgnoreSpacesRight::set(pOther->bIgnoreSpacesRight, batch);
794 officecfg::Office::Math::View::ToolboxVisible::set(pOther->bToolboxVisible, batch);
795 officecfg::Office::Math::View::AutoRedraw::set(pOther->bAutoRedraw, batch);
796 officecfg::Office::Math::View::FormulaCursor::set(pOther->bFormulaCursor, batch);
798 batch->commit();
799 SetOtherModified( false );
802 namespace {
804 // Latin default-fonts
805 const DefaultFontType aLatinDefFnts[FNT_END] =
807 DefaultFontType::SERIF, // FNT_VARIABLE
808 DefaultFontType::SERIF, // FNT_FUNCTION
809 DefaultFontType::SERIF, // FNT_NUMBER
810 DefaultFontType::SERIF, // FNT_TEXT
811 DefaultFontType::SERIF, // FNT_SERIF
812 DefaultFontType::SANS, // FNT_SANS
813 DefaultFontType::FIXED // FNT_FIXED
814 //OpenSymbol, // FNT_MATH
817 // CJK default-fonts
818 //! we use non-asian fonts for variables, functions and numbers since they
819 //! look better and even in asia only latin letters will be used for those.
820 //! At least that's what I was told...
821 const DefaultFontType aCJKDefFnts[FNT_END] =
823 DefaultFontType::SERIF, // FNT_VARIABLE
824 DefaultFontType::SERIF, // FNT_FUNCTION
825 DefaultFontType::SERIF, // FNT_NUMBER
826 DefaultFontType::CJK_TEXT, // FNT_TEXT
827 DefaultFontType::CJK_TEXT, // FNT_SERIF
828 DefaultFontType::CJK_DISPLAY, // FNT_SANS
829 DefaultFontType::CJK_TEXT // FNT_FIXED
830 //OpenSymbol, // FNT_MATH
833 // CTL default-fonts
834 const DefaultFontType aCTLDefFnts[FNT_END] =
836 DefaultFontType::CTL_TEXT, // FNT_VARIABLE
837 DefaultFontType::CTL_TEXT, // FNT_FUNCTION
838 DefaultFontType::CTL_TEXT, // FNT_NUMBER
839 DefaultFontType::CTL_TEXT, // FNT_TEXT
840 DefaultFontType::CTL_TEXT, // FNT_SERIF
841 DefaultFontType::CTL_TEXT, // FNT_SANS
842 DefaultFontType::CTL_TEXT // FNT_FIXED
843 //OpenSymbol, // FNT_MATH
847 OUString lcl_GetDefaultFontName( LanguageType nLang, sal_uInt16 nIdent )
849 assert(nIdent < FNT_END);
850 const DefaultFontType *pTable;
851 switch ( SvtLanguageOptions::GetScriptTypeOfLanguage( nLang ) )
853 case SvtScriptType::LATIN : pTable = aLatinDefFnts; break;
854 case SvtScriptType::ASIAN : pTable = aCJKDefFnts; break;
855 case SvtScriptType::COMPLEX : pTable = aCTLDefFnts; break;
856 default :
857 pTable = aLatinDefFnts;
858 SAL_WARN("starmath", "unknown script-type");
861 return OutputDevice::GetDefaultFont(pTable[ nIdent ], nLang,
862 GetDefaultFontFlags::OnlyOne ).GetFamilyName();
868 void SmMathConfig::LoadFormat()
870 if (!pFormat)
871 pFormat.reset(new SmFormat);
874 Sequence< OUString > aNames = lcl_GetFormatPropertyNames();
876 sal_Int32 nProps = aNames.getLength();
878 Sequence< Any > aValues( GetProperties( aNames ) );
879 if (nProps && aValues.getLength() == nProps)
881 const Any *pValues = aValues.getConstArray();
882 const Any *pVal = pValues;
884 OUString aTmpStr;
885 sal_Int16 nTmp16 = 0;
886 bool bTmp = false;
888 // StandardFormat/Textmode
889 if (pVal->hasValue() && (*pVal >>= bTmp))
890 pFormat->SetTextmode( bTmp );
891 ++pVal;
892 // StandardFormat/GreekCharStyle
893 if (pVal->hasValue() && (*pVal >>= nTmp16))
894 pFormat->SetGreekCharStyle( nTmp16 );
895 ++pVal;
896 // StandardFormat/ScaleNormalBracket
897 if (pVal->hasValue() && (*pVal >>= bTmp))
898 pFormat->SetScaleNormalBrackets( bTmp );
899 ++pVal;
900 // StandardFormat/HorizontalAlignment
901 if (pVal->hasValue() && (*pVal >>= nTmp16))
902 pFormat->SetHorAlign( static_cast<SmHorAlign>(nTmp16) );
903 ++pVal;
904 // StandardFormat/BaseSize
905 if (pVal->hasValue() && (*pVal >>= nTmp16))
906 pFormat->SetBaseSize( Size(0, SmPtsTo100th_mm( nTmp16 )) );
907 ++pVal;
909 sal_uInt16 i;
910 for (i = SIZ_BEGIN; i <= SIZ_END; ++i)
912 if (pVal->hasValue() && (*pVal >>= nTmp16))
913 pFormat->SetRelSize( i, nTmp16 );
914 ++pVal;
917 for (i = DIS_BEGIN; i <= DIS_END; ++i)
919 if (pVal->hasValue() && (*pVal >>= nTmp16))
920 pFormat->SetDistance( i, nTmp16 );
921 ++pVal;
924 LanguageType nLang = Application::GetSettings().GetUILanguageTag().getLanguageType();
925 for (i = FNT_BEGIN; i < FNT_END; ++i)
927 vcl::Font aFnt;
928 bool bUseDefaultFont = true;
929 if (pVal->hasValue() && (*pVal >>= aTmpStr))
931 bUseDefaultFont = aTmpStr.isEmpty();
932 if (bUseDefaultFont)
934 aFnt = pFormat->GetFont( i );
935 aFnt.SetFamilyName( lcl_GetDefaultFontName( nLang, i ) );
937 else
939 const SmFontFormat *pFntFmt = GetFontFormatList().GetFontFormat( aTmpStr );
940 OSL_ENSURE( pFntFmt, "unknown FontFormat" );
941 if (pFntFmt)
942 aFnt = pFntFmt->GetFont();
945 ++pVal;
947 aFnt.SetFontSize( pFormat->GetBaseSize() );
948 pFormat->SetFont( i, aFnt, bUseDefaultFont );
951 OSL_ENSURE( pVal - pValues == nProps, "property mismatch" );
952 SetFormatModified( false );
957 void SmMathConfig::SaveFormat()
959 if (!pFormat || !IsFormatModified())
960 return;
962 const Sequence< OUString > aNames = lcl_GetFormatPropertyNames();
963 sal_Int32 nProps = aNames.getLength();
965 Sequence< Any > aValues( nProps );
966 Any *pValues = aValues.getArray();
967 Any *pValue = pValues;
969 // StandardFormat/Textmode
970 *pValue++ <<= pFormat->IsTextmode();
971 // StandardFormat/GreekCharStyle
972 *pValue++ <<= pFormat->GetGreekCharStyle();
973 // StandardFormat/ScaleNormalBracket
974 *pValue++ <<= pFormat->IsScaleNormalBrackets();
975 // StandardFormat/HorizontalAlignment
976 *pValue++ <<= static_cast<sal_Int16>(pFormat->GetHorAlign());
977 // StandardFormat/BaseSize
978 *pValue++ <<= static_cast<sal_Int16>(SmRoundFraction( Sm100th_mmToPts(
979 pFormat->GetBaseSize().Height() ) ));
981 sal_uInt16 i;
982 for (i = SIZ_BEGIN; i <= SIZ_END; ++i)
983 *pValue++ <<= static_cast<sal_Int16>(pFormat->GetRelSize( i ));
985 for (i = DIS_BEGIN; i <= DIS_END; ++i)
986 *pValue++ <<= static_cast<sal_Int16>(pFormat->GetDistance( i ));
988 for (i = FNT_BEGIN; i < FNT_END; ++i)
990 OUString aFntFmtId;
992 if (!pFormat->IsDefaultFont( i ))
994 SmFontFormat aFntFmt( pFormat->GetFont( i ) );
995 aFntFmtId = GetFontFormatList().GetFontFormatId( aFntFmt, true );
996 OSL_ENSURE( !aFntFmtId.isEmpty(), "FontFormatId not found" );
999 *pValue++ <<= aFntFmtId;
1002 OSL_ENSURE( pValue - pValues == nProps, "property mismatch" );
1003 PutProperties( aNames , aValues );
1005 SetFormatModified( false );
1009 const SmFormat & SmMathConfig::GetStandardFormat() const
1011 if (!pFormat)
1012 const_cast<SmMathConfig*>(this)->LoadFormat();
1013 return *pFormat;
1017 void SmMathConfig::SetStandardFormat( const SmFormat &rFormat, bool bSaveFontFormatList )
1019 if (!pFormat)
1020 LoadFormat();
1021 if (rFormat != *pFormat)
1023 *pFormat = rFormat;
1024 SetFormatModified( true );
1025 SaveFormat();
1027 if (bSaveFontFormatList)
1029 // needed for SmFontTypeDialog's DefaultButtonClickHdl
1030 if (pFontFormatList)
1031 pFontFormatList->SetModified( true );
1032 SaveFontFormatList();
1038 SmPrintSize SmMathConfig::GetPrintSize() const
1040 if (!pOther)
1041 const_cast<SmMathConfig*>(this)->LoadOther();
1042 return pOther->ePrintSize;
1046 void SmMathConfig::SetPrintSize( SmPrintSize eSize )
1048 if (!pOther)
1049 LoadOther();
1050 if (eSize != pOther->ePrintSize)
1052 pOther->ePrintSize = eSize;
1053 SetOtherModified( true );
1058 sal_uInt16 SmMathConfig::GetPrintZoomFactor() const
1060 if (!pOther)
1061 const_cast<SmMathConfig*>(this)->LoadOther();
1062 return pOther->nPrintZoomFactor;
1066 void SmMathConfig::SetPrintZoomFactor( sal_uInt16 nVal )
1068 if (!pOther)
1069 LoadOther();
1070 if (nVal != pOther->nPrintZoomFactor)
1072 pOther->nPrintZoomFactor = nVal;
1073 SetOtherModified( true );
1078 void SmMathConfig::SetOtherIfNotEqual( bool &rbItem, bool bNewVal )
1080 if (bNewVal != rbItem)
1082 rbItem = bNewVal;
1083 SetOtherModified( true );
1088 bool SmMathConfig::IsPrintTitle() const
1090 if (!pOther)
1091 const_cast<SmMathConfig*>(this)->LoadOther();
1092 return pOther->bPrintTitle;
1096 void SmMathConfig::SetPrintTitle( bool bVal )
1098 if (!pOther)
1099 LoadOther();
1100 SetOtherIfNotEqual( pOther->bPrintTitle, bVal );
1104 bool SmMathConfig::IsPrintFormulaText() const
1106 if (!pOther)
1107 const_cast<SmMathConfig*>(this)->LoadOther();
1108 return pOther->bPrintFormulaText;
1112 void SmMathConfig::SetPrintFormulaText( bool bVal )
1114 if (!pOther)
1115 LoadOther();
1116 SetOtherIfNotEqual( pOther->bPrintFormulaText, bVal );
1119 bool SmMathConfig::IsSaveOnlyUsedSymbols() const
1121 if (!pOther)
1122 const_cast<SmMathConfig*>(this)->LoadOther();
1123 return pOther->bIsSaveOnlyUsedSymbols;
1126 bool SmMathConfig::IsAutoCloseBrackets() const
1128 if (!pOther)
1129 const_cast<SmMathConfig*>(this)->LoadOther();
1130 return pOther->bIsAutoCloseBrackets;
1133 bool SmMathConfig::IsPrintFrame() const
1135 if (!pOther)
1136 const_cast<SmMathConfig*>(this)->LoadOther();
1137 return pOther->bPrintFrame;
1141 void SmMathConfig::SetPrintFrame( bool bVal )
1143 if (!pOther)
1144 LoadOther();
1145 SetOtherIfNotEqual( pOther->bPrintFrame, bVal );
1149 void SmMathConfig::SetSaveOnlyUsedSymbols( bool bVal )
1151 if (!pOther)
1152 LoadOther();
1153 SetOtherIfNotEqual( pOther->bIsSaveOnlyUsedSymbols, bVal );
1157 void SmMathConfig::SetAutoCloseBrackets( bool bVal )
1159 if (!pOther)
1160 LoadOther();
1161 SetOtherIfNotEqual( pOther->bIsAutoCloseBrackets, bVal );
1165 bool SmMathConfig::IsIgnoreSpacesRight() const
1167 if (!pOther)
1168 const_cast<SmMathConfig*>(this)->LoadOther();
1169 return pOther->bIgnoreSpacesRight;
1173 void SmMathConfig::SetIgnoreSpacesRight( bool bVal )
1175 if (!pOther)
1176 LoadOther();
1177 SetOtherIfNotEqual( pOther->bIgnoreSpacesRight, bVal );
1181 bool SmMathConfig::IsAutoRedraw() const
1183 if (!pOther)
1184 const_cast<SmMathConfig*>(this)->LoadOther();
1185 return pOther->bAutoRedraw;
1189 void SmMathConfig::SetAutoRedraw( bool bVal )
1191 if (!pOther)
1192 LoadOther();
1193 SetOtherIfNotEqual( pOther->bAutoRedraw, bVal );
1197 bool SmMathConfig::IsShowFormulaCursor() const
1199 if (!pOther)
1200 const_cast<SmMathConfig*>(this)->LoadOther();
1201 return pOther->bFormulaCursor;
1205 void SmMathConfig::SetShowFormulaCursor( bool bVal )
1207 if (!pOther)
1208 LoadOther();
1209 SetOtherIfNotEqual( pOther->bFormulaCursor, bVal );
1212 void SmMathConfig::Notify( const css::uno::Sequence< OUString >& )
1216 void SmMathConfig::ItemSetToConfig(const SfxItemSet &rSet)
1218 const SfxPoolItem *pItem = nullptr;
1220 sal_uInt16 nU16;
1221 bool bVal;
1222 if (rSet.GetItemState(SID_PRINTSIZE, true, &pItem) == SfxItemState::SET)
1223 { nU16 = static_cast<const SfxUInt16Item *>(pItem)->GetValue();
1224 SetPrintSize( static_cast<SmPrintSize>(nU16) );
1226 if (rSet.GetItemState(SID_PRINTZOOM, true, &pItem) == SfxItemState::SET)
1227 { nU16 = static_cast<const SfxUInt16Item *>(pItem)->GetValue();
1228 SetPrintZoomFactor( nU16 );
1230 if (rSet.GetItemState(SID_PRINTTITLE, true, &pItem) == SfxItemState::SET)
1231 { bVal = static_cast<const SfxBoolItem *>(pItem)->GetValue();
1232 SetPrintTitle( bVal );
1234 if (rSet.GetItemState(SID_PRINTTEXT, true, &pItem) == SfxItemState::SET)
1235 { bVal = static_cast<const SfxBoolItem *>(pItem)->GetValue();
1236 SetPrintFormulaText( bVal );
1238 if (rSet.GetItemState(SID_PRINTFRAME, true, &pItem) == SfxItemState::SET)
1239 { bVal = static_cast<const SfxBoolItem *>(pItem)->GetValue();
1240 SetPrintFrame( bVal );
1242 if (rSet.GetItemState(SID_AUTOREDRAW, true, &pItem) == SfxItemState::SET)
1243 { bVal = static_cast<const SfxBoolItem *>(pItem)->GetValue();
1244 SetAutoRedraw( bVal );
1246 if (rSet.GetItemState(SID_NO_RIGHT_SPACES, true, &pItem) == SfxItemState::SET)
1247 { bVal = static_cast<const SfxBoolItem *>(pItem)->GetValue();
1248 if (IsIgnoreSpacesRight() != bVal)
1250 SetIgnoreSpacesRight( bVal );
1252 // reformat (displayed) formulas accordingly
1253 Broadcast(SfxHint(SfxHintId::MathFormatChanged));
1256 if (rSet.GetItemState(SID_SAVE_ONLY_USED_SYMBOLS, true, &pItem) == SfxItemState::SET)
1257 { bVal = static_cast<const SfxBoolItem *>(pItem)->GetValue();
1258 SetSaveOnlyUsedSymbols( bVal );
1261 if (rSet.GetItemState(SID_AUTO_CLOSE_BRACKETS, true, &pItem) == SfxItemState::SET)
1263 bVal = static_cast<const SfxBoolItem *>(pItem)->GetValue();
1264 SetAutoCloseBrackets( bVal );
1267 SaveOther();
1271 void SmMathConfig::ConfigToItemSet(SfxItemSet &rSet) const
1273 const SfxItemPool *pPool = rSet.GetPool();
1275 rSet.Put(SfxUInt16Item(pPool->GetWhich(SID_PRINTSIZE),
1276 sal::static_int_cast<sal_uInt16>(GetPrintSize())));
1277 rSet.Put(SfxUInt16Item(pPool->GetWhich(SID_PRINTZOOM),
1278 GetPrintZoomFactor()));
1280 rSet.Put(SfxBoolItem(pPool->GetWhich(SID_PRINTTITLE), IsPrintTitle()));
1281 rSet.Put(SfxBoolItem(pPool->GetWhich(SID_PRINTTEXT), IsPrintFormulaText()));
1282 rSet.Put(SfxBoolItem(pPool->GetWhich(SID_PRINTFRAME), IsPrintFrame()));
1283 rSet.Put(SfxBoolItem(pPool->GetWhich(SID_AUTOREDRAW), IsAutoRedraw()));
1284 rSet.Put(SfxBoolItem(pPool->GetWhich(SID_NO_RIGHT_SPACES), IsIgnoreSpacesRight()));
1285 rSet.Put(SfxBoolItem(pPool->GetWhich(SID_SAVE_ONLY_USED_SYMBOLS), IsSaveOnlyUsedSymbols()));
1286 rSet.Put(SfxBoolItem(pPool->GetWhich(SID_AUTO_CLOSE_BRACKETS), IsAutoCloseBrackets()));
1289 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */