1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <i18nlangtag/lang.h>
21 #include <svl/numformat.hxx>
22 #include <svl/zformat.hxx>
23 #include <svl/eitem.hxx>
24 #include <svx/svxids.hrc>
25 #include <svx/numinf.hxx>
26 #include <svx/flagsdef.hxx>
27 #include <svl/itemset.hxx>
28 #include <osl/diagnose.h>
30 #include <swtypes.hxx>
31 #include <swmodule.hxx>
34 #include <numfmtlb.hxx>
35 #include <strings.hrc>
36 #include <swabstdlg.hxx>
39 using namespace ::com::sun::star::uno
;
40 using namespace ::com::sun::star::lang
;
44 * nFormatType: Display the formats of this Type
45 * nDefaultFormat: Select this format and possibly insert it
51 bool lcl_isSystemFormat(sal_uInt32 nDefaultFormat
, SvNumberFormatter
* pFormatter
, LanguageType eCurLanguage
)
53 const sal_uInt32 nSysNumFormat
= pFormatter
->GetFormatIndex(NF_NUMBER_SYSTEM
, eCurLanguage
);
54 if (nDefaultFormat
== nSysNumFormat
)
56 const sal_uInt32 nSysShortDateFormat
= pFormatter
->GetFormatIndex(NF_DATE_SYSTEM_SHORT
, eCurLanguage
);
57 if (nDefaultFormat
== nSysShortDateFormat
)
59 const sal_uInt32 nSysLongDateFormat
= pFormatter
->GetFormatIndex(NF_DATE_SYSTEM_LONG
, eCurLanguage
);
60 if (nDefaultFormat
== nSysLongDateFormat
)
63 if ( eCurLanguage
!= GetAppLanguage() )
66 if (nDefaultFormat
== pFormatter
->GetFormatForLanguageIfBuiltIn(nSysNumFormat
, LANGUAGE_SYSTEM
))
68 if (nDefaultFormat
== pFormatter
->GetFormatForLanguageIfBuiltIn(nSysShortDateFormat
, LANGUAGE_SYSTEM
))
70 if (nDefaultFormat
== pFormatter
->GetFormatForLanguageIfBuiltIn(nSysLongDateFormat
, LANGUAGE_SYSTEM
))
78 double SwNumFormatBase::GetDefValue(const SvNumFormatType nFormatType
)
80 SvxNumValCategory nDefValue
= SvxNumValCategory::Standard
;
84 case SvNumFormatType::DATE
:
85 case SvNumFormatType::DATE
|SvNumFormatType::TIME
:
86 nDefValue
= SvxNumValCategory::Date
;
89 case SvNumFormatType::TIME
:
90 nDefValue
= SvxNumValCategory::Time
;
93 case SvNumFormatType::TEXT
:
94 case SvNumFormatType::UNDEFINED
:
95 nDefValue
= SvxNumValCategory::Standard
;
98 case SvNumFormatType::CURRENCY
:
99 nDefValue
= SvxNumValCategory::Currency
;
102 case SvNumFormatType::PERCENT
:
103 nDefValue
= SvxNumValCategory::Percent
;
106 case SvNumFormatType::LOGICAL
:
107 nDefValue
= SvxNumValCategory::Boolean
;
111 nDefValue
= SvxNumValCategory::Standard
;
115 return fSvxNumValConst
[nDefValue
];
118 SwNumFormatBase::SwNumFormatBase()
121 , m_nCurrFormatType(SvNumFormatType::ALL
)
123 , mbCurrFormatTypeNeedsInit(true)
124 , m_bShowLanguageControl(false)
125 , m_bUseAutomaticLanguage(true)
129 NumFormatListBox::NumFormatListBox(std::unique_ptr
<weld::ComboBox
> xControl
)
130 : mxControl(std::move(xControl
))
135 SwNumFormatTreeView::SwNumFormatTreeView(std::unique_ptr
<weld::TreeView
> xControl
)
136 : mxControl(std::move(xControl
))
141 void SwNumFormatBase::Init()
143 if (SwView
*pView
= GetActiveView())
144 m_eCurLanguage
= pView
->GetWrtShell().GetCurLang();
146 m_eCurLanguage
= SvtSysLocale().GetLanguageTag().getLanguageType();
148 SetFormatType(SvNumFormatType::NUMBER
);
149 SetDefFormat(m_nDefFormat
);
152 void NumFormatListBox::Init()
154 SwNumFormatBase::Init();
156 mxControl
->connect_changed(LINK(this, NumFormatListBox
, SelectHdl
));
159 void SwNumFormatTreeView::Init()
161 SwNumFormatBase::Init();
163 mxControl
->connect_changed(LINK(this, SwNumFormatTreeView
, SelectHdl
));
166 void SwNumFormatBase::SetFormatType(const SvNumFormatType nFormatType
)
168 if (!mbCurrFormatTypeNeedsInit
&&
169 (m_nCurrFormatType
& nFormatType
)) // there are mixed formats, like for example DateTime
172 SwView
*pView
= GetActiveView();
175 SwWrtShell
&rSh
= pView
->GetWrtShell();
176 SvNumberFormatter
* pFormatter
= rSh
.GetNumberFormatter();
178 clear(); // Remove all entries from the Listbox
180 NfIndexTableOffset eOffsetStart
= NF_NUMBER_START
;
181 NfIndexTableOffset eOffsetEnd
= NF_NUMBER_START
;
183 switch( nFormatType
)
185 case SvNumFormatType::NUMBER
:
186 eOffsetStart
=NF_NUMBER_START
;
187 eOffsetEnd
=NF_NUMBER_END
;
190 case SvNumFormatType::PERCENT
:
191 eOffsetStart
=NF_PERCENT_START
;
192 eOffsetEnd
=NF_PERCENT_END
;
195 case SvNumFormatType::CURRENCY
:
196 eOffsetStart
=NF_CURRENCY_START
;
197 eOffsetEnd
=NF_CURRENCY_END
;
200 case SvNumFormatType::DATETIME
:
201 eOffsetStart
=NF_DATE_START
;
202 eOffsetEnd
=NF_TIME_END
;
205 case SvNumFormatType::DATE
:
206 eOffsetStart
=NF_DATE_START
;
207 eOffsetEnd
=NF_DATE_END
;
210 case SvNumFormatType::TIME
:
211 eOffsetStart
=NF_TIME_START
;
212 eOffsetEnd
=NF_TIME_END
;
215 case SvNumFormatType::SCIENTIFIC
:
216 eOffsetStart
=NF_SCIENTIFIC_START
;
217 eOffsetEnd
=NF_SCIENTIFIC_END
;
220 case SvNumFormatType::FRACTION
:
221 eOffsetStart
=NF_FRACTION_START
;
222 eOffsetEnd
=NF_FRACTION_END
;
225 case SvNumFormatType::LOGICAL
:
226 eOffsetStart
=NF_BOOLEAN
;
227 eOffsetEnd
=NF_BOOLEAN
;
230 case SvNumFormatType::TEXT
:
231 eOffsetStart
=NF_TEXT
;
235 case SvNumFormatType::ALL
:
236 eOffsetStart
=NF_NUMERIC_START
;
237 eOffsetEnd
= NfIndexTableOffset( NF_INDEX_TABLE_ENTRIES
- 1 );
241 OSL_FAIL("what a format?");
245 const SvNumberformat
* pFormat
;
248 double fVal
= SwNumFormatBase::GetDefValue(nFormatType
);
251 const sal_uInt32 nSysNumFormat
= pFormatter
->GetFormatIndex(
252 NF_NUMBER_SYSTEM
, m_eCurLanguage
);
253 const sal_uInt32 nSysShortDateFormat
= pFormatter
->GetFormatIndex(
254 NF_DATE_SYSTEM_SHORT
, m_eCurLanguage
);
255 const sal_uInt32 nSysLongDateFormat
= pFormatter
->GetFormatIndex(
256 NF_DATE_SYSTEM_LONG
, m_eCurLanguage
);
258 for( tools::Long nIndex
= eOffsetStart
; nIndex
<= eOffsetEnd
; ++nIndex
)
260 const sal_uInt32 nFormat
= pFormatter
->GetFormatIndex(
261 static_cast<NfIndexTableOffset
>(nIndex
), m_eCurLanguage
);
262 pFormat
= pFormatter
->GetEntry( nFormat
);
264 if( nFormat
== pFormatter
->GetFormatIndex( NF_NUMBER_STANDARD
,
266 || const_cast<SvNumberformat
*>(pFormat
)->GetOutputString( fVal
, sValue
, &pCol
)
267 || nFormatType
== SvNumFormatType::UNDEFINED
)
269 sValue
= pFormat
->GetFormatstring();
271 else if( nFormatType
== SvNumFormatType::TEXT
)
273 pFormatter
->GetOutputString( "\"ABC\"", nFormat
, sValue
, &pCol
);
276 if (nFormat
!= nSysNumFormat
&&
277 nFormat
!= nSysShortDateFormat
&&
278 nFormat
!= nSysLongDateFormat
)
280 append(OUString::number(nFormat
), sValue
);
282 if( nFormat
== pFormatter
->GetStandardFormat(
283 nFormatType
, m_eCurLanguage
) )
289 append_text(SwResId(STR_DEFINE_NUMBERFORMAT
));
291 set_active(m_nStdEntry
);
293 m_nCurrFormatType
= nFormatType
;
294 mbCurrFormatTypeNeedsInit
= false;
298 void SwNumFormatBase::SetDefFormat(const sal_uInt32 nDefaultFormat
)
300 if (nDefaultFormat
== NUMBERFORMAT_ENTRY_NOT_FOUND
)
302 m_nDefFormat
= nDefaultFormat
;
306 SwView
*pView
= GetActiveView();
309 SwWrtShell
&rSh
= pView
->GetWrtShell();
310 SvNumberFormatter
* pFormatter
= rSh
.GetNumberFormatter();
312 SvNumFormatType nType
= pFormatter
->GetType(nDefaultFormat
);
314 SetFormatType(nType
);
316 sal_uInt32 nFormat
= pFormatter
->GetFormatForLanguageIfBuiltIn(nDefaultFormat
, m_eCurLanguage
);
318 for (sal_Int32 i
= 0, nCount
= get_count(); i
< nCount
; ++i
)
320 if (nFormat
== get_id(i
).toUInt32())
324 m_nDefFormat
= GetFormat();
331 const Color
* pCol
= nullptr;
333 if (nType
== SvNumFormatType::TEXT
)
335 pFormatter
->GetOutputString("\"ABC\"", nDefaultFormat
, sValue
, &pCol
);
339 pFormatter
->GetOutputString(SwNumFormatBase::GetDefValue(nType
), nDefaultFormat
, sValue
, &pCol
);
343 while (get_id(nPos
).toUInt32() == NUMBERFORMAT_ENTRY_NOT_FOUND
)
346 if ( lcl_isSystemFormat(nDefaultFormat
, pFormatter
, m_eCurLanguage
) )
348 sValue
+= SwResId(RID_STR_SYSTEM
);
351 insert_text(nPos
, sValue
); // Insert as first numeric entry
352 set_id(nPos
, OUString::number(nDefaultFormat
));
354 m_nDefFormat
= GetFormat();
357 sal_uInt32
NumFormatListBox::GetFormat() const
359 return mxControl
->get_active_id().toUInt32();
362 sal_uInt32
SwNumFormatTreeView::GetFormat() const
364 return mxControl
->get_selected_id().toUInt32();
367 void SwNumFormatBase::CallSelectHdl()
369 const sal_Int32 nPos
= get_active();
370 OUString
sDefine(SwResId( STR_DEFINE_NUMBERFORMAT
));
371 SwView
*pView
= GetActiveView();
373 if (!pView
|| nPos
!= get_count() - 1 || get_text(nPos
) != sDefine
)
376 SwWrtShell
&rSh
= pView
->GetWrtShell();
377 SvNumberFormatter
* pFormatter
= rSh
.GetNumberFormatter();
380 SID_ATTR_NUMBERFORMAT_VALUE
, SID_ATTR_NUMBERFORMAT_INFO
,
381 SID_ATTR_NUMBERFORMAT_ONE_AREA
, SID_ATTR_NUMBERFORMAT_ONE_AREA
,
382 SID_ATTR_NUMBERFORMAT_NOLANGUAGE
,
383 SID_ATTR_NUMBERFORMAT_NOLANGUAGE
,
384 SID_ATTR_NUMBERFORMAT_ADD_AUTO
,
385 SID_ATTR_NUMBERFORMAT_ADD_AUTO
> aCoreSet( rSh
.GetAttrPool() );
387 double fValue
= SwNumFormatBase::GetDefValue(m_nCurrFormatType
);
389 sal_uInt32 nFormat
= pFormatter
->GetStandardFormat( m_nCurrFormatType
, m_eCurLanguage
);
390 aCoreSet
.Put( SfxUInt32Item( SID_ATTR_NUMBERFORMAT_VALUE
, nFormat
));
392 aCoreSet
.Put( SvxNumberInfoItem( pFormatter
, fValue
,
393 SID_ATTR_NUMBERFORMAT_INFO
) );
395 if( (SvNumFormatType::DATE
| SvNumFormatType::TIME
) & m_nCurrFormatType
)
396 aCoreSet
.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ONE_AREA
, m_bOneArea
));
398 aCoreSet
.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_NOLANGUAGE
, !m_bShowLanguageControl
));
399 aCoreSet
.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ADD_AUTO
, m_bUseAutomaticLanguage
));
401 // force deselect to break mouse lock on selected entry
404 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
405 ScopedVclPtr
<SfxAbstractDialog
> pDlg(pFact
->CreateNumFormatDialog(&get_widget(), aCoreSet
));
407 if (RET_OK
== pDlg
->Execute())
409 const SvxNumberInfoItem
* pFormatInfoItem
= pView
->GetDocShell()->
410 GetItem( SID_ATTR_NUMBERFORMAT_INFO
);
412 if( pFormatInfoItem
)
414 for ( sal_uInt32 key
: pFormatInfoItem
->GetDelFormats() )
415 pFormatter
->DeleteEntry( key
);
418 const SfxItemSet
* pOutSet
= pDlg
->GetOutputItemSet();
419 if( const SfxUInt32Item
* pFormatValueItem
= pOutSet
->GetItemIfSet(
420 SID_ATTR_NUMBERFORMAT_VALUE
, false ))
422 sal_uInt32 nNumberFormat
= pFormatValueItem
->GetValue();
423 // oj #105473# change order of calls
424 const SvNumberformat
* pFormat
= pFormatter
->GetEntry(nNumberFormat
);
426 m_eCurLanguage
= pFormat
->GetLanguage();
427 // SetDefFormat uses eCurLanguage to look for if this format already in the list
428 SetDefFormat(nNumberFormat
);
430 const SfxBoolItem
* pAddAutoItem
;
431 if( m_bShowLanguageControl
&& (pAddAutoItem
= pOutSet
->GetItemIfSet(
432 SID_ATTR_NUMBERFORMAT_ADD_AUTO
, false)))
434 m_bUseAutomaticLanguage
= pAddAutoItem
->GetValue();
438 SetDefFormat(nFormat
);
442 IMPL_LINK_NOARG(NumFormatListBox
, SelectHdl
, weld::ComboBox
&, void)
447 IMPL_LINK_NOARG(SwNumFormatTreeView
, SelectHdl
, weld::TreeView
&, void)
452 void SwNumFormatBase::clear()
454 mbCurrFormatTypeNeedsInit
= true;
455 m_nCurrFormatType
= SvNumFormatType::ALL
;
458 void NumFormatListBox::clear()
461 SwNumFormatBase::clear();
464 void SwNumFormatTreeView::clear()
467 SwNumFormatBase::clear();
470 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */