LibreOffice Module sw (master) 1
numfmtlb.cxx
Go to the documentation of this file.
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 <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>
29#include <docsh.hxx>
30#include <swtypes.hxx>
31#include <swmodule.hxx>
32#include <view.hxx>
33#include <wrtsh.hxx>
34#include <numfmtlb.hxx>
35#include <strings.hrc>
36#include <swabstdlg.hxx>
37#include <memory>
38
39using namespace ::com::sun::star::uno;
40using namespace ::com::sun::star::lang;
41
48namespace
49{
50
51bool lcl_isSystemFormat(sal_uInt32 nDefaultFormat, SvNumberFormatter* pFormatter, LanguageType eCurLanguage)
52{
53 const sal_uInt32 nSysNumFormat = pFormatter->GetFormatIndex(NF_NUMBER_SYSTEM, eCurLanguage);
54 if (nDefaultFormat == nSysNumFormat)
55 return true;
56 const sal_uInt32 nSysShortDateFormat = pFormatter->GetFormatIndex(NF_DATE_SYSTEM_SHORT, eCurLanguage);
57 if (nDefaultFormat == nSysShortDateFormat)
58 return true;
59 const sal_uInt32 nSysLongDateFormat = pFormatter->GetFormatIndex(NF_DATE_SYSTEM_LONG, eCurLanguage);
60 if (nDefaultFormat == nSysLongDateFormat)
61 return true;
62
63 if ( eCurLanguage != GetAppLanguage() )
64 return false;
65
66 if (nDefaultFormat == pFormatter->GetFormatForLanguageIfBuiltIn(nSysNumFormat, LANGUAGE_SYSTEM))
67 return true;
68 if (nDefaultFormat == pFormatter->GetFormatForLanguageIfBuiltIn(nSysShortDateFormat, LANGUAGE_SYSTEM))
69 return true;
70 if (nDefaultFormat == pFormatter->GetFormatForLanguageIfBuiltIn(nSysLongDateFormat, LANGUAGE_SYSTEM))
71 return true;
72
73 return false;
74}
75
76}
77
79{
80 SvxNumValCategory nDefValue = SvxNumValCategory::Standard;
81
82 switch (nFormatType)
83 {
84 case SvNumFormatType::DATE:
85 case SvNumFormatType::DATE|SvNumFormatType::TIME:
86 nDefValue = SvxNumValCategory::Date;
87 break;
88
89 case SvNumFormatType::TIME:
90 nDefValue = SvxNumValCategory::Time;
91 break;
92
93 case SvNumFormatType::TEXT:
94 case SvNumFormatType::UNDEFINED:
95 nDefValue = SvxNumValCategory::Standard;
96 break;
97
98 case SvNumFormatType::CURRENCY:
99 nDefValue = SvxNumValCategory::Currency;
100 break;
101
102 case SvNumFormatType::PERCENT:
103 nDefValue = SvxNumValCategory::Percent;
104 break;
105
106 case SvNumFormatType::LOGICAL:
107 nDefValue = SvxNumValCategory::Boolean;
108 break;
109
110 default:
111 nDefValue = SvxNumValCategory::Standard;
112 break;
113 }
114
115 return fSvxNumValConst[nDefValue];
116}
117
119 : m_nStdEntry(0)
120 , m_nDefFormat(0)
121 , m_nCurrFormatType(SvNumFormatType::ALL)
122 , m_bOneArea(false)
123 , mbCurrFormatTypeNeedsInit(true)
124 , m_bShowLanguageControl(false)
125 , m_bUseAutomaticLanguage(true)
126{
127}
128
129NumFormatListBox::NumFormatListBox(std::unique_ptr<weld::ComboBox> xControl)
130 : mxControl(std::move(xControl))
131{
132 Init();
133}
134
135SwNumFormatTreeView::SwNumFormatTreeView(std::unique_ptr<weld::TreeView> xControl)
136 : mxControl(std::move(xControl))
137{
138 Init();
139}
140
142{
143 if (SwView *pView = GetActiveView())
144 m_eCurLanguage = pView->GetWrtShell().GetCurLang();
145 else
147
148 SetFormatType(SvNumFormatType::NUMBER);
150}
151
153{
155
156 mxControl->connect_changed(LINK(this, NumFormatListBox, SelectHdl));
157}
158
160{
162
163 mxControl->connect_changed(LINK(this, SwNumFormatTreeView, SelectHdl));
164}
165
167{
169 (m_nCurrFormatType & nFormatType)) // there are mixed formats, like for example DateTime
170 return;
171
172 SwView *pView = GetActiveView();
173 if(!pView)
174 return;
175 SwWrtShell &rSh = pView->GetWrtShell();
176 SvNumberFormatter* pFormatter = rSh.GetNumberFormatter();
177
178 clear(); // Remove all entries from the Listbox
179
180 NfIndexTableOffset eOffsetStart = NF_NUMBER_START;
182
183 switch( nFormatType )
184 {
185 case SvNumFormatType::NUMBER:
186 eOffsetStart=NF_NUMBER_START;
187 eOffsetEnd=NF_NUMBER_END;
188 break;
189
190 case SvNumFormatType::PERCENT:
191 eOffsetStart=NF_PERCENT_START;
192 eOffsetEnd=NF_PERCENT_END;
193 break;
194
195 case SvNumFormatType::CURRENCY:
196 eOffsetStart=NF_CURRENCY_START;
197 eOffsetEnd=NF_CURRENCY_END;
198 break;
199
200 case SvNumFormatType::DATETIME:
201 eOffsetStart=NF_DATE_START;
202 eOffsetEnd=NF_TIME_END;
203 break;
204
205 case SvNumFormatType::DATE:
206 eOffsetStart=NF_DATE_START;
207 eOffsetEnd=NF_DATE_END;
208 break;
209
210 case SvNumFormatType::TIME:
211 eOffsetStart=NF_TIME_START;
212 eOffsetEnd=NF_TIME_END;
213 break;
214
215 case SvNumFormatType::SCIENTIFIC:
216 eOffsetStart=NF_SCIENTIFIC_START;
217 eOffsetEnd=NF_SCIENTIFIC_END;
218 break;
219
220 case SvNumFormatType::FRACTION:
221 eOffsetStart=NF_FRACTION_START;
222 eOffsetEnd=NF_FRACTION_END;
223 break;
224
225 case SvNumFormatType::LOGICAL:
226 eOffsetStart=NF_BOOLEAN;
227 eOffsetEnd=NF_BOOLEAN;
228 break;
229
230 case SvNumFormatType::TEXT:
231 eOffsetStart=NF_TEXT;
232 eOffsetEnd=NF_TEXT;
233 break;
234
235 case SvNumFormatType::ALL:
236 eOffsetStart=NF_NUMERIC_START;
237 eOffsetEnd = NfIndexTableOffset( NF_INDEX_TABLE_ENTRIES - 1 );
238 break;
239
240 default:
241 OSL_FAIL("what a format?");
242 break;
243 }
244
245 const SvNumberformat* pFormat;
246 sal_Int32 i = 0;
247 const Color* pCol;
248 double fVal = SwNumFormatBase::GetDefValue(nFormatType);
249 OUString sValue;
250
251 const sal_uInt32 nSysNumFormat = pFormatter->GetFormatIndex(
253 const sal_uInt32 nSysShortDateFormat = pFormatter->GetFormatIndex(
255 const sal_uInt32 nSysLongDateFormat = pFormatter->GetFormatIndex(
257
258 for( tools::Long nIndex = eOffsetStart; nIndex <= eOffsetEnd; ++nIndex )
259 {
260 const sal_uInt32 nFormat = pFormatter->GetFormatIndex(
262 pFormat = pFormatter->GetEntry( nFormat );
263
264 if( nFormat == pFormatter->GetFormatIndex( NF_NUMBER_STANDARD,
266 || const_cast<SvNumberformat*>(pFormat)->GetOutputString( fVal, sValue, &pCol )
267 || nFormatType == SvNumFormatType::UNDEFINED )
268 {
269 sValue = pFormat->GetFormatstring();
270 }
271 else if( nFormatType == SvNumFormatType::TEXT )
272 {
273 pFormatter->GetOutputString( "\"ABC\"", nFormat, sValue, &pCol);
274 }
275
276 if (nFormat != nSysNumFormat &&
277 nFormat != nSysShortDateFormat &&
278 nFormat != nSysLongDateFormat)
279 {
280 append(OUString::number(nFormat), sValue);
281
282 if( nFormat == pFormatter->GetStandardFormat(
283 nFormatType, m_eCurLanguage ) )
284 m_nStdEntry = i;
285 ++i;
286 }
287 }
288
289 append_text(SwResId(STR_DEFINE_NUMBERFORMAT));
290
292
293 m_nCurrFormatType = nFormatType;
295
296}
297
298void SwNumFormatBase::SetDefFormat(const sal_uInt32 nDefaultFormat)
299{
300 if (nDefaultFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
301 {
302 m_nDefFormat = nDefaultFormat;
303 return;
304 }
305
306 SwView *pView = GetActiveView();
307 if(!pView)
308 return;
309 SwWrtShell &rSh = pView->GetWrtShell();
310 SvNumberFormatter* pFormatter = rSh.GetNumberFormatter();
311
312 SvNumFormatType nType = pFormatter->GetType(nDefaultFormat);
313
315
316 sal_uInt32 nFormat = pFormatter->GetFormatForLanguageIfBuiltIn(nDefaultFormat, m_eCurLanguage);
317
318 for (sal_Int32 i = 0, nCount = get_count(); i < nCount; ++i)
319 {
320 if (nFormat == get_id(i).toUInt32())
321 {
322 set_active(i);
323 m_nStdEntry = i;
325 return;
326 }
327 }
328
329 // No entry found:
330 OUString sValue;
331 const Color* pCol = nullptr;
332
333 if (nType == SvNumFormatType::TEXT)
334 {
335 pFormatter->GetOutputString("\"ABC\"", nDefaultFormat, sValue, &pCol);
336 }
337 else
338 {
339 pFormatter->GetOutputString(SwNumFormatBase::GetDefValue(nType), nDefaultFormat, sValue, &pCol);
340 }
341
342 sal_Int32 nPos = 0;
344 nPos++;
345
346 if ( lcl_isSystemFormat(nDefaultFormat, pFormatter, m_eCurLanguage) )
347 {
348 sValue += SwResId(RID_STR_SYSTEM);
349 }
350
351 insert_text(nPos, sValue); // Insert as first numeric entry
352 set_id(nPos, OUString::number(nDefaultFormat));
355}
356
358{
359 return mxControl->get_active_id().toUInt32();
360}
361
363{
364 return mxControl->get_selected_id().toUInt32();
365}
366
368{
369 const sal_Int32 nPos = get_active();
370 OUString sDefine(SwResId( STR_DEFINE_NUMBERFORMAT ));
371 SwView *pView = GetActiveView();
372
373 if (!pView || nPos != get_count() - 1 || get_text(nPos) != sDefine)
374 return;
375
376 SwWrtShell &rSh = pView->GetWrtShell();
377 SvNumberFormatter* pFormatter = rSh.GetNumberFormatter();
378
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() );
386
388
389 sal_uInt32 nFormat = pFormatter->GetStandardFormat( m_nCurrFormatType, m_eCurLanguage);
390 aCoreSet.Put( SfxUInt32Item( SID_ATTR_NUMBERFORMAT_VALUE, nFormat ));
391
392 aCoreSet.Put( SvxNumberInfoItem( pFormatter, fValue,
393 SID_ATTR_NUMBERFORMAT_INFO ) );
394
395 if( (SvNumFormatType::DATE | SvNumFormatType::TIME) & m_nCurrFormatType )
396 aCoreSet.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ONE_AREA, m_bOneArea));
397
398 aCoreSet.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_NOLANGUAGE, !m_bShowLanguageControl));
399 aCoreSet.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ADD_AUTO, m_bUseAutomaticLanguage));
400
401 // force deselect to break mouse lock on selected entry
402 set_active(-1);
403
406
407 if (RET_OK == pDlg->Execute())
408 {
409 const SvxNumberInfoItem* pFormatInfoItem = pView->GetDocShell()->
410 GetItem( SID_ATTR_NUMBERFORMAT_INFO );
411
412 if( pFormatInfoItem )
413 {
414 for ( sal_uInt32 key : pFormatInfoItem->GetDelFormats() )
415 pFormatter->DeleteEntry( key );
416 }
417
418 const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
419 if( const SfxUInt32Item* pFormatValueItem = pOutSet->GetItemIfSet(
420 SID_ATTR_NUMBERFORMAT_VALUE, false ))
421 {
422 sal_uInt32 nNumberFormat = pFormatValueItem->GetValue();
423 // oj #105473# change order of calls
424 const SvNumberformat* pFormat = pFormatter->GetEntry(nNumberFormat);
425 if( pFormat )
426 m_eCurLanguage = pFormat->GetLanguage();
427 // SetDefFormat uses eCurLanguage to look for if this format already in the list
428 SetDefFormat(nNumberFormat);
429 }
430 const SfxBoolItem* pAddAutoItem;
431 if( m_bShowLanguageControl && (pAddAutoItem = pOutSet->GetItemIfSet(
432 SID_ATTR_NUMBERFORMAT_ADD_AUTO, false)))
433 {
434 m_bUseAutomaticLanguage = pAddAutoItem->GetValue();
435 }
436 }
437 else
438 SetDefFormat(nFormat);
439
440}
441
443{
444 CallSelectHdl();
445}
446
448{
449 CallSelectHdl();
450}
451
453{
455 m_nCurrFormatType = SvNumFormatType::ALL;
456}
457
459{
460 mxControl->clear();
462}
463
465{
466 mxControl->clear();
468}
469
470/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
LanguageType getLanguageType(bool bResolveSystem=true) const
virtual sal_uInt32 GetFormat() const override
Definition: numfmtlb.cxx:357
std::unique_ptr< weld::ComboBox > mxControl
Definition: numfmtlb.hxx:74
NumFormatListBox(std::unique_ptr< weld::ComboBox > xControl)
Definition: numfmtlb.cxx:129
virtual void clear() override
Definition: numfmtlb.cxx:458
virtual void Init() override
Definition: numfmtlb.cxx:152
bool GetValue() const
const T * GetItemIfSet(TypedWhichId< T > nWhich, bool bSrchInParent=true) const
sal_uInt32 GetStandardFormat(SvNumFormatType eType, LanguageType eLnge=LANGUAGE_DONTKNOW)
void DeleteEntry(sal_uInt32 nKey)
void GetOutputString(const double &fOutNumber, sal_uInt32 nFIndex, OUString &sOutString, const Color **ppColor, bool bUseStarFormat=false)
SvNumFormatType GetType(sal_uInt32 nFIndex) const
sal_uInt32 GetFormatIndex(NfIndexTableOffset, LanguageType eLnge=LANGUAGE_DONTKNOW)
const SvNumberformat * GetEntry(sal_uInt32 nKey) const
sal_uInt32 GetFormatForLanguageIfBuiltIn(sal_uInt32 nFormat, LanguageType eLnge=LANGUAGE_DONTKNOW)
LanguageType GetLanguage() const
const OUString & GetFormatstring() const
const LanguageTag & GetLanguageTag() const
const std::vector< sal_uInt32 > & GetDelFormats() const
virtual VclPtr< SfxAbstractDialog > CreateNumFormatDialog(weld::Widget *pParent, const SfxItemSet &rAttr)=0
static SwAbstractDialogFactory * Create()
Definition: swabstdlg.cxx:36
SvNumberFormatter * GetNumberFormatter()
Query NumberFormatter from document.
Definition: editsh.cxx:756
bool mbCurrFormatTypeNeedsInit
Definition: numfmtlb.hxx:35
virtual void append(const OUString &rId, const OUString &rText)=0
virtual void clear()
Definition: numfmtlb.cxx:452
sal_uInt32 m_nDefFormat
Definition: numfmtlb.hxx:31
virtual int get_active() const =0
virtual OUString get_id(int nPos) const =0
LanguageType m_eCurLanguage
Definition: numfmtlb.hxx:33
virtual void set_id(int nPos, const OUString &rId)=0
void SetDefFormat(const sal_uInt32 nDefFormat)
Definition: numfmtlb.cxx:298
virtual void insert_text(int nPos, const OUString &rText)=0
virtual void append_text(const OUString &rText)=0
bool m_bShowLanguageControl
Definition: numfmtlb.hxx:36
SvNumFormatType m_nCurrFormatType
Definition: numfmtlb.hxx:32
virtual sal_uInt32 GetFormat() const =0
void SetFormatType(const SvNumFormatType nFormatType)
Definition: numfmtlb.cxx:166
virtual weld::Widget & get_widget() const =0
virtual void set_active(int nPos)=0
static SAL_DLLPRIVATE double GetDefValue(const SvNumFormatType nFormatType)
Definition: numfmtlb.cxx:78
void CallSelectHdl()
Definition: numfmtlb.cxx:367
virtual void Init()
Definition: numfmtlb.cxx:141
sal_Int32 m_nStdEntry
Definition: numfmtlb.hxx:30
virtual int get_count() const =0
virtual OUString get_text(int nPos) const =0
bool m_bUseAutomaticLanguage
Definition: numfmtlb.hxx:38
virtual void Init() override
Definition: numfmtlb.cxx:159
virtual sal_uInt32 GetFormat() const override
Definition: numfmtlb.cxx:362
virtual void clear() override
Definition: numfmtlb.cxx:464
std::unique_ptr< weld::TreeView > mxControl
Definition: numfmtlb.hxx:107
SwNumFormatTreeView(std::unique_ptr< weld::TreeView > xControl)
Definition: numfmtlb.cxx:135
const SfxItemPool & GetAttrPool() const
Definition: viewsh.hxx:648
Definition: view.hxx:146
SwWrtShell & GetWrtShell() const
Definition: view.hxx:423
SwDocShell * GetDocShell()
Definition: view.cxx:1193
Used by the UI to modify the document model.
Definition: wrtsh.hxx:97
int nCount
SvxNumValCategory
const o3tl::enumarray< SvxNumValCategory, double > fSvxNumValConst
LanguageType GetAppLanguage()
Definition: init.cxx:741
sal_Int32 nIndex
sal_uInt16 nPos
const SfxPoolItem * GetItem(const SwTextAttr &rAttr, sal_uInt16 nWhich)
Extracts pool item of type nWhich from rAttr.
Definition: atrstck.cxx:157
int i
sal_uInt32 toUInt32(std::u16string_view str, sal_Int16 radix=10)
long Long
IMPL_LINK_NOARG(NumFormatListBox, SelectHdl, weld::ComboBox &, void)
Definition: numfmtlb.cxx:442
QPRO_FUNC_TYPE nType
SwView * GetActiveView()
Definition: swmodul1.cxx:115
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:168
RET_OK
SvNumFormatType
NfIndexTableOffset
NF_TIME_END
NF_SCIENTIFIC_START
NF_DATE_SYSTEM_SHORT
NF_DATE_END
NF_SCIENTIFIC_END
NF_NUMBER_END
NF_FRACTION_END
NF_FRACTION_START
NF_NUMBER_SYSTEM
NF_CURRENCY_START
NF_TEXT
NF_INDEX_TABLE_ENTRIES
NF_BOOLEAN
NF_CURRENCY_END
NF_TIME_START
NF_NUMBER_STANDARD
NF_PERCENT_START
NF_DATE_START
NF_PERCENT_END
NF_NUMERIC_START
NF_NUMBER_START
NF_DATE_SYSTEM_LONG
constexpr sal_uInt32 NUMBERFORMAT_ENTRY_NOT_FOUND