Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <hintids.hxx>
21 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
22 : #include <comphelper/processfactory.hxx>
23 : #include <editeng/unolingu.hxx>
24 : #include <unotools/localedatawrapper.hxx>
25 : #include <i18nlangtag/lang.h>
26 : #include <svl/zformat.hxx>
27 : #include <svl/eitem.hxx>
28 : #include <svx/svxids.hrc>
29 : #include <svx/numinf.hxx>
30 : #include <vcl/msgbox.hxx>
31 : #include <vcl/builderfactory.hxx>
32 : #include <svx/flagsdef.hxx>
33 : #include <svl/itemset.hxx>
34 : #include <docsh.hxx>
35 : #include <swtypes.hxx>
36 : #include <swmodule.hxx>
37 : #include <view.hxx>
38 : #include <wrtsh.hxx>
39 : #include <numfmtlb.hxx>
40 : #include <utlui.hrc>
41 : #include "swabstdlg.hxx"
42 : #include "dialog.hrc"
43 : #include <unomid.h>
44 : #include <sfx2/viewfrm.hxx>
45 : #include <boost/scoped_ptr.hpp>
46 :
47 : using namespace ::com::sun::star::uno;
48 : using namespace ::com::sun::star::lang;
49 :
50 : // STATIC DATA
51 :
52 : /**
53 : * Description:
54 : * nFormatType: Display the formats of this Type
55 : * nDefaultFormat: Select this format and possibly insert it
56 : */
57 :
58 0 : NumFormatListBox::NumFormatListBox(vcl::Window* pWin, WinBits nStyle) :
59 : ListBox ( pWin, nStyle ),
60 : nCurrFormatType (-1),
61 : nStdEntry (0),
62 : bOneArea (false),
63 : nDefFormat (0),
64 : pVw (0),
65 : pOwnFormatter (0),
66 : bShowLanguageControl(false),
67 0 : bUseAutomaticLanguage(true)
68 : {
69 0 : Init(css::util::NumberFormat::NUMBER, true);
70 0 : }
71 :
72 0 : VCL_BUILDER_DECL_FACTORY(NumFormatListBox)
73 : {
74 0 : WinBits nBits = WB_LEFT|WB_VCENTER|WB_3DLOOK;
75 :
76 0 : bool bDropdown = VclBuilder::extractDropdown(rMap);
77 :
78 0 : if (bDropdown)
79 0 : nBits |= WB_DROPDOWN;
80 : else
81 0 : nBits |= WB_BORDER;
82 :
83 0 : VclPtrInstance<NumFormatListBox> pListBox(pParent, nBits|WB_SIMPLEMODE);
84 :
85 0 : if (bDropdown)
86 0 : pListBox->EnableAutoSize(true);
87 :
88 0 : rRet = pListBox;
89 0 : }
90 :
91 0 : void NumFormatListBox::Init(short nFormatType, bool bUsrFormats)
92 : {
93 0 : SwView *pView = GetView();
94 :
95 0 : if (pView)
96 0 : eCurLanguage = pView->GetWrtShell().GetCurLang();
97 : else
98 0 : eCurLanguage = SvtSysLocale().GetLanguageTag().getLanguageType();
99 :
100 0 : if (!bUsrFormats)
101 : {
102 0 : pOwnFormatter = new SvNumberFormatter(comphelper::getProcessComponentContext(), eCurLanguage);
103 : }
104 :
105 0 : SetFormatType(nFormatType);
106 0 : SetDefFormat(nDefFormat);
107 :
108 0 : SetSelectHdl(LINK(this, NumFormatListBox, SelectHdl));
109 0 : }
110 :
111 0 : NumFormatListBox::~NumFormatListBox()
112 : {
113 0 : disposeOnce();
114 0 : }
115 :
116 0 : void NumFormatListBox::dispose()
117 : {
118 0 : delete pOwnFormatter;
119 0 : ListBox::dispose();
120 0 : }
121 :
122 0 : SwView* NumFormatListBox::GetView()
123 : {
124 0 : if( pVw )
125 0 : return pVw;
126 0 : return ::GetActiveView();
127 : }
128 :
129 0 : void NumFormatListBox::SetFormatType(const short nFormatType)
130 : {
131 0 : if (nCurrFormatType == -1 ||
132 0 : (nCurrFormatType & nFormatType) == 0) // there are mixed formats, like for example DateTime
133 : {
134 : SvNumberFormatter* pFormatter;
135 :
136 0 : if( pOwnFormatter )
137 0 : pFormatter = pOwnFormatter;
138 : else
139 : {
140 0 : SwView *pView = GetView();
141 : OSL_ENSURE(pView, "no view found");
142 0 : if(!pView)
143 0 : return;
144 0 : SwWrtShell &rSh = pView->GetWrtShell();
145 0 : pFormatter = rSh.GetNumberFormatter();
146 : }
147 :
148 0 : Clear(); // Remove all entries from the Listbox
149 :
150 0 : NfIndexTableOffset eOffsetStart = NF_NUMBER_START;
151 0 : NfIndexTableOffset eOffsetEnd = NF_NUMBER_START;
152 :
153 0 : switch( nFormatType )
154 : {
155 : case css::util::NumberFormat::NUMBER:
156 0 : eOffsetStart=NF_NUMBER_START;
157 0 : eOffsetEnd=NF_NUMBER_END;
158 0 : break;
159 :
160 : case css::util::NumberFormat::PERCENT:
161 0 : eOffsetStart=NF_PERCENT_START;
162 0 : eOffsetEnd=NF_PERCENT_END;
163 0 : break;
164 :
165 : case css::util::NumberFormat::CURRENCY:
166 0 : eOffsetStart=NF_CURRENCY_START;
167 0 : eOffsetEnd=NF_CURRENCY_END;
168 0 : break;
169 :
170 : case css::util::NumberFormat::DATETIME:
171 0 : eOffsetStart=NF_DATE_START;
172 0 : eOffsetEnd=NF_TIME_END;
173 0 : break;
174 :
175 : case css::util::NumberFormat::DATE:
176 0 : eOffsetStart=NF_DATE_START;
177 0 : eOffsetEnd=NF_DATE_END;
178 0 : break;
179 :
180 : case css::util::NumberFormat::TIME:
181 0 : eOffsetStart=NF_TIME_START;
182 0 : eOffsetEnd=NF_TIME_END;
183 0 : break;
184 :
185 : case css::util::NumberFormat::SCIENTIFIC:
186 0 : eOffsetStart=NF_SCIENTIFIC_START;
187 0 : eOffsetEnd=NF_SCIENTIFIC_END;
188 0 : break;
189 :
190 : case css::util::NumberFormat::FRACTION:
191 0 : eOffsetStart=NF_FRACTION_START;
192 0 : eOffsetEnd=NF_FRACTION_END;
193 0 : break;
194 :
195 : case css::util::NumberFormat::LOGICAL:
196 0 : eOffsetStart=NF_BOOLEAN;
197 0 : eOffsetEnd=NF_BOOLEAN;
198 0 : break;
199 :
200 : case css::util::NumberFormat::TEXT:
201 0 : eOffsetStart=NF_TEXT;
202 0 : eOffsetEnd=NF_TEXT;
203 0 : break;
204 :
205 : case css::util::NumberFormat::ALL:
206 0 : eOffsetStart=NF_NUMERIC_START;
207 0 : eOffsetEnd = NfIndexTableOffset( NF_INDEX_TABLE_ENTRIES - 1 );
208 0 : break;
209 :
210 : default:
211 : OSL_FAIL("what a format?");
212 0 : break;
213 : }
214 :
215 : const SvNumberformat* pFormat;
216 0 : sal_Int32 i = 0;
217 : sal_uLong nFormat;
218 : Color* pCol;
219 0 : double fVal = GetDefValue( nFormatType );
220 0 : OUString sValue;
221 :
222 : sal_uLong nSysNumFormat = pFormatter->GetFormatIndex(
223 0 : NF_NUMBER_SYSTEM, eCurLanguage );
224 : sal_uLong nSysShortDateFormat = pFormatter->GetFormatIndex(
225 0 : NF_DATE_SYSTEM_SHORT, eCurLanguage );
226 : sal_uLong nSysLongDateFormat = pFormatter->GetFormatIndex(
227 0 : NF_DATE_SYSTEM_LONG, eCurLanguage );
228 :
229 0 : for( long nIndex = eOffsetStart; nIndex <= eOffsetEnd; ++nIndex )
230 : {
231 : nFormat = pFormatter->GetFormatIndex(
232 0 : (NfIndexTableOffset)nIndex, eCurLanguage );
233 0 : pFormat = pFormatter->GetEntry( nFormat );
234 :
235 0 : if( nFormat == pFormatter->GetFormatIndex( NF_NUMBER_STANDARD,
236 0 : eCurLanguage )
237 0 : || const_cast<SvNumberformat*>(pFormat)->GetOutputString( fVal, sValue, &pCol )
238 0 : || nFormatType == css::util::NumberFormat::UNDEFINED )
239 : {
240 0 : sValue = pFormat->GetFormatstring();
241 : }
242 0 : else if( nFormatType == css::util::NumberFormat::TEXT )
243 : {
244 0 : pFormatter->GetOutputString( "\"ABC\"", nFormat, sValue, &pCol);
245 : }
246 :
247 0 : if (nFormat != nSysNumFormat &&
248 0 : nFormat != nSysShortDateFormat &&
249 : nFormat != nSysLongDateFormat)
250 : {
251 0 : const sal_Int32 nPos = InsertEntry( sValue );
252 0 : SetEntryData( nPos, reinterpret_cast<void*>(nFormat) );
253 :
254 0 : if( nFormat == pFormatter->GetStandardFormat(
255 0 : nFormatType, eCurLanguage ) )
256 0 : nStdEntry = i;
257 0 : ++i;
258 : }
259 : }
260 :
261 0 : if (!pOwnFormatter)
262 : {
263 0 : const sal_Int32 nPos = InsertEntry(SW_RESSTR( STR_DEFINE_NUMBERFORMAT ));
264 0 : SetEntryData( nPos, NULL );
265 : }
266 :
267 0 : SelectEntryPos( nStdEntry );
268 :
269 0 : nCurrFormatType = nFormatType;
270 : }
271 : }
272 :
273 0 : void NumFormatListBox::SetDefFormat(const sal_uLong nDefaultFormat)
274 : {
275 0 : if (nDefaultFormat == ULONG_MAX)
276 : {
277 0 : nDefFormat = nDefaultFormat;
278 0 : return;
279 : }
280 :
281 : SvNumberFormatter* pFormatter;
282 0 : if (pOwnFormatter)
283 0 : pFormatter = pOwnFormatter;
284 : else
285 : {
286 0 : SwView *pView = GetView();
287 : OSL_ENSURE(pView, "no view found");
288 0 : if(!pView)
289 0 : return;
290 0 : SwWrtShell &rSh = pView->GetWrtShell();
291 0 : pFormatter = rSh.GetNumberFormatter();
292 : }
293 :
294 0 : short nType = pFormatter->GetType(nDefaultFormat);
295 :
296 0 : SetFormatType(nType);
297 :
298 0 : sal_uLong nFormat = pFormatter->GetFormatForLanguageIfBuiltIn(nDefaultFormat, eCurLanguage);
299 :
300 0 : for (sal_Int32 i = 0; i < GetEntryCount(); i++)
301 : {
302 0 : if (nFormat == reinterpret_cast<sal_uLong>(GetEntryData(i)))
303 : {
304 0 : SelectEntryPos(i);
305 0 : nStdEntry = i;
306 0 : nDefFormat = GetFormat();
307 0 : return;
308 : }
309 : }
310 :
311 : // No entry found:
312 0 : double fValue = GetDefValue(nType);
313 0 : OUString sValue;
314 0 : Color* pCol = 0;
315 :
316 0 : if (nType == css::util::NumberFormat::TEXT)
317 : {
318 0 : pFormatter->GetOutputString("\"ABC\"", nDefaultFormat, sValue, &pCol);
319 : }
320 : else
321 : {
322 0 : pFormatter->GetOutputString(fValue, nDefaultFormat, sValue, &pCol);
323 : }
324 :
325 0 : sal_Int32 nPos = 0;
326 0 : while (reinterpret_cast<sal_uLong>(GetEntryData(nPos)) == ULONG_MAX)
327 0 : nPos++;
328 :
329 0 : sal_uLong nSysNumFormat = pFormatter->GetFormatIndex( NF_NUMBER_SYSTEM, eCurLanguage);
330 0 : sal_uLong nSysShortDateFormat = pFormatter->GetFormatIndex( NF_DATE_SYSTEM_SHORT, eCurLanguage);
331 0 : sal_uLong nSysLongDateFormat = pFormatter->GetFormatIndex( NF_DATE_SYSTEM_LONG, eCurLanguage);
332 0 : bool bSysLang = false;
333 0 : if( eCurLanguage == GetAppLanguage() )
334 0 : bSysLang = true;
335 0 : sal_uLong nNumFormatForLanguage = pFormatter->GetFormatForLanguageIfBuiltIn(nSysNumFormat, LANGUAGE_SYSTEM );
336 0 : sal_uLong nShortDateFormatForLanguage = pFormatter->GetFormatForLanguageIfBuiltIn(nSysShortDateFormat, LANGUAGE_SYSTEM );
337 0 : sal_uLong nLongDateFormatForLanguage = pFormatter->GetFormatForLanguageIfBuiltIn(nSysLongDateFormat, LANGUAGE_SYSTEM );
338 :
339 0 : if (
340 0 : nDefaultFormat == nSysNumFormat ||
341 0 : nDefaultFormat == nSysShortDateFormat ||
342 0 : nDefaultFormat == nSysLongDateFormat ||
343 : (
344 0 : bSysLang &&
345 : (
346 0 : nDefaultFormat == nNumFormatForLanguage ||
347 0 : nDefaultFormat == nShortDateFormatForLanguage ||
348 : nDefaultFormat == nLongDateFormatForLanguage
349 : )
350 : )
351 : )
352 : {
353 0 : sValue += SW_RES(RID_STR_SYSTEM);
354 : }
355 :
356 0 : nPos = InsertEntry(sValue, nPos); // Insert as first numeric entry
357 0 : SetEntryData(nPos, reinterpret_cast<void*>(nDefaultFormat));
358 0 : SelectEntryPos(nPos);
359 0 : nDefFormat = GetFormat();
360 : }
361 :
362 0 : sal_uLong NumFormatListBox::GetFormat() const
363 : {
364 0 : sal_Int32 nPos = GetSelectEntryPos();
365 :
366 0 : return reinterpret_cast<sal_uLong>(GetEntryData(nPos));
367 : }
368 :
369 0 : IMPL_LINK( NumFormatListBox, SelectHdl, ListBox *, pBox )
370 : {
371 0 : const sal_Int32 nPos = pBox->GetSelectEntryPos();
372 0 : OUString sDefine(SW_RES( STR_DEFINE_NUMBERFORMAT ));
373 0 : SwView *pView = GetView();
374 :
375 0 : if( pView && nPos == pBox->GetEntryCount() - 1 &&
376 0 : pBox->GetEntry( nPos ) == sDefine )
377 : {
378 0 : SwWrtShell &rSh = pView->GetWrtShell();
379 0 : SvNumberFormatter* pFormatter = rSh.GetNumberFormatter();
380 :
381 0 : SfxItemSet aCoreSet( rSh.GetAttrPool(),
382 : SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_VALUE,
383 : SID_ATTR_NUMBERFORMAT_INFO, SID_ATTR_NUMBERFORMAT_INFO,
384 : SID_ATTR_NUMBERFORMAT_ONE_AREA, SID_ATTR_NUMBERFORMAT_ONE_AREA,
385 : SID_ATTR_NUMBERFORMAT_NOLANGUAGE, SID_ATTR_NUMBERFORMAT_NOLANGUAGE,
386 : SID_ATTR_NUMBERFORMAT_ADD_AUTO, SID_ATTR_NUMBERFORMAT_ADD_AUTO,
387 0 : 0 );
388 :
389 0 : double fValue = GetDefValue( nCurrFormatType);
390 :
391 0 : sal_uLong nFormat = pFormatter->GetStandardFormat( nCurrFormatType, eCurLanguage);
392 0 : aCoreSet.Put( SfxUInt32Item( SID_ATTR_NUMBERFORMAT_VALUE, nFormat ));
393 :
394 : aCoreSet.Put( SvxNumberInfoItem( pFormatter, fValue,
395 0 : SID_ATTR_NUMBERFORMAT_INFO ) );
396 :
397 0 : if( (css::util::NumberFormat::DATE | css::util::NumberFormat::TIME) & nCurrFormatType )
398 0 : aCoreSet.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ONE_AREA, bOneArea));
399 :
400 0 : aCoreSet.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_NOLANGUAGE, !bShowLanguageControl));
401 0 : aCoreSet.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ADD_AUTO, bUseAutomaticLanguage));
402 :
403 0 : SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
404 : OSL_ENSURE(pFact, "SwAbstractDialogFactory fail!");
405 :
406 : boost::scoped_ptr<SfxAbstractDialog> pDlg(pFact->CreateSfxDialog( this, aCoreSet,
407 0 : GetView()->GetViewFrame()->GetFrame().GetFrameInterface(),
408 0 : RC_DLG_SWNUMFMTDLG ));
409 : OSL_ENSURE(pDlg, "Dialog creation failed!");
410 :
411 0 : if (RET_OK == pDlg->Execute())
412 : {
413 0 : const SfxPoolItem* pItem = pView->GetDocShell()->
414 0 : GetItem( SID_ATTR_NUMBERFORMAT_INFO );
415 :
416 0 : if( pItem && 0 != static_cast<const SvxNumberInfoItem*>(pItem)->GetDelCount() )
417 : {
418 0 : const sal_uInt32* pDelArr = static_cast<const SvxNumberInfoItem*>(pItem)->GetDelArray();
419 :
420 0 : for ( sal_uInt32 i = 0; i < static_cast<const SvxNumberInfoItem*>(pItem)->GetDelCount(); i++ )
421 0 : pFormatter->DeleteEntry( pDelArr[i] );
422 : }
423 :
424 0 : const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
425 0 : if( SfxItemState::SET == pOutSet->GetItemState(
426 0 : SID_ATTR_NUMBERFORMAT_VALUE, false, &pItem ))
427 : {
428 0 : sal_uInt32 nNumberFormat = static_cast<const SfxUInt32Item*>(pItem)->GetValue();
429 : // oj #105473# change order of calls
430 0 : const SvNumberformat* pFormat = pFormatter->GetEntry(nNumberFormat);
431 0 : if( pFormat )
432 0 : eCurLanguage = pFormat->GetLanguage();
433 : // SetDefFormat uses eCurLanguage to look for if this format already in the list
434 0 : SetDefFormat(nNumberFormat);
435 : }
436 0 : if( bShowLanguageControl && SfxItemState::SET == pOutSet->GetItemState(
437 0 : SID_ATTR_NUMBERFORMAT_ADD_AUTO, false, &pItem ))
438 : {
439 0 : bUseAutomaticLanguage = static_cast<const SfxBoolItem*>(pItem)->GetValue();
440 : }
441 : }
442 : else
443 0 : SetDefFormat(nFormat);
444 : }
445 0 : return 0;
446 : }
447 :
448 0 : double NumFormatListBox::GetDefValue(const short nFormatType) const
449 : {
450 0 : double fDefValue = 0.0;
451 :
452 0 : switch (nFormatType)
453 : {
454 : case css::util::NumberFormat::DATE:
455 : case css::util::NumberFormat::DATE|css::util::NumberFormat::TIME:
456 0 : fDefValue = SVX_NUMVAL_DATE;
457 0 : break;
458 :
459 : case css::util::NumberFormat::TIME:
460 0 : fDefValue = SVX_NUMVAL_TIME;
461 0 : break;
462 :
463 : case css::util::NumberFormat::TEXT:
464 : case css::util::NumberFormat::UNDEFINED:
465 0 : fDefValue = 0;
466 0 : break;
467 :
468 : case css::util::NumberFormat::CURRENCY:
469 0 : fDefValue = SVX_NUMVAL_CURRENCY;
470 0 : break;
471 :
472 : case css::util::NumberFormat::PERCENT:
473 0 : fDefValue = SVX_NUMVAL_PERCENT;
474 0 : break;
475 :
476 : case css::util::NumberFormat::LOGICAL:
477 0 : fDefValue = SVX_NUMVAL_BOOLEAN;
478 0 : break;
479 :
480 : default:
481 0 : fDefValue = SVX_NUMVAL_STANDARD;
482 0 : break;
483 : }
484 :
485 0 : return fDefValue;
486 : }
487 :
488 0 : void NumFormatListBox::Clear()
489 : {
490 0 : ListBox::Clear();
491 0 : nCurrFormatType = -1;
492 177 : }
493 :
494 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|