update dev300-m58
[ooovba.git] / sc / source / core / tool / docoptio.cxx
blobb0188eec8d25e59fb58017ae2b02436cd7ec2de9
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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>
44 #include "cfgids.hxx"
45 #include "docoptio.hxx"
46 #include "rechead.hxx"
47 #include "scresid.hxx"
48 #include "sc.hrc"
49 #include "miscuno.hxx"
50 #include "global.hxx"
52 using namespace utl;
53 using namespace rtl;
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
78 else
79 return 720; // 1/2"
82 //========================================================================
83 // ScDocOptions - Dokument-Optionen
84 //========================================================================
86 ScDocOptions::ScDocOptions()
88 ResetDocOptions();
91 //------------------------------------------------------------------------
93 ScDocOptions::ScDocOptions( const ScDocOptions& rCpy )
94 : fIterEps( rCpy.fIterEps ),
95 nIterCount( rCpy.nIterCount ),
96 nPrecStandardFormat( rCpy.nPrecStandardFormat ),
97 nDay( rCpy.nDay ),
98 nMonth( rCpy.nMonth ),
99 nYear( rCpy.nYear ),
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;
127 bIsIter = FALSE;
128 nIterCount = 100;
129 fIterEps = 1.0E-3;
130 nPrecStandardFormat = 2;
131 nDay = 30;
132 nMonth = 12;
133 nYear = 1899;
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.
150 break;
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.
158 break;
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
175 // list separator.
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(";");
189 return;
191 while (false);
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 )
209 //UNUSED2008-05 {
210 //UNUSED2008-05 }
212 //------------------------------------------------------------------------
214 ScTpCalcItem::ScTpCalcItem( USHORT nWhichP, const ScDocOptions& rOpt )
215 : SfxPoolItem ( nWhichP ),
216 theOptions ( rOpt )
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]);
314 return aNames;
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]);
331 return aNames;
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" );
349 return aNames;
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())
379 switch(nProp)
381 case SCCALCOPT_ITER_ITER:
382 SetIter( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
383 break;
384 case SCCALCOPT_ITER_STEPS:
385 if (pValues[nProp] >>= nIntVal) SetIterCount( (USHORT) nIntVal );
386 break;
387 case SCCALCOPT_ITER_MINCHG:
388 if (pValues[nProp] >>= fDoubleVal) SetIterEps( fDoubleVal );
389 break;
390 case SCCALCOPT_DATE_DAY:
391 if (pValues[nProp] >>= nIntVal) nDateDay = (USHORT) nIntVal;
392 break;
393 case SCCALCOPT_DATE_MONTH:
394 if (pValues[nProp] >>= nIntVal) nDateMonth = (USHORT) nIntVal;
395 break;
396 case SCCALCOPT_DATE_YEAR:
397 if (pValues[nProp] >>= nIntVal) nDateYear = (USHORT) nIntVal;
398 break;
399 case SCCALCOPT_DECIMALS:
400 if (pValues[nProp] >>= nIntVal) SetStdPrecision( (USHORT) nIntVal );
401 break;
402 case SCCALCOPT_CASESENSITIVE:
403 // content is reversed
404 SetIgnoreCase( !ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
405 break;
406 case SCCALCOPT_PRECISION:
407 SetCalcAsShown( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
408 break;
409 case SCCALCOPT_SEARCHCRIT:
410 SetMatchWholeCell( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
411 break;
412 case SCCALCOPT_FINDLABEL:
413 SetLookUpColRowNames( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
414 break;
415 case SCCALCOPT_REGEX :
416 SetFormulaRegexEnabled( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
417 break;
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)
434 switch (nProp)
436 case SCFORMULAOPT_GRAMMAR:
438 ::formula::FormulaGrammar::Grammar eGram = ::formula::FormulaGrammar::GRAM_DEFAULT;
442 if (!(pValues[nProp] >>= nIntVal))
443 // extractino failed.
444 break;
446 switch (nIntVal)
448 case 0: // Calc A1
449 eGram = ::formula::FormulaGrammar::GRAM_NATIVE;
450 break;
451 case 1: // Excel A1
452 eGram = ::formula::FormulaGrammar::GRAM_NATIVE_XL_A1;
453 break;
454 case 2: // Excel R1C1
455 eGram = ::formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1;
456 break;
459 while (false);
460 SetFormulaSyntax(eGram);
462 break;
463 case SCFORMULAOPT_SEP_ARG:
465 OUString aSep;
466 if ((pValues[nProp] >>= aSep) && aSep.getLength())
467 SetFormulaSepArg(aSep);
469 break;
470 case SCFORMULAOPT_SEP_ARRAY_ROW:
472 OUString aSep;
473 if ((pValues[nProp] >>= aSep) && aSep.getLength())
474 SetFormulaSepArrayRow(aSep);
476 break;
477 case SCFORMULAOPT_SEP_ARRAY_COL:
479 OUString aSep;
480 if ((pValues[nProp] >>= aSep) && aSep.getLength())
481 SetFormulaSepArrayCol(aSep);
483 break;
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())
501 switch(nProp)
503 case SCDOCLAYOUTOPT_TABSTOP:
504 // TabDistance in ScDocOptions is in twips
505 if (pValues[nProp] >>= nIntVal)
506 SetTabDistance( (USHORT) HMMToTwips( nIntVal ) );
507 break;
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++)
526 switch(nProp)
528 case SCCALCOPT_ITER_ITER:
529 ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], IsIter() );
530 break;
531 case SCCALCOPT_ITER_STEPS:
532 pValues[nProp] <<= (sal_Int32) GetIterCount();
533 break;
534 case SCCALCOPT_ITER_MINCHG:
535 pValues[nProp] <<= (double) GetIterEps();
536 break;
537 case SCCALCOPT_DATE_DAY:
538 pValues[nProp] <<= (sal_Int32) nDateDay;
539 break;
540 case SCCALCOPT_DATE_MONTH:
541 pValues[nProp] <<= (sal_Int32) nDateMonth;
542 break;
543 case SCCALCOPT_DATE_YEAR:
544 pValues[nProp] <<= (sal_Int32) nDateYear;
545 break;
546 case SCCALCOPT_DECIMALS:
547 pValues[nProp] <<= (sal_Int32) GetStdPrecision();
548 break;
549 case SCCALCOPT_CASESENSITIVE:
550 // content is reversed
551 ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], !IsIgnoreCase() );
552 break;
553 case SCCALCOPT_PRECISION:
554 ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], IsCalcAsShown() );
555 break;
556 case SCCALCOPT_SEARCHCRIT:
557 ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], IsMatchWholeCell() );
558 break;
559 case SCCALCOPT_FINDLABEL:
560 ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], IsLookUpColRowNames() );
561 break;
562 case SCCALCOPT_REGEX :
563 ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], IsFormulaRegexEnabled() );
566 aCalcItem.PutProperties(aNames, aValues);
568 return 0;
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)
579 switch (nProp)
581 case SCFORMULAOPT_GRAMMAR :
583 sal_Int32 nVal = 0;
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;
591 break;
592 case SCFORMULAOPT_SEP_ARG:
593 pValues[nProp] <<= GetFormulaSepArg();
594 break;
595 case SCFORMULAOPT_SEP_ARRAY_ROW:
596 pValues[nProp] <<= GetFormulaSepArrayRow();
597 break;
598 case SCFORMULAOPT_SEP_ARRAY_COL:
599 pValues[nProp] <<= GetFormulaSepArrayCol();
600 break;
603 aFormulaItem.PutProperties(aNames, aValues);
605 return 0;
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++)
616 switch(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() );
623 break;
626 aLayoutItem.PutProperties(aNames, aValues);
628 return 0;
632 void ScDocCfg::SetOptions( const ScDocOptions& rNew )
634 *(ScDocOptions*)this = rNew;
636 aCalcItem.SetModified();
637 aFormulaItem.SetModified();
638 aLayoutItem.SetModified();