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