xref: /aoo42x/main/starmath/source/cfgitem.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_starmath.hxx"
30 
31 
32 #include <vcl/svapp.hxx>
33 
34 #include "cfgitem.hxx"
35 
36 #include "starmath.hrc"
37 #include "smdll.hxx"
38 #include "format.hxx"
39 
40 using namespace rtl;
41 using namespace com::sun::star;
42 using namespace com::sun::star::uno;
43 using namespace com::sun::star::beans;
44 
45 
46 static const char* aRootName = "Office.Math";
47 
48 #define SYMBOL_LIST         "SymbolList"
49 #define FONT_FORMAT_LIST    "FontFormatList"
50 
51 /////////////////////////////////////////////////////////////////
52 
53 
54 static Sequence< OUString > lcl_GetFontPropertyNames()
55 {
56 	static const char * aPropNames[] =
57 	{
58         "Name",
59         "CharSet",
60         "Family",
61         "Pitch",
62         "Weight",
63         "Italic",
64 		0
65 	};
66 
67 	const char** ppPropName = aPropNames;
68 
69     Sequence< OUString > aNames( 6 );
70 	OUString *pNames = aNames.getArray();
71 	for( sal_Int32 i = 0; *ppPropName;  ++i, ++ppPropName )
72 	{
73 		pNames[i] = A2OU( *ppPropName );
74 	}
75 	//aNames.realloc( i );
76 	return aNames;
77 }
78 
79 /////////////////////////////////////////////////////////////////
80 
81 
82 static Sequence< OUString > lcl_GetSymbolPropertyNames()
83 {
84 	static const char * aPropNames[] =
85 	{
86         "Char",
87         "Set",
88         "Predefined",
89         "FontFormatId",
90 		0
91 	};
92 
93 	const char** ppPropName = aPropNames;
94 
95     Sequence< OUString > aNames( 4 );
96 	OUString *pNames = aNames.getArray();
97 	for( sal_Int32 i = 0; *ppPropName;  ++i, ++ppPropName )
98 	{
99 		pNames[i] = A2OU( *ppPropName );
100 	}
101 	//aNames.realloc( i );
102 	return aNames;
103 }
104 
105 /////////////////////////////////////////////////////////////////
106 
107 static const char * aMathPropNames[] =
108 {
109     "Print/Title",
110     "Print/FormulaText",
111     "Print/Frame",
112     "Print/Size",
113     "Print/ZoomFactor",
114     "LoadSave/IsSaveOnlyUsedSymbols",
115     //"Misc/NoSymbolsWarning",  @deprecated
116     "Misc/IgnoreSpacesRight",
117     "View/ToolboxVisible",
118     "View/AutoRedraw",
119     "View/FormulaCursor"
120 };
121 
122 
123 //! Beware of order according to *_BEGIN *_END defines in format.hxx !
124 //! see respective load/save routines here
125 static const char * aFormatPropNames[] =
126 {
127     "StandardFormat/Textmode",
128     "StandardFormat/GreekCharStyle",
129     "StandardFormat/ScaleNormalBracket",
130     "StandardFormat/HorizontalAlignment",
131     "StandardFormat/BaseSize",
132     "StandardFormat/TextSize",
133     "StandardFormat/IndexSize",
134     "StandardFormat/FunctionSize",
135     "StandardFormat/OperatorSize",
136     "StandardFormat/LimitsSize",
137     "StandardFormat/Distance/Horizontal",
138     "StandardFormat/Distance/Vertical",
139     "StandardFormat/Distance/Root",
140     "StandardFormat/Distance/SuperScript",
141     "StandardFormat/Distance/SubScript",
142     "StandardFormat/Distance/Numerator",
143     "StandardFormat/Distance/Denominator",
144     "StandardFormat/Distance/Fraction",
145     "StandardFormat/Distance/StrokeWidth",
146     "StandardFormat/Distance/UpperLimit",
147     "StandardFormat/Distance/LowerLimit",
148     "StandardFormat/Distance/BracketSize",
149     "StandardFormat/Distance/BracketSpace",
150     "StandardFormat/Distance/MatrixRow",
151     "StandardFormat/Distance/MatrixColumn",
152     "StandardFormat/Distance/OrnamentSize",
153     "StandardFormat/Distance/OrnamentSpace",
154     "StandardFormat/Distance/OperatorSize",
155     "StandardFormat/Distance/OperatorSpace",
156     "StandardFormat/Distance/LeftSpace",
157     "StandardFormat/Distance/RightSpace",
158     "StandardFormat/Distance/TopSpace",
159     "StandardFormat/Distance/BottomSpace",
160     "StandardFormat/Distance/NormalBracketSize",
161     "StandardFormat/VariableFont",
162     "StandardFormat/FunctionFont",
163     "StandardFormat/NumberFont",
164     "StandardFormat/TextFont",
165     "StandardFormat/SerifFont",
166     "StandardFormat/SansFont",
167     "StandardFormat/FixedFont"
168 };
169 
170 
171 static Sequence< OUString > lcl_GetPropertyNames(
172         const char * aPropNames[], sal_uInt16 nCount )
173 {
174 
175 	const char** ppPropName = aPropNames;
176 
177     Sequence< OUString > aNames( nCount );
178 	OUString *pNames = aNames.getArray();
179     for (sal_Int32 i = 0;  i < nCount;  ++i, ++ppPropName)
180 	{
181 		pNames[i] = A2OU( *ppPropName );
182 	}
183 	//aNames.realloc( i );
184 	return aNames;
185 }
186 
187 
188 static Sequence< OUString > GetFormatPropertyNames()
189 {
190     sal_uInt16 nCnt = sizeof(aFormatPropNames) / sizeof(aFormatPropNames[0]);
191     return lcl_GetPropertyNames( aFormatPropNames, nCnt );
192 }
193 
194 
195 static Sequence< OUString > GetOtherPropertyNames()
196 {
197     sal_uInt16 nCnt = sizeof(aMathPropNames) / sizeof(aMathPropNames[0]);
198     return lcl_GetPropertyNames( aMathPropNames, nCnt );
199 }
200 
201 /////////////////////////////////////////////////////////////////
202 
203 struct SmCfgOther
204 {
205     SmPrintSize     ePrintSize;
206     sal_uInt16      nPrintZoomFactor;
207     sal_Bool        bPrintTitle;
208     sal_Bool        bPrintFormulaText;
209     sal_Bool        bPrintFrame;
210     sal_Bool        bIsSaveOnlyUsedSymbols;
211     sal_Bool        bIgnoreSpacesRight;
212     sal_Bool        bToolboxVisible;
213     sal_Bool        bAutoRedraw;
214     sal_Bool        bFormulaCursor;
215     //sal_Bool            bNoSymbolsWarning;
216 
217     SmCfgOther();
218 };
219 
220 
221 SmCfgOther::SmCfgOther()
222 {
223     ePrintSize          = PRINT_SIZE_NORMAL;
224     nPrintZoomFactor    = 100;
225     bPrintTitle         = bPrintFormulaText   =
226     bPrintFrame         = bIgnoreSpacesRight  =
227     bToolboxVisible     = bAutoRedraw         =
228     bFormulaCursor      = bIsSaveOnlyUsedSymbols = sal_True;
229 }
230 
231 /////////////////////////////////////////////////////////////////
232 
233 
234 SmFontFormat::SmFontFormat()
235 {
236     aName.AssignAscii( FONTNAME_MATH );
237     nCharSet    = RTL_TEXTENCODING_UNICODE;
238     nFamily     = FAMILY_DONTKNOW;
239     nPitch      = PITCH_DONTKNOW;
240     nWeight     = WEIGHT_DONTKNOW;
241     nItalic     = ITALIC_NONE;
242 }
243 
244 
245 SmFontFormat::SmFontFormat( const Font &rFont )
246 {
247     aName       = rFont.GetName();
248     nCharSet    = (sal_Int16) rFont.GetCharSet();
249     nFamily     = (sal_Int16) rFont.GetFamily();
250     nPitch      = (sal_Int16) rFont.GetPitch();
251     nWeight     = (sal_Int16) rFont.GetWeight();
252     nItalic     = (sal_Int16) rFont.GetItalic();
253 }
254 
255 
256 const Font SmFontFormat::GetFont() const
257 {
258     Font aRes;
259     aRes.SetName( aName );
260     aRes.SetCharSet( (rtl_TextEncoding) nCharSet );
261     aRes.SetFamily( (FontFamily) nFamily );
262     aRes.SetPitch( (FontPitch) nPitch );
263     aRes.SetWeight( (FontWeight) nWeight );
264     aRes.SetItalic( (FontItalic) nItalic );
265     return aRes;
266 }
267 
268 
269 sal_Bool SmFontFormat::operator == ( const SmFontFormat &rFntFmt ) const
270 {
271     return  aName    == rFntFmt.aName       &&
272             nCharSet == rFntFmt.nCharSet    &&
273             nFamily  == rFntFmt.nFamily     &&
274             nPitch   == rFntFmt.nPitch      &&
275             nWeight  == rFntFmt.nWeight     &&
276             nItalic  == rFntFmt.nItalic;
277 }
278 
279 
280 /////////////////////////////////////////////////////////////////
281 
282 SmFntFmtListEntry::SmFntFmtListEntry( const String &rId, const SmFontFormat &rFntFmt ) :
283     aId     (rId),
284     aFntFmt (rFntFmt)
285 {
286 }
287 
288 
289 SmFontFormatList::SmFontFormatList()
290 {
291     bModified = sal_False;
292 }
293 
294 
295 void SmFontFormatList::Clear()
296 {
297     if (!aEntries.empty())
298     {
299         aEntries.clear();
300         SetModified( sal_True );
301     }
302 }
303 
304 
305 void SmFontFormatList::AddFontFormat( const String &rFntFmtId,
306         const SmFontFormat &rFntFmt )
307 {
308     const SmFontFormat *pFntFmt = GetFontFormat( rFntFmtId );
309     DBG_ASSERT( !pFntFmt, "FontFormatId already exists" );
310     if (!pFntFmt)
311     {
312         SmFntFmtListEntry aEntry( rFntFmtId, rFntFmt );
313         aEntries.push_back( aEntry );
314         SetModified( sal_True );
315     }
316 }
317 
318 
319 void SmFontFormatList::RemoveFontFormat( const String &rFntFmtId )
320 {
321 
322     // search for entry
323     for (size_t i = 0;  i < aEntries.size();  ++i)
324     {
325         if (aEntries[i].aId == rFntFmtId)
326         {
327             // remove entry if found
328             aEntries.erase( aEntries.begin() + i );
329             SetModified( sal_True );
330             break;
331         }
332     }
333 }
334 
335 
336 const SmFontFormat * SmFontFormatList::GetFontFormat( const String &rFntFmtId ) const
337 {
338     const SmFontFormat *pRes = 0;
339 
340     for (size_t i = 0;  i < aEntries.size();  ++i)
341     {
342         if (aEntries[i].aId == rFntFmtId)
343         {
344             pRes = &aEntries[i].aFntFmt;
345             break;
346         }
347     }
348 
349     return pRes;
350 }
351 
352 
353 
354 const SmFontFormat * SmFontFormatList::GetFontFormat( size_t nPos ) const
355 {
356     const SmFontFormat *pRes = 0;
357     if (nPos < aEntries.size())
358         pRes = &aEntries[nPos].aFntFmt;
359     return pRes;
360 }
361 
362 
363 const String SmFontFormatList::GetFontFormatId( const SmFontFormat &rFntFmt ) const
364 {
365     String aRes;
366 
367     for (size_t i = 0;  i < aEntries.size();  ++i)
368     {
369         if (aEntries[i].aFntFmt == rFntFmt)
370         {
371             aRes = aEntries[i].aId;
372             break;
373         }
374     }
375 
376     return aRes;
377 }
378 
379 
380 const String SmFontFormatList::GetFontFormatId( const SmFontFormat &rFntFmt, sal_Bool bAdd )
381 {
382     String aRes( GetFontFormatId( rFntFmt) );
383     if (0 == aRes.Len()  &&  bAdd)
384     {
385         aRes = GetNewFontFormatId();
386         AddFontFormat( aRes, rFntFmt );
387     }
388     return aRes;
389 }
390 
391 
392 const String SmFontFormatList::GetFontFormatId( size_t nPos ) const
393 {
394     String aRes;
395     if (nPos < aEntries.size())
396         aRes = aEntries[nPos].aId;
397     return aRes;
398 }
399 
400 
401 const String SmFontFormatList::GetNewFontFormatId() const
402 {
403     // returns first unused FormatId
404 
405     String aRes;
406 
407     String aPrefix( RTL_CONSTASCII_STRINGPARAM( "Id" ) );
408     sal_Int32 nCnt = GetCount();
409     for (sal_Int32 i = 1;  i <= nCnt + 1;  ++i)
410     {
411         String aTmpId( aPrefix );
412         aTmpId += String::CreateFromInt32( i );
413         if (!GetFontFormat( aTmpId ))
414         {
415             aRes = aTmpId;
416             break;
417         }
418     }
419     DBG_ASSERT( 0 != aRes.Len(), "failed to create new FontFormatId" );
420 
421     return aRes;
422 }
423 
424 /////////////////////////////////////////////////////////////////
425 
426 SmMathConfig::SmMathConfig() :
427     ConfigItem( String::CreateFromAscii( aRootName ))
428 {
429     pFormat         = 0;
430     pOther          = 0;
431     pFontFormatList = 0;
432     pSymbolMgr      = 0;
433 
434     bIsOtherModified = bIsFormatModified = sal_False;
435 }
436 
437 
438 SmMathConfig::~SmMathConfig()
439 {
440     Save();
441     delete pFormat;
442     delete pOther;
443     delete pFontFormatList;
444     delete pSymbolMgr;
445 }
446 
447 
448 void SmMathConfig::SetOtherModified( sal_Bool bVal )
449 {
450     bIsOtherModified = bVal;
451 }
452 
453 
454 void SmMathConfig::SetFormatModified( sal_Bool bVal )
455 {
456     bIsFormatModified = bVal;
457 }
458 
459 
460 void SmMathConfig::SetFontFormatListModified( sal_Bool bVal )
461 {
462     if (pFontFormatList)
463         pFontFormatList->SetModified( bVal );
464 }
465 
466 
467 void SmMathConfig::ReadSymbol( SmSym &rSymbol,
468 						const rtl::OUString &rSymbolName,
469 						const rtl::OUString &rBaseNode ) const
470 {
471 	Sequence< OUString > aNames = lcl_GetSymbolPropertyNames();
472 	sal_Int32 nProps = aNames.getLength();
473 
474 	OUString aDelim( OUString::valueOf( (sal_Unicode) '/' ) );
475 	OUString *pName = aNames.getArray();
476 	for (sal_Int32 i = 0;  i < nProps;  ++i)
477 	{
478 		OUString &rName = pName[i];
479 		OUString aTmp( rName );
480 		rName = rBaseNode;
481 		rName += aDelim;
482 		rName += rSymbolName;
483 		rName += aDelim;
484 		rName += aTmp;
485 	}
486 
487     const Sequence< Any > aValues = ((SmMathConfig*) this)->GetProperties( aNames );
488 
489 	if (nProps  &&  aValues.getLength() == nProps)
490 	{
491 		const Any * pValue = aValues.getConstArray();
492         Font        aFont;
493         sal_UCS4    cChar = '\0';
494         String      aSet;
495         sal_Bool        bPredefined = sal_False;
496 
497         OUString    aTmpStr;
498         sal_Int32       nTmp32 = 0;
499         sal_Bool        bTmp = sal_False;
500 
501         sal_Bool bOK = sal_True;
502         if (pValue->hasValue()  &&  (*pValue >>= nTmp32))
503             cChar = static_cast< sal_UCS4 >( nTmp32 );
504         else
505             bOK = sal_False;
506         ++pValue;
507         if (pValue->hasValue()  &&  (*pValue >>= aTmpStr))
508             aSet = aTmpStr;
509         else
510             bOK = sal_False;
511 		++pValue;
512         if (pValue->hasValue()  &&  (*pValue >>= bTmp))
513             bPredefined = bTmp;
514         else
515             bOK = sal_False;
516 		++pValue;
517         if (pValue->hasValue()  &&  (*pValue >>= aTmpStr))
518         {
519             const SmFontFormat *pFntFmt = GetFontFormatList().GetFontFormat( aTmpStr );
520             DBG_ASSERT( pFntFmt, "unknown FontFormat" );
521             if (pFntFmt)
522                 aFont = pFntFmt->GetFont();
523         }
524         else
525             bOK = sal_False;
526         ++pValue;
527 
528         if (bOK)
529         {
530             String aUiName( rSymbolName );
531             String aUiSetName( aSet );
532             if (bPredefined)
533             {
534                 String aTmp;
535                 aTmp = GetUiSymbolName( rSymbolName );
536                 DBG_ASSERT( aTmp.Len(), "localized symbol-name not found" );
537                 if (aTmp.Len())
538                     aUiName = aTmp;
539                 aTmp = GetUiSymbolSetName( aSet );
540                 DBG_ASSERT( aTmp.Len(), "localized symbolset-name not found" );
541                 if (aTmp.Len())
542                     aUiSetName = aTmp;
543             }
544 
545             rSymbol = SmSym( aUiName, aFont, cChar, aUiSetName, bPredefined );
546             if (aUiName != String(rSymbolName))
547                 rSymbol.SetExportName( rSymbolName );
548         }
549         else
550         {
551             DBG_ERROR( "symbol read error" );
552         }
553 	}
554 }
555 
556 
557 SmSymbolManager & SmMathConfig::GetSymbolManager()
558 {
559     if (!pSymbolMgr)
560     {
561         pSymbolMgr = new SmSymbolManager;
562         pSymbolMgr->Load();
563     }
564     return *pSymbolMgr;
565 }
566 
567 
568 void SmMathConfig::Commit()
569 {
570     Save();
571 }
572 
573 
574 void SmMathConfig::Save()
575 {
576     SaveOther();
577     SaveFormat();
578     SaveFontFormatList();
579 }
580 
581 
582 void SmMathConfig::GetSymbols( std::vector< SmSym > &rSymbols ) const
583 {
584     Sequence< OUString > aNodes( ((SmMathConfig*) this)->GetNodeNames( A2OU( SYMBOL_LIST ) ) );
585     const OUString *pNode = aNodes.getConstArray();
586     sal_Int32 nNodes = aNodes.getLength();
587 
588     rSymbols.resize( nNodes );
589     std::vector< SmSym >::iterator aIt( rSymbols.begin() );
590     std::vector< SmSym >::iterator aEnd( rSymbols.end() );
591     while (aIt != aEnd)
592     {
593         ReadSymbol( *aIt++, *pNode++, A2OU( SYMBOL_LIST ) );
594     }
595 }
596 
597 
598 void SmMathConfig::SetSymbols( const std::vector< SmSym > &rNewSymbols )
599 {
600     sal_uIntPtr nCount = rNewSymbols.size();
601 
602     Sequence< OUString > aNames = lcl_GetSymbolPropertyNames();
603     const OUString *pNames = aNames.getConstArray();
604     sal_uIntPtr nSymbolProps = sal::static_int_cast< sal_uInt32 >(aNames.getLength());
605 
606     Sequence< PropertyValue > aValues( nCount * nSymbolProps );
607     PropertyValue *pValues = aValues.getArray();
608 
609     PropertyValue *pVal = pValues;
610     OUString aDelim( OUString::valueOf( (sal_Unicode) '/' ) );
611     std::vector< SmSym >::const_iterator aIt( rNewSymbols.begin() );
612     std::vector< SmSym >::const_iterator aEnd( rNewSymbols.end() );
613     while (aIt != aEnd)
614     {
615         const SmSym &rSymbol = *aIt++;
616         //const Font  &rFont = rSymbol.GetFace();
617         OUString  aNodeNameDelim( A2OU( SYMBOL_LIST ) );
618         aNodeNameDelim += aDelim;
619         aNodeNameDelim += rSymbol.GetExportName();
620         aNodeNameDelim += aDelim;
621 
622         const OUString *pName = pNames;
623 
624         // Char
625         pVal->Name  = aNodeNameDelim;
626         pVal->Name += *pName++;
627         pVal->Value <<= static_cast< sal_UCS4 >( rSymbol.GetCharacter() );
628         pVal++;
629         // Set
630         pVal->Name  = aNodeNameDelim;
631         pVal->Name += *pName++;
632         OUString aTmp( rSymbol.GetSymbolSetName() );
633         if (rSymbol.IsPredefined())
634             aTmp = GetExportSymbolSetName( aTmp );
635         pVal->Value <<= aTmp;
636         pVal++;
637         // Predefined
638         pVal->Name  = aNodeNameDelim;
639         pVal->Name += *pName++;
640         pVal->Value <<= (sal_Bool) rSymbol.IsPredefined();
641         pVal++;
642         // FontFormatId
643         SmFontFormat aFntFmt( rSymbol.GetFace() );
644         String aFntFmtId( GetFontFormatList().GetFontFormatId( aFntFmt, sal_True ) );
645         DBG_ASSERT( aFntFmtId.Len(), "FontFormatId not found" );
646         pVal->Name  = aNodeNameDelim;
647         pVal->Name += *pName++;
648         pVal->Value <<= OUString( aFntFmtId );
649         pVal++;
650     }
651     DBG_ASSERT( pVal - pValues == sal::static_int_cast< ptrdiff_t >(nCount * nSymbolProps), "properties missing" );
652     ReplaceSetProperties( A2OU( SYMBOL_LIST ) , aValues );
653 
654     StripFontFormatList( rNewSymbols );
655     SaveFontFormatList();
656 }
657 
658 
659 SmFontFormatList & SmMathConfig::GetFontFormatList()
660 {
661     if (!pFontFormatList)
662     {
663         LoadFontFormatList();
664     }
665     return *pFontFormatList;
666 }
667 
668 
669 void SmMathConfig::LoadFontFormatList()
670 {
671     if (!pFontFormatList)
672         pFontFormatList = new SmFontFormatList;
673     else
674         pFontFormatList->Clear();
675 
676     Sequence< OUString > aNodes( GetNodeNames( A2OU( FONT_FORMAT_LIST ) ) );
677 	const OUString *pNode = aNodes.getConstArray();
678 	sal_Int32 nNodes = aNodes.getLength();
679 
680 	for (sal_Int32 i = 0;  i < nNodes;  ++i)
681 	{
682         SmFontFormat aFntFmt;
683         ReadFontFormat( aFntFmt, pNode[i], A2OU( FONT_FORMAT_LIST ) );
684         if (!pFontFormatList->GetFontFormat( pNode[i] ))
685         {
686             DBG_ASSERT( 0 == pFontFormatList->GetFontFormat( pNode[i] ),
687                     "FontFormat ID already exists" );
688             pFontFormatList->AddFontFormat( pNode[i], aFntFmt );
689         }
690 	}
691     pFontFormatList->SetModified( sal_False );
692 }
693 
694 
695 void SmMathConfig::ReadFontFormat( SmFontFormat &rFontFormat,
696         const OUString &rSymbolName, const OUString &rBaseNode ) const
697 {
698     Sequence< OUString > aNames = lcl_GetFontPropertyNames();
699 	sal_Int32 nProps = aNames.getLength();
700 
701 	OUString aDelim( OUString::valueOf( (sal_Unicode) '/' ) );
702 	OUString *pName = aNames.getArray();
703 	for (sal_Int32 i = 0;  i < nProps;  ++i)
704 	{
705 		OUString &rName = pName[i];
706 		OUString aTmp( rName );
707 		rName = rBaseNode;
708 		rName += aDelim;
709 		rName += rSymbolName;
710 		rName += aDelim;
711 		rName += aTmp;
712 	}
713 
714     const Sequence< Any > aValues = ((SmMathConfig*) this)->GetProperties( aNames );
715 
716 	if (nProps  &&  aValues.getLength() == nProps)
717 	{
718 		const Any * pValue = aValues.getConstArray();
719 
720         OUString    aTmpStr;
721         sal_Int16       nTmp16 = 0;
722 
723         sal_Bool bOK = sal_True;
724         if (pValue->hasValue()  &&  (*pValue >>= aTmpStr))
725             rFontFormat.aName = aTmpStr;
726         else
727             bOK = sal_False;
728         ++pValue;
729         if (pValue->hasValue()  &&  (*pValue >>= nTmp16))
730             rFontFormat.nCharSet = nTmp16; // 6.0 file-format GetSOLoadTextEncoding not needed
731         else
732             bOK = sal_False;
733 		++pValue;
734         if (pValue->hasValue()  &&  (*pValue >>= nTmp16))
735             rFontFormat.nFamily = nTmp16;
736         else
737             bOK = sal_False;
738 		++pValue;
739         if (pValue->hasValue()  &&  (*pValue >>= nTmp16))
740             rFontFormat.nPitch = nTmp16;
741         else
742             bOK = sal_False;
743 		++pValue;
744         if (pValue->hasValue()  &&  (*pValue >>= nTmp16))
745             rFontFormat.nWeight = nTmp16;
746         else
747             bOK = sal_False;
748 		++pValue;
749         if (pValue->hasValue()  &&  (*pValue >>= nTmp16))
750             rFontFormat.nItalic = nTmp16;
751         else
752             bOK = sal_False;
753 		++pValue;
754 
755         DBG_ASSERT( bOK, "read FontFormat failed" );
756 	}
757 }
758 
759 
760 void SmMathConfig::SaveFontFormatList()
761 {
762     SmFontFormatList &rFntFmtList = GetFontFormatList();
763 
764     if (!rFntFmtList.IsModified())
765         return;
766 
767     Sequence< OUString > aNames = lcl_GetFontPropertyNames();
768     sal_Int32 nSymbolProps = aNames.getLength();
769 
770     size_t nCount = rFntFmtList.GetCount();
771 
772     Sequence< PropertyValue > aValues( nCount * nSymbolProps );
773     PropertyValue *pValues = aValues.getArray();
774 
775     PropertyValue *pVal = pValues;
776     OUString aDelim( OUString::valueOf( (sal_Unicode) '/' ) );
777     for (size_t i = 0;  i < nCount;  ++i)
778     {
779         String aFntFmtId( rFntFmtList.GetFontFormatId( i ) );
780         const SmFontFormat aFntFmt( *rFntFmtList.GetFontFormat( aFntFmtId ) );
781 
782         OUString  aNodeNameDelim( A2OU( FONT_FORMAT_LIST ) );
783         aNodeNameDelim += aDelim;
784         aNodeNameDelim += aFntFmtId;
785         aNodeNameDelim += aDelim;
786 
787         const OUString *pName = aNames.getConstArray();;
788 
789         // Name
790         pVal->Name  = aNodeNameDelim;
791         pVal->Name += *pName++;
792         pVal->Value <<= OUString( aFntFmt.aName );
793         pVal++;
794         // CharSet
795         pVal->Name  = aNodeNameDelim;
796         pVal->Name += *pName++;
797         pVal->Value <<= (sal_Int16) aFntFmt.nCharSet; // 6.0 file-format GetSOStoreTextEncoding not needed
798         pVal++;
799         // Family
800         pVal->Name  = aNodeNameDelim;
801         pVal->Name += *pName++;
802         pVal->Value <<= (sal_Int16) aFntFmt.nFamily;
803         pVal++;
804         // Pitch
805         pVal->Name  = aNodeNameDelim;
806         pVal->Name += *pName++;
807         pVal->Value <<= (sal_Int16) aFntFmt.nPitch;
808         pVal++;
809         // Weight
810         pVal->Name  = aNodeNameDelim;
811         pVal->Name += *pName++;
812         pVal->Value <<= (sal_Int16) aFntFmt.nWeight;
813         pVal++;
814         // Italic
815         pVal->Name  = aNodeNameDelim;
816         pVal->Name += *pName++;
817         pVal->Value <<= (sal_Int16) aFntFmt.nItalic;
818         pVal++;
819     }
820     DBG_ASSERT( static_cast<size_t>(pVal - pValues) == (nCount * nSymbolProps),
821             "properties missing" );
822     ReplaceSetProperties( A2OU( FONT_FORMAT_LIST ) , aValues );
823 
824     rFntFmtList.SetModified( sal_False );
825 }
826 
827 
828 void SmMathConfig::StripFontFormatList( const std::vector< SmSym > &rSymbols )
829 {
830     size_t i;
831 
832     // build list of used font-formats only
833     //!! font-format IDs may be different !!
834     SmFontFormatList aUsedList;
835     for (i = 0;  i < rSymbols.size();  ++i)
836     {
837         DBG_ASSERT( rSymbols[i].GetName().Len() > 0, "non named symbol" );
838         aUsedList.GetFontFormatId( SmFontFormat( rSymbols[i].GetFace() ) , sal_True );
839     }
840     const SmFormat & rStdFmt = GetStandardFormat();
841     for (i = FNT_BEGIN;  i <= FNT_END;  ++i)
842     {
843         aUsedList.GetFontFormatId( SmFontFormat( rStdFmt.GetFont( i ) ) , sal_True );
844     }
845 
846     // remove unused font-formats from list
847     SmFontFormatList &rFntFmtList = GetFontFormatList();
848     size_t nCnt = rFntFmtList.GetCount();
849     SmFontFormat *pTmpFormat = new SmFontFormat[ nCnt ];
850     String       *pId     = new String      [ nCnt ];
851     size_t k;
852     for (k = 0;  k < nCnt;  ++k)
853     {
854         pTmpFormat[k] = *rFntFmtList.GetFontFormat( k );
855         pId[k]     = rFntFmtList.GetFontFormatId( k );
856     }
857     for (k = 0;  k < nCnt;  ++k)
858     {
859         if (0 == aUsedList.GetFontFormatId( pTmpFormat[k] ).Len())
860         {
861             rFntFmtList.RemoveFontFormat( pId[k] );
862         }
863     }
864     delete [] pId;
865     delete [] pTmpFormat;
866 }
867 
868 
869 void SmMathConfig::LoadOther()
870 {
871     if (!pOther)
872         pOther = new SmCfgOther;
873 
874     Sequence< OUString > aNames( GetOtherPropertyNames() );
875     sal_Int32 nProps = aNames.getLength();
876 
877     Sequence< Any > aValues( GetProperties( aNames ) );
878     if (nProps  &&  aValues.getLength() == nProps)
879     {
880         const Any *pValues = aValues.getConstArray();
881         const Any *pVal = pValues;
882 
883         sal_Int16   nTmp16 = 0;
884         sal_Bool    bTmp = sal_False;
885 
886         // Print/Title
887         if (pVal->hasValue()  &&  (*pVal >>= bTmp))
888             pOther->bPrintTitle = bTmp;
889         ++pVal;
890         // Print/FormulaText
891         if (pVal->hasValue()  &&  (*pVal >>= bTmp))
892             pOther->bPrintFormulaText = bTmp;
893         ++pVal;
894         // Print/Frame
895         if (pVal->hasValue()  &&  (*pVal >>= bTmp))
896             pOther->bPrintFrame = bTmp;
897         ++pVal;
898         // Print/Size
899         if (pVal->hasValue()  &&  (*pVal >>= nTmp16))
900             pOther->ePrintSize = (SmPrintSize) nTmp16;
901         ++pVal;
902         // Print/ZoomFactor
903         if (pVal->hasValue()  &&  (*pVal >>= nTmp16))
904             pOther->nPrintZoomFactor = nTmp16;
905         ++pVal;
906         // LoadSave/IsSaveOnlyUsedSymbols
907         if (pVal->hasValue()  &&  (*pVal >>= bTmp))
908             pOther->bIsSaveOnlyUsedSymbols = bTmp;
909 /*        ++pVal;
910         // Misc/NoSymbolsWarning
911         if (pVal->hasValue()  &&  (*pVal >>= bTmp))
912             pOther->bNoSymbolsWarning = bTmp;
913 */
914         ++pVal;
915         // Misc/IgnoreSpacesRight
916         if (pVal->hasValue()  &&  (*pVal >>= bTmp))
917             pOther->bIgnoreSpacesRight = bTmp;
918         ++pVal;
919         // View/ToolboxVisible
920         if (pVal->hasValue()  &&  (*pVal >>= bTmp))
921             pOther->bToolboxVisible = bTmp;
922         ++pVal;
923         // View/AutoRedraw
924         if (pVal->hasValue()  &&  (*pVal >>= bTmp))
925             pOther->bAutoRedraw = bTmp;
926         ++pVal;
927         // View/FormulaCursor
928         if (pVal->hasValue()  &&  (*pVal >>= bTmp))
929             pOther->bFormulaCursor = bTmp;
930         ++pVal;
931 
932         DBG_ASSERT( pVal - pValues == nProps, "property mismatch" );
933         SetOtherModified( sal_False );
934     }
935 }
936 
937 
938 void SmMathConfig::SaveOther()
939 {
940     if (!pOther || !IsOtherModified())
941         return;
942 
943     const Sequence< OUString > aNames( GetOtherPropertyNames() );
944     sal_Int32 nProps = aNames.getLength();
945 
946     Sequence< Any > aValues( nProps );
947     Any *pValues = aValues.getArray();
948     Any *pValue  = pValues;
949 
950     // Print/Title
951     *pValue++ <<= (sal_Bool) pOther->bPrintTitle;
952     // Print/FormulaText
953     *pValue++ <<= (sal_Bool) pOther->bPrintFormulaText;
954     // Print/Frame
955     *pValue++ <<= (sal_Bool) pOther->bPrintFrame;
956     // Print/Size
957     *pValue++ <<= (sal_Int16) pOther->ePrintSize;
958     // Print/ZoomFactor
959     *pValue++ <<= (sal_Int16) pOther->nPrintZoomFactor;
960     // LoadSave/IsSaveOnlyUsedSymbols
961     *pValue++ <<= (sal_Bool) pOther->bIsSaveOnlyUsedSymbols;
962 /*    // Misc/NoSymbolsWarning
963     *pValue++ <<= (sal_Bool) pOther->bNoSymbolsWarning;
964 */
965     // Misc/IgnoreSpacesRight
966     *pValue++ <<= (sal_Bool) pOther->bIgnoreSpacesRight;
967     // View/ToolboxVisible
968     *pValue++ <<= (sal_Bool) pOther->bToolboxVisible;
969     // View/AutoRedraw
970     *pValue++ <<= (sal_Bool) pOther->bAutoRedraw;
971     // View/FormulaCursor
972     *pValue++ <<= (sal_Bool) pOther->bFormulaCursor;
973 
974     DBG_ASSERT( pValue - pValues == nProps, "property mismatch" );
975     PutProperties( aNames , aValues );
976 
977     SetOtherModified( sal_False );
978 }
979 
980 void SmMathConfig::LoadFormat()
981 {
982     if (!pFormat)
983         pFormat = new SmFormat;
984 
985 
986     Sequence< OUString > aNames( GetFormatPropertyNames() );
987     sal_Int32 nProps = aNames.getLength();
988 
989     Sequence< Any > aValues( GetProperties( aNames ) );
990     if (nProps  &&  aValues.getLength() == nProps)
991     {
992         const Any *pValues = aValues.getConstArray();
993         const Any *pVal = pValues;
994 
995         OUString    aTmpStr;
996         sal_Int16       nTmp16 = 0;
997         sal_Bool        bTmp = sal_False;
998 
999         // StandardFormat/Textmode
1000         if (pVal->hasValue()  &&  (*pVal >>= bTmp))
1001             pFormat->SetTextmode( bTmp );
1002         ++pVal;
1003         // StandardFormat/GreekCharStyle
1004         if (pVal->hasValue()  &&  (*pVal >>= nTmp16))
1005             pFormat->SetGreekCharStyle( nTmp16 );
1006         ++pVal;
1007         // StandardFormat/ScaleNormalBracket
1008         if (pVal->hasValue()  &&  (*pVal >>= bTmp))
1009             pFormat->SetScaleNormalBrackets( bTmp );
1010         ++pVal;
1011         // StandardFormat/HorizontalAlignment
1012         if (pVal->hasValue()  &&  (*pVal >>= nTmp16))
1013             pFormat->SetHorAlign( (SmHorAlign) nTmp16 );
1014         ++pVal;
1015         // StandardFormat/BaseSize
1016         if (pVal->hasValue()  &&  (*pVal >>= nTmp16))
1017             pFormat->SetBaseSize( Size(0, SmPtsTo100th_mm( nTmp16 )) );
1018         ++pVal;
1019 
1020         sal_uInt16 i;
1021         for (i = SIZ_BEGIN;  i <= SIZ_END;  ++i)
1022         {
1023             if (pVal->hasValue()  &&  (*pVal >>= nTmp16))
1024                 pFormat->SetRelSize( i, nTmp16 );
1025             ++pVal;
1026         }
1027 
1028         for (i = DIS_BEGIN;  i <= DIS_END;  ++i)
1029         {
1030             if (pVal->hasValue()  &&  (*pVal >>= nTmp16))
1031                 pFormat->SetDistance( i, nTmp16 );
1032             ++pVal;
1033         }
1034 
1035         LanguageType nLang = Application::GetSettings().GetUILanguage();
1036         for (i = FNT_BEGIN;  i < FNT_END;  ++i)
1037         {
1038             Font aFnt;
1039             sal_Bool bUseDefaultFont = sal_True;
1040             if (pVal->hasValue()  &&  (*pVal >>= aTmpStr))
1041             {
1042                 bUseDefaultFont = 0 == aTmpStr.getLength();
1043                 if (bUseDefaultFont)
1044                 {
1045                     aFnt = pFormat->GetFont( i );
1046                     aFnt.SetName( GetDefaultFontName( nLang, i ) );
1047                 }
1048                 else
1049                 {
1050                     const SmFontFormat *pFntFmt = GetFontFormatList().GetFontFormat( aTmpStr );
1051                     DBG_ASSERT( pFntFmt, "unknown FontFormat" );
1052                     if (pFntFmt)
1053                         aFnt = pFntFmt->GetFont();
1054                 }
1055             }
1056             ++pVal;
1057 
1058             aFnt.SetSize( pFormat->GetBaseSize() );
1059             pFormat->SetFont( i, aFnt, bUseDefaultFont );
1060         }
1061 
1062         DBG_ASSERT( pVal - pValues == nProps, "property mismatch" );
1063         SetFormatModified( sal_False );
1064     }
1065 }
1066 
1067 
1068 void SmMathConfig::SaveFormat()
1069 {
1070     if (!pFormat || !IsFormatModified())
1071         return;
1072 
1073     const Sequence< OUString > aNames( GetFormatPropertyNames() );
1074     sal_Int32 nProps = aNames.getLength();
1075 
1076     Sequence< Any > aValues( nProps );
1077     Any *pValues = aValues.getArray();
1078     Any *pValue  = pValues;
1079 
1080     // StandardFormat/Textmode
1081     *pValue++ <<= (sal_Bool) pFormat->IsTextmode();
1082     // StandardFormat/GreekCharStyle
1083     *pValue++ <<= (sal_Int16) pFormat->GetGreekCharStyle();
1084     // StandardFormat/ScaleNormalBracket
1085     *pValue++ <<= (sal_Bool) pFormat->IsScaleNormalBrackets();
1086     // StandardFormat/HorizontalAlignment
1087     *pValue++ <<= (sal_Int16) pFormat->GetHorAlign();
1088     // StandardFormat/BaseSize
1089     *pValue++ <<= (sal_Int16) SmRoundFraction( Sm100th_mmToPts(
1090                                     pFormat->GetBaseSize().Height() ) );
1091 
1092     sal_uInt16 i;
1093     for (i = SIZ_BEGIN;  i <= SIZ_END;  ++i)
1094         *pValue++ <<= (sal_Int16) pFormat->GetRelSize( i );
1095 
1096     for (i = DIS_BEGIN;  i <= DIS_END;  ++i)
1097         *pValue++ <<= (sal_Int16) pFormat->GetDistance( i );
1098 
1099     for (i = FNT_BEGIN;  i < FNT_END;  ++i)
1100     {
1101         OUString aFntFmtId;
1102 
1103         if (!pFormat->IsDefaultFont( i ))
1104         {
1105             SmFontFormat aFntFmt( pFormat->GetFont( i ) );
1106             aFntFmtId = GetFontFormatList().GetFontFormatId( aFntFmt, sal_True );
1107             DBG_ASSERT( aFntFmtId.getLength(), "FontFormatId not found" );
1108         }
1109 
1110         *pValue++ <<= aFntFmtId;
1111     }
1112 
1113     DBG_ASSERT( pValue - pValues == nProps, "property mismatch" );
1114     PutProperties( aNames , aValues );
1115 
1116     SetFormatModified( sal_False );
1117 }
1118 
1119 
1120 const SmFormat & SmMathConfig::GetStandardFormat() const
1121 {
1122     if (!pFormat)
1123         ((SmMathConfig *) this)->LoadFormat();
1124     return *pFormat;
1125 }
1126 
1127 
1128 void SmMathConfig::SetStandardFormat( const SmFormat &rFormat, sal_Bool bSaveFontFormatList )
1129 {
1130     if (!pFormat)
1131         LoadFormat();
1132     if (rFormat != *pFormat)
1133     {
1134         *pFormat = rFormat;
1135         SetFormatModified( sal_True );
1136 		SaveFormat();
1137 
1138         if (bSaveFontFormatList)
1139         {
1140             // needed for SmFontTypeDialog's DefaultButtonClickHdl
1141             SetFontFormatListModified( sal_True );
1142             SaveFontFormatList();
1143         }
1144     }
1145 }
1146 
1147 
1148 SmPrintSize SmMathConfig::GetPrintSize() const
1149 {
1150     if (!pOther)
1151         ((SmMathConfig *) this)->LoadOther();
1152     return pOther->ePrintSize;
1153 }
1154 
1155 
1156 void SmMathConfig::SetPrintSize( SmPrintSize eSize )
1157 {
1158     if (!pOther)
1159         LoadOther();
1160     if (eSize != pOther->ePrintSize)
1161     {
1162         pOther->ePrintSize = eSize;
1163         SetOtherModified( sal_True );
1164     }
1165 }
1166 
1167 
1168 sal_uInt16 SmMathConfig::GetPrintZoomFactor() const
1169 {
1170     if (!pOther)
1171         ((SmMathConfig *) this)->LoadOther();
1172     return pOther->nPrintZoomFactor;
1173 }
1174 
1175 
1176 void SmMathConfig::SetPrintZoomFactor( sal_uInt16 nVal )
1177 {
1178     if (!pOther)
1179         LoadOther();
1180     if (nVal != pOther->nPrintZoomFactor)
1181     {
1182         pOther->nPrintZoomFactor = nVal;
1183         SetOtherModified( sal_True );
1184     }
1185 }
1186 
1187 
1188 void SmMathConfig::SetOtherIfNotEqual( sal_Bool &rbItem, sal_Bool bNewVal )
1189 {
1190     if (bNewVal != rbItem)
1191     {
1192         rbItem = bNewVal;
1193         SetOtherModified( sal_True );
1194     }
1195 }
1196 
1197 
1198 sal_Bool SmMathConfig::IsPrintTitle() const
1199 {
1200     if (!pOther)
1201         ((SmMathConfig *) this)->LoadOther();
1202     return pOther->bPrintTitle;
1203 }
1204 
1205 
1206 void SmMathConfig::SetPrintTitle( sal_Bool bVal )
1207 {
1208     if (!pOther)
1209         LoadOther();
1210     SetOtherIfNotEqual( pOther->bPrintTitle, bVal );
1211 }
1212 
1213 
1214 sal_Bool SmMathConfig::IsPrintFormulaText() const
1215 {
1216     if (!pOther)
1217         ((SmMathConfig *) this)->LoadOther();
1218     return pOther->bPrintFormulaText;
1219 }
1220 
1221 
1222 void SmMathConfig::SetPrintFormulaText( sal_Bool bVal )
1223 {
1224     if (!pOther)
1225         LoadOther();
1226     SetOtherIfNotEqual( pOther->bPrintFormulaText, bVal );
1227 }
1228 
1229 
1230 sal_Bool SmMathConfig::IsPrintFrame() const
1231 {
1232     if (!pOther)
1233         ((SmMathConfig *) this)->LoadOther();
1234     return pOther->bPrintFrame;
1235 }
1236 
1237 
1238 void SmMathConfig::SetPrintFrame( sal_Bool bVal )
1239 {
1240     if (!pOther)
1241         LoadOther();
1242     SetOtherIfNotEqual( pOther->bPrintFrame, bVal );
1243 }
1244 
1245 
1246 sal_Bool SmMathConfig::IsSaveOnlyUsedSymbols() const
1247 {
1248     if (!pOther)
1249         ((SmMathConfig *) this)->LoadOther();
1250     return pOther->bIsSaveOnlyUsedSymbols;
1251 }
1252 
1253 
1254 void SmMathConfig::SetSaveOnlyUsedSymbols( sal_Bool bVal )
1255 {
1256     if (!pOther)
1257         LoadOther();
1258     SetOtherIfNotEqual( pOther->bIsSaveOnlyUsedSymbols, bVal );
1259 }
1260 
1261 
1262 sal_Bool SmMathConfig::IsIgnoreSpacesRight() const
1263 {
1264     if (!pOther)
1265         ((SmMathConfig *) this)->LoadOther();
1266     return pOther->bIgnoreSpacesRight;
1267 }
1268 
1269 
1270 void SmMathConfig::SetIgnoreSpacesRight( sal_Bool bVal )
1271 {
1272     if (!pOther)
1273         LoadOther();
1274     SetOtherIfNotEqual( pOther->bIgnoreSpacesRight, bVal );
1275 }
1276 
1277 
1278 sal_Bool SmMathConfig::IsAutoRedraw() const
1279 {
1280     if (!pOther)
1281         ((SmMathConfig *) this)->LoadOther();
1282     return pOther->bAutoRedraw;
1283 }
1284 
1285 
1286 void SmMathConfig::SetAutoRedraw( sal_Bool bVal )
1287 {
1288     if (!pOther)
1289         LoadOther();
1290     SetOtherIfNotEqual( pOther->bAutoRedraw, bVal );
1291 }
1292 
1293 
1294 sal_Bool SmMathConfig::IsShowFormulaCursor() const
1295 {
1296     if (!pOther)
1297         ((SmMathConfig *) this)->LoadOther();
1298     return pOther->bFormulaCursor;
1299 }
1300 
1301 
1302 void SmMathConfig::SetShowFormulaCursor( sal_Bool bVal )
1303 {
1304     if (!pOther)
1305         LoadOther();
1306     SetOtherIfNotEqual( pOther->bFormulaCursor, bVal );
1307 }
1308 
1309 void SmMathConfig::Notify( const com::sun::star::uno::Sequence< rtl::OUString >& )
1310 {}
1311 
1312 /////////////////////////////////////////////////////////////////
1313 
1314