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 SwView *pView = GetActiveView();
144
145 if (pView)
147 else
149
150 SetFormatType(SvNumFormatType::NUMBER);
152}
153
155{
157
158 mxControl->connect_changed(LINK(this, NumFormatListBox, SelectHdl));
159}
160
162{
164
165 mxControl->connect_changed(LINK(this, SwNumFormatTreeView, SelectHdl));
166}
167
169{
171 (m_nCurrFormatType & nFormatType)) // there are mixed formats, like for example DateTime
172 return;
173
174 SwView *pView = GetActiveView();
175 OSL_ENSURE(pView, "no view found");
176 if(!pView)
177 return;
178 SwWrtShell &rSh = pView->GetWrtShell();
179 SvNumberFormatter* pFormatter = rSh.GetNumberFormatter();
180
181 clear(); // Remove all entries from the Listbox
182
183 NfIndexTableOffset eOffsetStart = NF_NUMBER_START;
185
186 switch( nFormatType )
187 {
188 case SvNumFormatType::NUMBER:
189 eOffsetStart=NF_NUMBER_START;
190 eOffsetEnd=NF_NUMBER_END;
191 break;
192
193 case SvNumFormatType::PERCENT:
194 eOffsetStart=NF_PERCENT_START;
195 eOffsetEnd=NF_PERCENT_END;
196 break;
197
198 case SvNumFormatType::CURRENCY:
199 eOffsetStart=NF_CURRENCY_START;
200 eOffsetEnd=NF_CURRENCY_END;
201 break;
202
203 case SvNumFormatType::DATETIME:
204 eOffsetStart=NF_DATE_START;
205 eOffsetEnd=NF_TIME_END;
206 break;
207
208 case SvNumFormatType::DATE:
209 eOffsetStart=NF_DATE_START;
210 eOffsetEnd=NF_DATE_END;
211 break;
212
213 case SvNumFormatType::TIME:
214 eOffsetStart=NF_TIME_START;
215 eOffsetEnd=NF_TIME_END;
216 break;
217
218 case SvNumFormatType::SCIENTIFIC:
219 eOffsetStart=NF_SCIENTIFIC_START;
220 eOffsetEnd=NF_SCIENTIFIC_END;
221 break;
222
223 case SvNumFormatType::FRACTION:
224 eOffsetStart=NF_FRACTION_START;
225 eOffsetEnd=NF_FRACTION_END;
226 break;
227
228 case SvNumFormatType::LOGICAL:
229 eOffsetStart=NF_BOOLEAN;
230 eOffsetEnd=NF_BOOLEAN;
231 break;
232
233 case SvNumFormatType::TEXT:
234 eOffsetStart=NF_TEXT;
235 eOffsetEnd=NF_TEXT;
236 break;
237
238 case SvNumFormatType::ALL:
239 eOffsetStart=NF_NUMERIC_START;
240 eOffsetEnd = NfIndexTableOffset( NF_INDEX_TABLE_ENTRIES - 1 );
241 break;
242
243 default:
244 OSL_FAIL("what a format?");
245 break;
246 }
247
248 const SvNumberformat* pFormat;
249 sal_Int32 i = 0;
250 const Color* pCol;
251 double fVal = SwNumFormatBase::GetDefValue(nFormatType);
252 OUString sValue;
253
254 const sal_uInt32 nSysNumFormat = pFormatter->GetFormatIndex(
256 const sal_uInt32 nSysShortDateFormat = pFormatter->GetFormatIndex(
258 const sal_uInt32 nSysLongDateFormat = pFormatter->GetFormatIndex(
260
261 for( tools::Long nIndex = eOffsetStart; nIndex <= eOffsetEnd; ++nIndex )
262 {
263 const sal_uInt32 nFormat = pFormatter->GetFormatIndex(
265 pFormat = pFormatter->GetEntry( nFormat );
266
267 if( nFormat == pFormatter->GetFormatIndex( NF_NUMBER_STANDARD,
269 || const_cast<SvNumberformat*>(pFormat)->GetOutputString( fVal, sValue, &pCol )
270 || nFormatType == SvNumFormatType::UNDEFINED )
271 {
272 sValue = pFormat->GetFormatstring();
273 }
274 else if( nFormatType == SvNumFormatType::TEXT )
275 {
276 pFormatter->GetOutputString( "\"ABC\"", nFormat, sValue, &pCol);
277 }
278
279 if (nFormat != nSysNumFormat &&
280 nFormat != nSysShortDateFormat &&
281 nFormat != nSysLongDateFormat)
282 {
283 append(OUString::number(nFormat), sValue);
284
285 if( nFormat == pFormatter->GetStandardFormat(
286 nFormatType, m_eCurLanguage ) )
287 m_nStdEntry = i;
288 ++i;
289 }
290 }
291
292 append_text(SwResId(STR_DEFINE_NUMBERFORMAT));
293
295
296 m_nCurrFormatType = nFormatType;
298
299}
300
301void SwNumFormatBase::SetDefFormat(const sal_uInt32 nDefaultFormat)
302{
303 if (nDefaultFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
304 {
305 m_nDefFormat = nDefaultFormat;
306 return;
307 }
308
309 SwView *pView = GetActiveView();
310 OSL_ENSURE(pView, "no view found");
311 if(!pView)
312 return;
313 SwWrtShell &rSh = pView->GetWrtShell();
314 SvNumberFormatter* pFormatter = rSh.GetNumberFormatter();
315
316 SvNumFormatType nType = pFormatter->GetType(nDefaultFormat);
317
319
320 sal_uInt32 nFormat = pFormatter->GetFormatForLanguageIfBuiltIn(nDefaultFormat, m_eCurLanguage);
321
322 for (sal_Int32 i = 0, nCount = get_count(); i < nCount; ++i)
323 {
324 if (nFormat == get_id(i).toUInt32())
325 {
326 set_active(i);
327 m_nStdEntry = i;
329 return;
330 }
331 }
332
333 // No entry found:
334 OUString sValue;
335 const Color* pCol = nullptr;
336
337 if (nType == SvNumFormatType::TEXT)
338 {
339 pFormatter->GetOutputString("\"ABC\"", nDefaultFormat, sValue, &pCol);
340 }
341 else
342 {
343 pFormatter->GetOutputString(SwNumFormatBase::GetDefValue(nType), nDefaultFormat, sValue, &pCol);
344 }
345
346 sal_Int32 nPos = 0;
348 nPos++;
349
350 if ( lcl_isSystemFormat(nDefaultFormat, pFormatter, m_eCurLanguage) )
351 {
352 sValue += SwResId(RID_STR_SYSTEM);
353 }
354
355 insert_text(nPos, sValue); // Insert as first numeric entry
356 set_id(nPos, OUString::number(nDefaultFormat));
359}
360
362{
363 return mxControl->get_active_id().toUInt32();
364}
365
367{
368 return mxControl->get_selected_id().toUInt32();
369}
370
372{
373 const sal_Int32 nPos = get_active();
374 OUString sDefine(SwResId( STR_DEFINE_NUMBERFORMAT ));
375 SwView *pView = GetActiveView();
376
377 if (!pView || nPos != get_count() - 1 || get_text(nPos) != sDefine)
378 return;
379
380 SwWrtShell &rSh = pView->GetWrtShell();
381 SvNumberFormatter* pFormatter = rSh.GetNumberFormatter();
382
384 SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_INFO,
385 SID_ATTR_NUMBERFORMAT_ONE_AREA, SID_ATTR_NUMBERFORMAT_ONE_AREA,
386 SID_ATTR_NUMBERFORMAT_NOLANGUAGE,
387 SID_ATTR_NUMBERFORMAT_NOLANGUAGE,
388 SID_ATTR_NUMBERFORMAT_ADD_AUTO,
389 SID_ATTR_NUMBERFORMAT_ADD_AUTO> aCoreSet( rSh.GetAttrPool() );
390
392
393 sal_uInt32 nFormat = pFormatter->GetStandardFormat( m_nCurrFormatType, m_eCurLanguage);
394 aCoreSet.Put( SfxUInt32Item( SID_ATTR_NUMBERFORMAT_VALUE, nFormat ));
395
396 aCoreSet.Put( SvxNumberInfoItem( pFormatter, fValue,
397 SID_ATTR_NUMBERFORMAT_INFO ) );
398
399 if( (SvNumFormatType::DATE | SvNumFormatType::TIME) & m_nCurrFormatType )
400 aCoreSet.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ONE_AREA, m_bOneArea));
401
402 aCoreSet.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_NOLANGUAGE, !m_bShowLanguageControl));
403 aCoreSet.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ADD_AUTO, m_bUseAutomaticLanguage));
404
405 // force deselect to break mouse lock on selected entry
406 set_active(-1);
407
410
411 if (RET_OK == pDlg->Execute())
412 {
413 const SvxNumberInfoItem* pFormatInfoItem = pView->GetDocShell()->
414 GetItem( SID_ATTR_NUMBERFORMAT_INFO );
415
416 if( pFormatInfoItem )
417 {
418 for ( sal_uInt32 key : pFormatInfoItem->GetDelFormats() )
419 pFormatter->DeleteEntry( key );
420 }
421
422 const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
423 if( const SfxUInt32Item* pFormatValueItem = pOutSet->GetItemIfSet(
424 SID_ATTR_NUMBERFORMAT_VALUE, false ))
425 {
426 sal_uInt32 nNumberFormat = pFormatValueItem->GetValue();
427 // oj #105473# change order of calls
428 const SvNumberformat* pFormat = pFormatter->GetEntry(nNumberFormat);
429 if( pFormat )
430 m_eCurLanguage = pFormat->GetLanguage();
431 // SetDefFormat uses eCurLanguage to look for if this format already in the list
432 SetDefFormat(nNumberFormat);
433 }
434 const SfxBoolItem* pAddAutoItem;
435 if( m_bShowLanguageControl && (pAddAutoItem = pOutSet->GetItemIfSet(
436 SID_ATTR_NUMBERFORMAT_ADD_AUTO, false)))
437 {
438 m_bUseAutomaticLanguage = pAddAutoItem->GetValue();
439 }
440 }
441 else
442 SetDefFormat(nFormat);
443
444}
445
447{
448 CallSelectHdl();
449}
450
452{
453 CallSelectHdl();
454}
455
457{
459 m_nCurrFormatType = SvNumFormatType::ALL;
460}
461
463{
464 mxControl->clear();
466}
467
469{
470 mxControl->clear();
472}
473
474/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
LanguageType getLanguageType(bool bResolveSystem=true) const
virtual sal_uInt32 GetFormat() const override
Definition: numfmtlb.cxx:361
std::unique_ptr< weld::ComboBox > mxControl
Definition: numfmtlb.hxx:75
NumFormatListBox(std::unique_ptr< weld::ComboBox > xControl)
Definition: numfmtlb.cxx:129
virtual void clear() override
Definition: numfmtlb.cxx:462
virtual void Init() override
Definition: numfmtlb.cxx:154
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
LanguageType GetCurLang() const
Definition: edattr.cxx:801
bool mbCurrFormatTypeNeedsInit
Definition: numfmtlb.hxx:36
virtual void append(const OUString &rId, const OUString &rText)=0
virtual void clear()
Definition: numfmtlb.cxx:456
sal_uInt32 m_nDefFormat
Definition: numfmtlb.hxx:32
virtual int get_active() const =0
virtual OUString get_id(int nPos) const =0
LanguageType m_eCurLanguage
Definition: numfmtlb.hxx:34
virtual void set_id(int nPos, const OUString &rId)=0
void SetDefFormat(const sal_uInt32 nDefFormat)
Definition: numfmtlb.cxx:301
virtual void insert_text(int nPos, const OUString &rText)=0
virtual void append_text(const OUString &rText)=0
bool m_bShowLanguageControl
Definition: numfmtlb.hxx:37
SvNumFormatType m_nCurrFormatType
Definition: numfmtlb.hxx:33
virtual sal_uInt32 GetFormat() const =0
void SetFormatType(const SvNumFormatType nFormatType)
Definition: numfmtlb.cxx:168
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:371
virtual void Init()
Definition: numfmtlb.cxx:141
sal_Int32 m_nStdEntry
Definition: numfmtlb.hxx:31
virtual int get_count() const =0
virtual OUString get_text(int nPos) const =0
bool m_bUseAutomaticLanguage
Definition: numfmtlb.hxx:39
virtual void Init() override
Definition: numfmtlb.cxx:161
virtual sal_uInt32 GetFormat() const override
Definition: numfmtlb.cxx:366
virtual void clear() override
Definition: numfmtlb.cxx:468
std::unique_ptr< weld::TreeView > mxControl
Definition: numfmtlb.hxx:108
SwNumFormatTreeView(std::unique_ptr< weld::TreeView > xControl)
Definition: numfmtlb.cxx:135
const SfxItemPool & GetAttrPool() const
Definition: viewsh.hxx:624
Definition: view.hxx:146
SwWrtShell & GetWrtShell() const
Definition: view.hxx:416
SwDocShell * GetDocShell()
Definition: view.cxx:1160
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:725
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:446
QPRO_FUNC_TYPE nType
SwView * GetActiveView()
Definition: swmodul1.cxx:116
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:165
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