xref: /trunk/main/sw/source/ui/utlui/numfmtlb.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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_sw.hxx"
30 
31 
32 #include <hintids.hxx>
33 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
34 #include <comphelper/processfactory.hxx>
35 #include <editeng/unolingu.hxx>
36 #include <unotools/localedatawrapper.hxx>
37 #include <i18npool/lang.h>
38 #ifndef _ZFORMAT_HXX //autogen
39 #define _ZFORLIST_DECLARE_TABLE
40 #include <svl/zformat.hxx>
41 #endif
42 #include <svl/eitem.hxx>
43 #include <svx/svxids.hrc>
44 #include <svx/numinf.hxx>
45 #include <vcl/msgbox.hxx>
46 #include <svx/flagsdef.hxx>
47 #include <svl/itemset.hxx>
48 #include <docsh.hxx>
49 #include <swtypes.hxx>
50 #include <swmodule.hxx>
51 #include <view.hxx>
52 #include <wrtsh.hxx>
53 #include <numfmtlb.hxx>
54 #include <utlui.hrc>
55 #include "swabstdlg.hxx"
56 #include "dialog.hrc"
57 #include <unomid.h>
58 #include <sfx2/viewfrm.hxx>
59 
60 using namespace ::com::sun::star::uno;
61 using namespace ::com::sun::star::lang;
62 
63 
64 // STATIC DATA -----------------------------------------------------------
65 
66 /*--------------------------------------------------------------------
67     Beschreibung:
68                     nFormatType: Formate dieses Typs anzeigen
69                     nDefFmt:     Dieses Format selektieren und ggf vorher
70                                  einfuegen
71  --------------------------------------------------------------------*/
72 
73 NumFormatListBox::NumFormatListBox( Window* pWin, const ResId& rResId,
74                                     short nFormatType, sal_uLong nDefFmt,
75                                     sal_Bool bUsrFmts ) :
76     ListBox             ( pWin, rResId ),
77     nCurrFormatType     (-1),
78     nStdEntry           (0),
79     bOneArea            (sal_False),
80     nDefFormat          (nDefFmt),
81     pVw                 (0),
82     pOwnFormatter       (0),
83     bShowLanguageControl(sal_False),
84     bUseAutomaticLanguage(sal_True)
85 {
86     Init(nFormatType, bUsrFmts);
87 }
88 
89 /*--------------------------------------------------------------------
90     Beschreibung:
91  --------------------------------------------------------------------*/
92 
93 NumFormatListBox::NumFormatListBox( Window* pWin, SwView* pView,
94                                     const ResId& rResId, short nFormatType,
95                                     sal_uLong nDefFmt, sal_Bool bUsrFmts ) :
96     ListBox             ( pWin, rResId ),
97     nCurrFormatType     (-1),
98     nStdEntry           (0),
99     bOneArea            (sal_False),
100     nDefFormat          (nDefFmt),
101     pVw                 (pView),
102     pOwnFormatter       (0),
103     bShowLanguageControl(sal_False),
104     bUseAutomaticLanguage(sal_True)
105 {
106     Init(nFormatType, bUsrFmts);
107 }
108 
109 /* -----------------15.06.98 11:29-------------------
110  *
111  * --------------------------------------------------*/
112 
113 void NumFormatListBox::Init(short nFormatType, sal_Bool bUsrFmts)
114 {
115     SwView *pView = GetView();
116 
117     if (pView)
118         eCurLanguage = pView->GetWrtShell().GetCurLang();
119     else
120         eCurLanguage = SvxLocaleToLanguage( SvtSysLocale().GetLocaleData().getLocale() );
121 
122     if (bUsrFmts == sal_False)
123     {
124         Reference< XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
125         pOwnFormatter = new SvNumberFormatter(xMSF, eCurLanguage);
126     }
127 
128     SetFormatType(nFormatType);
129     SetDefFormat(nDefFormat);
130 
131     SetSelectHdl(LINK(this, NumFormatListBox, SelectHdl));
132 }
133 
134 /*--------------------------------------------------------------------
135     Beschreibung:
136  --------------------------------------------------------------------*/
137 
138 NumFormatListBox::~NumFormatListBox()
139 {
140     if (pOwnFormatter)
141         delete pOwnFormatter;
142 }
143 /*--------------------------------------------------------------------
144     Beschreibung:
145  --------------------------------------------------------------------*/
146 
147 SwView* NumFormatListBox::GetView()
148 {
149     if( pVw )
150         return pVw;
151     return ::GetActiveView();
152 }
153 
154 /*--------------------------------------------------------------------
155     Beschreibung:
156  --------------------------------------------------------------------*/
157 
158 void NumFormatListBox::SetFormatType(const short nFormatType)
159 {
160     if (nCurrFormatType == -1 ||
161         (nCurrFormatType & nFormatType) == 0)   // Es gibt Mischformate, wie z.B. DateTime
162     {
163         SvNumberFormatter* pFormatter;
164 
165         if( pOwnFormatter )
166             pFormatter = pOwnFormatter;
167         else
168         {
169             SwView *pView = GetView();
170             DBG_ASSERT(pView, "no view found");
171             if(!pView)
172                 return;
173             SwWrtShell &rSh = pView->GetWrtShell();
174             pFormatter = rSh.GetNumberFormatter();
175         }
176 
177         Clear();    // Alle Eintraege in der Listbox entfernen
178 
179         NfIndexTableOffset eOffsetStart = NF_NUMBER_START;
180         NfIndexTableOffset eOffsetEnd = NF_NUMBER_START;
181 
182         switch( nFormatType )
183         {
184         case NUMBERFORMAT_NUMBER:
185             eOffsetStart=NF_NUMBER_START;
186             eOffsetEnd=NF_NUMBER_END;
187             break;
188 
189         case NUMBERFORMAT_PERCENT:
190             eOffsetStart=NF_PERCENT_START;
191             eOffsetEnd=NF_PERCENT_END;
192             break;
193 
194         case NUMBERFORMAT_CURRENCY:
195             eOffsetStart=NF_CURRENCY_START;
196             eOffsetEnd=NF_CURRENCY_END;
197             break;
198 
199         case NUMBERFORMAT_DATETIME:
200             eOffsetStart=NF_DATE_START;
201             eOffsetEnd=NF_TIME_END;
202             break;
203 
204         case NUMBERFORMAT_DATE:
205             eOffsetStart=NF_DATE_START;
206             eOffsetEnd=NF_DATE_END;
207             break;
208 
209         case NUMBERFORMAT_TIME:
210             eOffsetStart=NF_TIME_START;
211             eOffsetEnd=NF_TIME_END;
212             break;
213 
214         case NUMBERFORMAT_SCIENTIFIC:
215             eOffsetStart=NF_SCIENTIFIC_START;
216             eOffsetEnd=NF_SCIENTIFIC_END;
217             break;
218 
219         case NUMBERFORMAT_FRACTION:
220             eOffsetStart=NF_FRACTION_START;
221             eOffsetEnd=NF_FRACTION_END;
222             break;
223 
224         case NUMBERFORMAT_LOGICAL:
225             eOffsetStart=NF_BOOLEAN;
226             eOffsetEnd=NF_BOOLEAN;
227             break;
228 
229         case NUMBERFORMAT_TEXT:
230             eOffsetStart=NF_TEXT;
231             eOffsetEnd=NF_TEXT;
232             break;
233 
234         case NUMBERFORMAT_ALL:
235             eOffsetStart=NF_NUMERIC_START;
236             eOffsetEnd = NfIndexTableOffset( NF_INDEX_TABLE_ENTRIES - 1 );
237             break;
238 
239         default:
240             DBG_ERROR("what a format?");
241             break;
242         }
243 
244         const SvNumberformat* pFmt;
245         sal_uInt16 nPos, i = 0;
246         sal_uLong  nFormat;
247         Color* pCol;
248         double fVal = GetDefValue( nFormatType );
249         String sValue;
250 
251         sal_uLong nSysNumFmt = pFormatter->GetFormatIndex(
252                                         NF_NUMBER_SYSTEM, eCurLanguage );
253         sal_uLong nSysShortDateFmt = pFormatter->GetFormatIndex(
254                                         NF_DATE_SYSTEM_SHORT, eCurLanguage );
255         sal_uLong nSysLongDateFmt = pFormatter->GetFormatIndex(
256                                         NF_DATE_SYSTEM_LONG, eCurLanguage );
257 
258         for( long nIndex = eOffsetStart; nIndex <= eOffsetEnd; ++nIndex )
259         {
260             nFormat = pFormatter->GetFormatIndex(
261                             (NfIndexTableOffset)nIndex, eCurLanguage );
262             pFmt = pFormatter->GetEntry( nFormat );
263 
264             if( nFormat == pFormatter->GetFormatIndex( NF_NUMBER_STANDARD,
265                                                         eCurLanguage )
266                 || ((SvNumberformat*)pFmt)->GetOutputString( fVal, sValue, &pCol )
267                 || nFormatType == NUMBERFORMAT_UNDEFINED )
268                     sValue = pFmt->GetFormatstring();
269             else if( nFormatType == NUMBERFORMAT_TEXT )
270             {
271                 String sTxt(C2S("\"ABC\""));
272                 pFormatter->GetOutputString( sTxt, nFormat, sValue, &pCol);
273             }
274 
275             if (nFormat != nSysNumFmt       &&
276                 nFormat != nSysShortDateFmt &&
277                 nFormat != nSysLongDateFmt)
278             {
279                 nPos = InsertEntry( sValue );
280                 SetEntryData( nPos, (void*)nFormat );
281 
282                 if( nFormat == pFormatter->GetStandardFormat(
283                                         nFormatType, eCurLanguage ) )
284                     nStdEntry = i;
285                 ++i;
286             }
287         }
288 
289         if (!pOwnFormatter)
290         {
291             nPos = InsertEntry(SW_RESSTR( STR_DEFINE_NUMBERFORMAT ));
292             SetEntryData( nPos, NULL );
293         }
294 
295         SelectEntryPos( nStdEntry );
296 
297         nCurrFormatType = nFormatType;
298     }
299 }
300 
301 /*--------------------------------------------------------------------
302     Beschreibung:
303  --------------------------------------------------------------------*/
304 
305 void NumFormatListBox::SetDefFormat(const sal_uLong nDefFmt)
306 {
307     if (nDefFmt == ULONG_MAX)
308     {
309         nDefFormat = nDefFmt;
310         return;
311     }
312 
313     SvNumberFormatter* pFormatter;
314     if (pOwnFormatter)
315         pFormatter = pOwnFormatter;
316     else
317     {
318         SwView *pView = GetView();
319         DBG_ASSERT(pView, "no view found");
320         if(!pView)
321             return;
322         SwWrtShell &rSh = pView->GetWrtShell();
323         pFormatter = rSh.GetNumberFormatter();
324     }
325 
326     short nType = pFormatter->GetType(nDefFmt);
327 
328     SetFormatType(nType);
329 
330     sal_uLong nFormat = pFormatter->GetFormatForLanguageIfBuiltIn(nDefFmt, eCurLanguage);
331 
332     for (sal_uInt16 i = 0; i < GetEntryCount(); i++)
333     {
334         if (nFormat == (sal_uLong)GetEntryData(i))
335         {
336             SelectEntryPos(i);
337             nStdEntry = i;
338             nDefFormat = GetFormat();
339             return;
340         }
341     }
342 
343     // Kein Eintrag gefunden:
344     double fValue = GetDefValue(nType);
345     String sValue;
346     Color* pCol = 0;
347 
348     if (nType == NUMBERFORMAT_TEXT)
349     {
350         String sTxt(C2S("\"ABC\""));
351         pFormatter->GetOutputString(sTxt, nDefFmt, sValue, &pCol);
352     }
353     else
354         pFormatter->GetOutputString(fValue, nDefFmt, sValue, &pCol);
355 
356     sal_uInt16 nPos = 0;
357     while ((sal_uLong)GetEntryData(nPos) == ULONG_MAX)
358         nPos++;
359 
360 //
361     sal_uLong nSysNumFmt = pFormatter->GetFormatIndex( NF_NUMBER_SYSTEM, eCurLanguage);
362     sal_uLong nSysShortDateFmt = pFormatter->GetFormatIndex( NF_DATE_SYSTEM_SHORT, eCurLanguage);
363     sal_uLong nSysLongDateFmt = pFormatter->GetFormatIndex( NF_DATE_SYSTEM_LONG, eCurLanguage);
364     sal_Bool bSysLang = sal_False;
365     if( eCurLanguage == GetAppLanguage() )
366         bSysLang = sal_True;
367     sal_uLong nNumFormatForLanguage = pFormatter->GetFormatForLanguageIfBuiltIn(nSysNumFmt, LANGUAGE_SYSTEM );
368     sal_uLong nShortDateFormatForLanguage = pFormatter->GetFormatForLanguageIfBuiltIn(nSysShortDateFmt, LANGUAGE_SYSTEM );
369     sal_uLong nLongDateFormatForLanguage = pFormatter->GetFormatForLanguageIfBuiltIn(nSysLongDateFmt, LANGUAGE_SYSTEM );
370 
371     if (
372          nDefFmt == nSysNumFmt ||
373          nDefFmt == nSysShortDateFmt ||
374          nDefFmt == nSysLongDateFmt ||
375          (
376            bSysLang &&
377            (
378              nDefFmt == nNumFormatForLanguage ||
379              nDefFmt == nShortDateFormatForLanguage ||
380              nDefFmt == nLongDateFormatForLanguage
381            )
382          )
383        )
384     {
385         sValue += String(SW_RES(RID_STR_SYSTEM));
386     }
387 
388     nPos = InsertEntry(sValue, nPos);   // Als ersten numerischen Eintrag einfuegen
389     SetEntryData(nPos, (void*)nDefFmt);
390     SelectEntryPos(nPos);
391     nDefFormat = GetFormat();
392 }
393 
394 /*--------------------------------------------------------------------
395     Beschreibung:
396  --------------------------------------------------------------------*/
397 
398 sal_uLong NumFormatListBox::GetFormat() const
399 {
400     sal_uInt16 nPos = GetSelectEntryPos();
401 
402     return (sal_uLong)GetEntryData(nPos);
403 }
404 
405 /*--------------------------------------------------------------------
406     Beschreibung:
407  --------------------------------------------------------------------*/
408 
409 IMPL_LINK( NumFormatListBox, SelectHdl, ListBox *, pBox )
410 {
411     sal_uInt16 nPos = pBox->GetSelectEntryPos();
412     String sDefine(SW_RES( STR_DEFINE_NUMBERFORMAT ));
413     SwView *pView = GetView();
414 
415     if( pView && nPos == pBox->GetEntryCount() - 1 &&
416         pBox->GetEntry( nPos ) == sDefine )
417     {
418         SwWrtShell &rSh = pView->GetWrtShell();
419         SvNumberFormatter* pFormatter = rSh.GetNumberFormatter();
420 
421         SfxItemSet aCoreSet( rSh.GetAttrPool(),
422             SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_VALUE,
423             SID_ATTR_NUMBERFORMAT_INFO, SID_ATTR_NUMBERFORMAT_INFO,
424             SID_ATTR_NUMBERFORMAT_ONE_AREA, SID_ATTR_NUMBERFORMAT_ONE_AREA,
425             SID_ATTR_NUMBERFORMAT_NOLANGUAGE, SID_ATTR_NUMBERFORMAT_NOLANGUAGE,
426             SID_ATTR_NUMBERFORMAT_ADD_AUTO, SID_ATTR_NUMBERFORMAT_ADD_AUTO,
427             0 );
428 
429         double fValue = GetDefValue( nCurrFormatType);
430 
431         sal_uLong nFormat = pFormatter->GetStandardFormat( nCurrFormatType, eCurLanguage);
432         aCoreSet.Put( SfxUInt32Item( SID_ATTR_NUMBERFORMAT_VALUE, nFormat ));
433 
434         aCoreSet.Put( SvxNumberInfoItem( pFormatter, fValue,
435                                             SID_ATTR_NUMBERFORMAT_INFO ) );
436 
437         if( (NUMBERFORMAT_DATE | NUMBERFORMAT_TIME) & nCurrFormatType )
438             aCoreSet.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ONE_AREA, bOneArea));
439 
440         aCoreSet.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_NOLANGUAGE, !bShowLanguageControl));
441         aCoreSet.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ADD_AUTO, bUseAutomaticLanguage));
442 
443         SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
444         DBG_ASSERT(pFact, "SwAbstractDialogFactory fail!");
445 
446         SfxAbstractDialog* pDlg = pFact->CreateSfxDialog( this, aCoreSet,
447             GetView()->GetViewFrame()->GetFrame().GetFrameInterface(),
448             RC_DLG_SWNUMFMTDLG );
449         DBG_ASSERT(pDlg, "Dialogdiet fail!");
450 
451         if (RET_OK == pDlg->Execute())
452         {
453             const SfxPoolItem* pItem = pView->GetDocShell()->
454                             GetItem( SID_ATTR_NUMBERFORMAT_INFO );
455 
456             if( pItem && 0 != ((SvxNumberInfoItem*)pItem)->GetDelCount() )
457             {
458                 const sal_uInt32* pDelArr = ((SvxNumberInfoItem*)pItem)->GetDelArray();
459 
460                 for ( sal_uInt16 i = 0; i < ((SvxNumberInfoItem*)pItem)->GetDelCount(); i++ )
461                     pFormatter->DeleteEntry( pDelArr[i] );
462             }
463 
464             const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
465             if( SFX_ITEM_SET == pOutSet->GetItemState(
466                 SID_ATTR_NUMBERFORMAT_VALUE, sal_False, &pItem ))
467             {
468                 sal_uInt32 nNumberFormat = ((SfxUInt32Item*)pItem)->GetValue();
469                 // oj #105473# change order of calls
470                 const SvNumberformat* pFmt = pFormatter->GetEntry(nNumberFormat);
471                 if( pFmt )
472                     eCurLanguage = pFmt->GetLanguage();
473                 // SetDefFormat uses eCurLanguage to look for if this format already in the list
474                 SetDefFormat(nNumberFormat);
475             }
476             if( bShowLanguageControl && SFX_ITEM_SET == pOutSet->GetItemState(
477                 SID_ATTR_NUMBERFORMAT_ADD_AUTO, sal_False, &pItem ))
478             {
479                 bUseAutomaticLanguage = ((const SfxBoolItem*)pItem)->GetValue();
480             }
481         }
482         else
483             SetDefFormat(nFormat);
484 
485         delete pDlg;
486     }
487     return 0;
488 }
489 
490 /*--------------------------------------------------------------------
491     Beschreibung:
492  --------------------------------------------------------------------*/
493 
494 double NumFormatListBox::GetDefValue(const short nFormatType) const
495 {
496     double fDefValue = 0.0;
497 
498     switch (nFormatType)
499     {
500         case NUMBERFORMAT_DATE:
501         case NUMBERFORMAT_DATE|NUMBERFORMAT_TIME:
502             fDefValue = SVX_NUMVAL_DATE;
503             break;
504 
505         case NUMBERFORMAT_TIME:
506             fDefValue = SVX_NUMVAL_TIME;
507             break;
508 /*      {
509             String sValue("31.8.1997 16:57:34");
510             sal_uLong nFormat = pFormatter->GetStandardFormat(nFormatType, LANGUAGE_GERMAN);
511             pFormatter->IsNumberFormat( sValue, nFormat, fDefValue );
512         }
513         break;*/
514 
515         case NUMBERFORMAT_TEXT:
516         case NUMBERFORMAT_UNDEFINED:
517             fDefValue = 0;
518             break;
519 
520         case NUMBERFORMAT_CURRENCY:
521             fDefValue = SVX_NUMVAL_CURRENCY;
522             break;
523 
524         case NUMBERFORMAT_PERCENT:
525             fDefValue = SVX_NUMVAL_PERCENT;
526             break;
527 
528         case NUMBERFORMAT_LOGICAL:
529             fDefValue = SVX_NUMVAL_BOOLEAN;
530             break;
531 
532         default:
533             fDefValue = SVX_NUMVAL_STANDARD;
534             break;
535     }
536 
537     return fDefValue;
538 }
539 
540 /*--------------------------------------------------------------------
541     Beschreibung:
542  --------------------------------------------------------------------*/
543 
544 void NumFormatListBox::Clear()
545 {
546     ListBox::Clear();
547     nCurrFormatType = -1;
548 }
549 
550