xref: /aoo41x/main/sw/source/ui/utlui/numfmtlb.cxx (revision cdf0e10c)
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