1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: docoptio.cxx,v $
10 * $Revision: 1.9.32.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 #include <vcl/svapp.hxx>
37 #include <svtools/zforlist.hxx>
39 #include <com/sun/star/uno/Any.hxx>
40 #include <com/sun/star/uno/Sequence.hxx>
41 #include <com/sun/star/lang/Locale.hpp>
42 #include <com/sun/star/i18n/LocaleDataItem.hpp>
45 #include "docoptio.hxx"
46 #include "rechead.hxx"
47 #include "scresid.hxx"
49 #include "miscuno.hxx"
54 using namespace com::sun::star::uno
;
55 using ::com::sun::star::lang::Locale
;
56 using ::com::sun::star::i18n::LocaleDataItem
;
58 //------------------------------------------------------------------------
60 #define SC_VERSION ((USHORT)251)
62 TYPEINIT1(ScTpCalcItem
, SfxPoolItem
);
64 //------------------------------------------------------------------------
66 //! these functions should be moved to some header file
67 inline long TwipsToHMM(long nTwips
) { return (nTwips
* 127 + 36) / 72; }
68 inline long HMMToTwips(long nHMM
) { return (nHMM
* 72 + 63) / 127; }
70 inline long TwipsToEvenHMM(long nTwips
) { return ( (nTwips
* 127 + 72) / 144 ) * 2; }
72 //------------------------------------------------------------------------
74 USHORT
lcl_GetDefaultTabDist()
76 if ( ScOptionsUtil::IsMetricSystem() )
77 return 709; // 1,25 cm
82 //========================================================================
83 // ScDocOptions - Dokument-Optionen
84 //========================================================================
86 ScDocOptions::ScDocOptions()
91 //------------------------------------------------------------------------
93 ScDocOptions::ScDocOptions( const ScDocOptions
& rCpy
)
94 : fIterEps( rCpy
.fIterEps
),
95 nIterCount( rCpy
.nIterCount
),
96 nPrecStandardFormat( rCpy
.nPrecStandardFormat
),
98 nMonth( rCpy
.nMonth
),
100 nYear2000( rCpy
.nYear2000
),
101 nTabDistance( rCpy
.nTabDistance
),
102 bIsIgnoreCase( rCpy
.bIsIgnoreCase
),
103 bIsIter( rCpy
.bIsIter
),
104 bCalcAsShown( rCpy
.bCalcAsShown
),
105 bMatchWholeCell( rCpy
.bMatchWholeCell
),
106 bDoAutoSpell( rCpy
.bDoAutoSpell
),
107 bLookUpColRowNames( rCpy
.bLookUpColRowNames
),
108 bFormulaRegexEnabled( rCpy
.bFormulaRegexEnabled
),
109 eFormulaGrammar( rCpy
.eFormulaGrammar
),
110 aFormulaSepArg( rCpy
.aFormulaSepArg
),
111 aFormulaSepArrayRow( rCpy
.aFormulaSepArrayRow
),
112 aFormulaSepArrayCol( rCpy
.aFormulaSepArrayCol
)
116 //------------------------------------------------------------------------
118 ScDocOptions::~ScDocOptions()
122 //------------------------------------------------------------------------
124 void ScDocOptions::ResetDocOptions()
126 bIsIgnoreCase
= FALSE
;
130 nPrecStandardFormat
= 2;
134 nYear2000
= SvNumberFormatter::GetYear2000Default();
135 nTabDistance
= lcl_GetDefaultTabDist();
136 bCalcAsShown
= FALSE
;
137 bMatchWholeCell
= TRUE
;
138 bDoAutoSpell
= FALSE
;
139 bLookUpColRowNames
= TRUE
;
140 bFormulaRegexEnabled
= TRUE
;
141 eFormulaGrammar
= ::formula::FormulaGrammar::GRAM_NATIVE
;
145 const Locale
& rLocale
= *ScGlobal::GetLocale();
146 const OUString
& rLang
= rLocale
.Language
;
147 if (rLang
.equalsAscii("ru"))
148 // Don't do automatic guess for these languages, and fall back to
149 // the old separator set.
152 const LocaleDataWrapper
& rLocaleData
= GetLocaleDataWrapper();
153 const OUString
& rDecSep
= rLocaleData
.getNumDecimalSep();
154 const OUString
& rListSep
= rLocaleData
.getListSep();
156 if (!rDecSep
.getLength() || !rListSep
.getLength())
157 // Something is wrong. Stick with the default separators.
160 sal_Unicode cDecSep
= rDecSep
.getStr()[0];
161 sal_Unicode cListSep
= rListSep
.getStr()[0];
163 // Excel by default uses system's list separator as the parameter
164 // separator, which in English locales is a comma. However, OOo's list
165 // separator value is set to ';' for all English locales. Because of this
166 // discrepancy, we will hardcode the separator value here, for now.
167 if (cDecSep
== sal_Unicode('.'))
168 cListSep
= sal_Unicode(',');
170 // Special case for de_CH locale.
171 if (rLocale
.Language
.equalsAsciiL("de", 2) && rLocale
.Country
.equalsAsciiL("CH", 2))
172 cListSep
= sal_Unicode(';');
174 // by default, the parameter separator equals the locale-specific
176 aFormulaSepArg
= OUString(cListSep
);
178 if (cDecSep
== cListSep
&& cDecSep
!= sal_Unicode(';'))
179 // if the decimal and list separators are equal, set the
180 // parameter separator to be ';', unless they are both
181 // semicolon in which case don't change the decimal separator.
182 aFormulaSepArg
= OUString::createFromAscii(";");
184 aFormulaSepArrayCol
= OUString::createFromAscii(",");
185 if (cDecSep
== sal_Unicode(','))
186 aFormulaSepArrayCol
= OUString::createFromAscii(".");
187 aFormulaSepArrayRow
= OUString::createFromAscii(";");
193 // Defaults to the old separator values.
194 aFormulaSepArg
= OUString::createFromAscii(";");
195 aFormulaSepArrayCol
= OUString::createFromAscii(";");
196 aFormulaSepArrayRow
= OUString::createFromAscii("|");
199 const LocaleDataWrapper
& ScDocOptions::GetLocaleDataWrapper() const
201 return *ScGlobal::pLocaleData
;
204 //========================================================================
205 // ScTpCalcItem - Daten fuer die CalcOptions-TabPage
206 //========================================================================
208 //UNUSED2008-05 ScTpCalcItem::ScTpCalcItem( USHORT nWhichP ) : SfxPoolItem( nWhichP )
212 //------------------------------------------------------------------------
214 ScTpCalcItem::ScTpCalcItem( USHORT nWhichP
, const ScDocOptions
& rOpt
)
215 : SfxPoolItem ( nWhichP
),
220 //------------------------------------------------------------------------
222 ScTpCalcItem::ScTpCalcItem( const ScTpCalcItem
& rItem
)
223 : SfxPoolItem ( rItem
),
224 theOptions ( rItem
.theOptions
)
228 //------------------------------------------------------------------------
230 __EXPORT
ScTpCalcItem::~ScTpCalcItem()
234 //------------------------------------------------------------------------
236 String __EXPORT
ScTpCalcItem::GetValueText() const
238 return String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("ScTpCalcItem") );
241 //------------------------------------------------------------------------
243 int __EXPORT
ScTpCalcItem::operator==( const SfxPoolItem
& rItem
) const
245 DBG_ASSERT( SfxPoolItem::operator==( rItem
), "unequal Which or Type" );
247 const ScTpCalcItem
& rPItem
= (const ScTpCalcItem
&)rItem
;
249 return ( theOptions
== rPItem
.theOptions
);
252 //------------------------------------------------------------------------
254 SfxPoolItem
* __EXPORT
ScTpCalcItem::Clone( SfxItemPool
* ) const
256 return new ScTpCalcItem( *this );
259 //==================================================================
260 // Config Item containing document options
261 //==================================================================
263 #define CFGPATH_CALC "Office.Calc/Calculate"
265 #define SCCALCOPT_ITER_ITER 0
266 #define SCCALCOPT_ITER_STEPS 1
267 #define SCCALCOPT_ITER_MINCHG 2
268 #define SCCALCOPT_DATE_DAY 3
269 #define SCCALCOPT_DATE_MONTH 4
270 #define SCCALCOPT_DATE_YEAR 5
271 #define SCCALCOPT_DECIMALS 6
272 #define SCCALCOPT_CASESENSITIVE 7
273 #define SCCALCOPT_PRECISION 8
274 #define SCCALCOPT_SEARCHCRIT 9
275 #define SCCALCOPT_FINDLABEL 10
276 #define SCCALCOPT_REGEX 11
277 #define SCCALCOPT_COUNT 12
279 #define CFGPATH_FORMULA "Office.Calc/Formula"
280 #define SCFORMULAOPT_GRAMMAR 0
281 #define SCFORMULAOPT_SEP_ARG 1
282 #define SCFORMULAOPT_SEP_ARRAY_ROW 2
283 #define SCFORMULAOPT_SEP_ARRAY_COL 3
284 #define SCFORMULAOPT_COUNT 4
286 #define CFGPATH_DOCLAYOUT "Office.Calc/Layout/Other"
288 #define SCDOCLAYOUTOPT_TABSTOP 0
289 #define SCDOCLAYOUTOPT_COUNT 1
292 Sequence
<OUString
> ScDocCfg::GetCalcPropertyNames()
294 static const char* aPropNames
[] =
296 "IterativeReference/Iteration", // SCCALCOPT_ITER_ITER
297 "IterativeReference/Steps", // SCCALCOPT_ITER_STEPS
298 "IterativeReference/MinimumChange", // SCCALCOPT_ITER_MINCHG
299 "Other/Date/DD", // SCCALCOPT_DATE_DAY
300 "Other/Date/MM", // SCCALCOPT_DATE_MONTH
301 "Other/Date/YY", // SCCALCOPT_DATE_YEAR
302 "Other/DecimalPlaces", // SCCALCOPT_DECIMALS
303 "Other/CaseSensitive", // SCCALCOPT_CASESENSITIVE
304 "Other/Precision", // SCCALCOPT_PRECISION
305 "Other/SearchCriteria", // SCCALCOPT_SEARCHCRIT
306 "Other/FindLabel", // SCCALCOPT_FINDLABEL
307 "Other/RegularExpressions", // SCCALCOPT_REGEX
309 Sequence
<OUString
> aNames(SCCALCOPT_COUNT
);
310 OUString
* pNames
= aNames
.getArray();
311 for(int i
= 0; i
< SCCALCOPT_COUNT
; i
++)
312 pNames
[i
] = OUString::createFromAscii(aPropNames
[i
]);
317 Sequence
<OUString
> ScDocCfg::GetFormulaPropertyNames()
319 static const char* aPropNames
[] =
321 "Syntax/Grammar", // SCFORMULAOPT_GRAMMAR
322 "Syntax/SeparatorArg", // SCFORMULAOPT_SEP_ARG
323 "Syntax/SeparatorArrayRow", // SCFORMULAOPT_SEP_ARRAY_ROW
324 "Syntax/SeparatorArrayCol", // SCFORMULAOPT_SEP_ARRAY_COL
326 Sequence
<OUString
> aNames(SCFORMULAOPT_COUNT
);
327 OUString
* pNames
= aNames
.getArray();
328 for (int i
= 0; i
< SCFORMULAOPT_COUNT
; ++i
)
329 pNames
[i
] = OUString::createFromAscii(aPropNames
[i
]);
334 Sequence
<OUString
> ScDocCfg::GetLayoutPropertyNames()
336 static const char* aPropNames
[] =
338 "TabStop/NonMetric" // SCDOCLAYOUTOPT_TABSTOP
340 Sequence
<OUString
> aNames(SCDOCLAYOUTOPT_COUNT
);
341 OUString
* pNames
= aNames
.getArray();
342 for(int i
= 0; i
< SCDOCLAYOUTOPT_COUNT
; i
++)
343 pNames
[i
] = OUString::createFromAscii(aPropNames
[i
]);
345 // adjust for metric system
346 if (ScOptionsUtil::IsMetricSystem())
347 pNames
[SCDOCLAYOUTOPT_TABSTOP
] = OUString::createFromAscii( "TabStop/Metric" );
352 ScDocCfg::ScDocCfg() :
353 aCalcItem( OUString::createFromAscii( CFGPATH_CALC
) ),
354 aFormulaItem(OUString::createFromAscii(CFGPATH_FORMULA
)),
355 aLayoutItem( OUString::createFromAscii( CFGPATH_DOCLAYOUT
) )
357 sal_Int32 nIntVal
= 0;
358 double fDoubleVal
= 0;
360 Sequence
<OUString
> aNames
;
361 Sequence
<Any
> aValues
;
362 const Any
* pValues
= NULL
;
364 USHORT nDateDay
, nDateMonth
, nDateYear
;
365 GetDate( nDateDay
, nDateMonth
, nDateYear
);
367 aNames
= GetCalcPropertyNames();
368 aValues
= aCalcItem
.GetProperties(aNames
);
369 aCalcItem
.EnableNotification(aNames
);
370 pValues
= aValues
.getConstArray();
371 DBG_ASSERT(aValues
.getLength() == aNames
.getLength(), "GetProperties failed");
372 if(aValues
.getLength() == aNames
.getLength())
374 for(int nProp
= 0; nProp
< aNames
.getLength(); nProp
++)
376 DBG_ASSERT(pValues
[nProp
].hasValue(), "property value missing");
377 if(pValues
[nProp
].hasValue())
381 case SCCALCOPT_ITER_ITER
:
382 SetIter( ScUnoHelpFunctions::GetBoolFromAny( pValues
[nProp
] ) );
384 case SCCALCOPT_ITER_STEPS
:
385 if (pValues
[nProp
] >>= nIntVal
) SetIterCount( (USHORT
) nIntVal
);
387 case SCCALCOPT_ITER_MINCHG
:
388 if (pValues
[nProp
] >>= fDoubleVal
) SetIterEps( fDoubleVal
);
390 case SCCALCOPT_DATE_DAY
:
391 if (pValues
[nProp
] >>= nIntVal
) nDateDay
= (USHORT
) nIntVal
;
393 case SCCALCOPT_DATE_MONTH
:
394 if (pValues
[nProp
] >>= nIntVal
) nDateMonth
= (USHORT
) nIntVal
;
396 case SCCALCOPT_DATE_YEAR
:
397 if (pValues
[nProp
] >>= nIntVal
) nDateYear
= (USHORT
) nIntVal
;
399 case SCCALCOPT_DECIMALS
:
400 if (pValues
[nProp
] >>= nIntVal
) SetStdPrecision( (USHORT
) nIntVal
);
402 case SCCALCOPT_CASESENSITIVE
:
403 // content is reversed
404 SetIgnoreCase( !ScUnoHelpFunctions::GetBoolFromAny( pValues
[nProp
] ) );
406 case SCCALCOPT_PRECISION
:
407 SetCalcAsShown( ScUnoHelpFunctions::GetBoolFromAny( pValues
[nProp
] ) );
409 case SCCALCOPT_SEARCHCRIT
:
410 SetMatchWholeCell( ScUnoHelpFunctions::GetBoolFromAny( pValues
[nProp
] ) );
412 case SCCALCOPT_FINDLABEL
:
413 SetLookUpColRowNames( ScUnoHelpFunctions::GetBoolFromAny( pValues
[nProp
] ) );
415 case SCCALCOPT_REGEX
:
416 SetFormulaRegexEnabled( ScUnoHelpFunctions::GetBoolFromAny( pValues
[nProp
] ) );
422 aCalcItem
.SetCommitLink( LINK( this, ScDocCfg
, CalcCommitHdl
) );
424 SetDate( nDateDay
, nDateMonth
, nDateYear
);
426 aNames
= GetFormulaPropertyNames();
427 aValues
= aFormulaItem
.GetProperties(aNames
);
428 aFormulaItem
.EnableNotification(aNames
);
429 pValues
= aValues
.getConstArray();
430 if (aValues
.getLength() == aNames
.getLength())
432 for (int nProp
= 0; nProp
< aNames
.getLength(); ++nProp
)
436 case SCFORMULAOPT_GRAMMAR
:
438 ::formula::FormulaGrammar::Grammar eGram
= ::formula::FormulaGrammar::GRAM_DEFAULT
;
442 if (!(pValues
[nProp
] >>= nIntVal
))
443 // extractino failed.
449 eGram
= ::formula::FormulaGrammar::GRAM_NATIVE
;
452 eGram
= ::formula::FormulaGrammar::GRAM_NATIVE_XL_A1
;
454 case 2: // Excel R1C1
455 eGram
= ::formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1
;
460 SetFormulaSyntax(eGram
);
463 case SCFORMULAOPT_SEP_ARG
:
466 if ((pValues
[nProp
] >>= aSep
) && aSep
.getLength())
467 SetFormulaSepArg(aSep
);
470 case SCFORMULAOPT_SEP_ARRAY_ROW
:
473 if ((pValues
[nProp
] >>= aSep
) && aSep
.getLength())
474 SetFormulaSepArrayRow(aSep
);
477 case SCFORMULAOPT_SEP_ARRAY_COL
:
480 if ((pValues
[nProp
] >>= aSep
) && aSep
.getLength())
481 SetFormulaSepArrayCol(aSep
);
487 aFormulaItem
.SetCommitLink( LINK(this, ScDocCfg
, FormulaCommitHdl
) );
489 aNames
= GetLayoutPropertyNames();
490 aValues
= aLayoutItem
.GetProperties(aNames
);
491 aLayoutItem
.EnableNotification(aNames
);
492 pValues
= aValues
.getConstArray();
493 DBG_ASSERT(aValues
.getLength() == aNames
.getLength(), "GetProperties failed");
494 if(aValues
.getLength() == aNames
.getLength())
496 for(int nProp
= 0; nProp
< aNames
.getLength(); nProp
++)
498 DBG_ASSERT(pValues
[nProp
].hasValue(), "property value missing");
499 if(pValues
[nProp
].hasValue())
503 case SCDOCLAYOUTOPT_TABSTOP
:
504 // TabDistance in ScDocOptions is in twips
505 if (pValues
[nProp
] >>= nIntVal
)
506 SetTabDistance( (USHORT
) HMMToTwips( nIntVal
) );
512 aLayoutItem
.SetCommitLink( LINK( this, ScDocCfg
, LayoutCommitHdl
) );
515 IMPL_LINK( ScDocCfg
, CalcCommitHdl
, void *, EMPTYARG
)
517 Sequence
<OUString
> aNames
= GetCalcPropertyNames();
518 Sequence
<Any
> aValues(aNames
.getLength());
519 Any
* pValues
= aValues
.getArray();
521 USHORT nDateDay
, nDateMonth
, nDateYear
;
522 GetDate( nDateDay
, nDateMonth
, nDateYear
);
524 for(int nProp
= 0; nProp
< aNames
.getLength(); nProp
++)
528 case SCCALCOPT_ITER_ITER
:
529 ScUnoHelpFunctions::SetBoolInAny( pValues
[nProp
], IsIter() );
531 case SCCALCOPT_ITER_STEPS
:
532 pValues
[nProp
] <<= (sal_Int32
) GetIterCount();
534 case SCCALCOPT_ITER_MINCHG
:
535 pValues
[nProp
] <<= (double) GetIterEps();
537 case SCCALCOPT_DATE_DAY
:
538 pValues
[nProp
] <<= (sal_Int32
) nDateDay
;
540 case SCCALCOPT_DATE_MONTH
:
541 pValues
[nProp
] <<= (sal_Int32
) nDateMonth
;
543 case SCCALCOPT_DATE_YEAR
:
544 pValues
[nProp
] <<= (sal_Int32
) nDateYear
;
546 case SCCALCOPT_DECIMALS
:
547 pValues
[nProp
] <<= (sal_Int32
) GetStdPrecision();
549 case SCCALCOPT_CASESENSITIVE
:
550 // content is reversed
551 ScUnoHelpFunctions::SetBoolInAny( pValues
[nProp
], !IsIgnoreCase() );
553 case SCCALCOPT_PRECISION
:
554 ScUnoHelpFunctions::SetBoolInAny( pValues
[nProp
], IsCalcAsShown() );
556 case SCCALCOPT_SEARCHCRIT
:
557 ScUnoHelpFunctions::SetBoolInAny( pValues
[nProp
], IsMatchWholeCell() );
559 case SCCALCOPT_FINDLABEL
:
560 ScUnoHelpFunctions::SetBoolInAny( pValues
[nProp
], IsLookUpColRowNames() );
562 case SCCALCOPT_REGEX
:
563 ScUnoHelpFunctions::SetBoolInAny( pValues
[nProp
], IsFormulaRegexEnabled() );
566 aCalcItem
.PutProperties(aNames
, aValues
);
571 IMPL_LINK( ScDocCfg
, FormulaCommitHdl
, void *, EMPTYARG
)
573 Sequence
<OUString
> aNames
= GetFormulaPropertyNames();
574 Sequence
<Any
> aValues(aNames
.getLength());
575 Any
* pValues
= aValues
.getArray();
577 for (int nProp
= 0; nProp
< aNames
.getLength(); ++nProp
)
581 case SCFORMULAOPT_GRAMMAR
:
584 switch (GetFormulaSyntax())
586 case ::formula::FormulaGrammar::GRAM_NATIVE_XL_A1
: nVal
= 1; break;
587 case ::formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1
: nVal
= 2; break;
589 pValues
[nProp
] <<= nVal
;
592 case SCFORMULAOPT_SEP_ARG
:
593 pValues
[nProp
] <<= GetFormulaSepArg();
595 case SCFORMULAOPT_SEP_ARRAY_ROW
:
596 pValues
[nProp
] <<= GetFormulaSepArrayRow();
598 case SCFORMULAOPT_SEP_ARRAY_COL
:
599 pValues
[nProp
] <<= GetFormulaSepArrayCol();
603 aFormulaItem
.PutProperties(aNames
, aValues
);
608 IMPL_LINK( ScDocCfg
, LayoutCommitHdl
, void *, EMPTYARG
)
610 Sequence
<OUString
> aNames
= GetLayoutPropertyNames();
611 Sequence
<Any
> aValues(aNames
.getLength());
612 Any
* pValues
= aValues
.getArray();
614 for(int nProp
= 0; nProp
< aNames
.getLength(); nProp
++)
618 case SCDOCLAYOUTOPT_TABSTOP
:
619 // TabDistance in ScDocOptions is in twips
620 // use only even numbers, so defaults don't get changed
621 // by modifying other settings in the same config item
622 pValues
[nProp
] <<= (sal_Int32
) TwipsToEvenHMM( GetTabDistance() );
626 aLayoutItem
.PutProperties(aNames
, aValues
);
632 void ScDocCfg::SetOptions( const ScDocOptions
& rNew
)
634 *(ScDocOptions
*)this = rNew
;
636 aCalcItem
.SetModified();
637 aFormulaItem
.SetModified();
638 aLayoutItem
.SetModified();