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 
39 using namespace ::com::sun::star::uno;
40 using namespace ::com::sun::star::lang;
41 
48 namespace
49 {
50 
51 bool 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  : nStdEntry(0)
120  , nDefFormat(0)
121  , nCurrFormatType(SvNumFormatType::ALL)
122  , bOneArea(false)
123  , mbCurrFormatTypeNeedsInit(true)
124  , bShowLanguageControl(false)
125  , bUseAutomaticLanguage(true)
126 {
127 }
128 
129 NumFormatListBox::NumFormatListBox(std::unique_ptr<weld::ComboBox> xControl)
130  : mxControl(std::move(xControl))
131 {
132  Init();
133 }
134 
135 SwNumFormatTreeView::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)
146  eCurLanguage = pView->GetWrtShell().GetCurLang();
147  else
148  eCurLanguage = SvtSysLocale().GetLanguageTag().getLanguageType();
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  (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;
184  NfIndexTableOffset eOffsetEnd = 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(
255  NF_NUMBER_SYSTEM, eCurLanguage );
256  const sal_uInt32 nSysShortDateFormat = pFormatter->GetFormatIndex(
257  NF_DATE_SYSTEM_SHORT, eCurLanguage );
258  const sal_uInt32 nSysLongDateFormat = pFormatter->GetFormatIndex(
259  NF_DATE_SYSTEM_LONG, eCurLanguage );
260 
261  for( tools::Long nIndex = eOffsetStart; nIndex <= eOffsetEnd; ++nIndex )
262  {
263  const sal_uInt32 nFormat = pFormatter->GetFormatIndex(
264  static_cast<NfIndexTableOffset>(nIndex), eCurLanguage );
265  pFormat = pFormatter->GetEntry( nFormat );
266 
267  if( nFormat == pFormatter->GetFormatIndex( NF_NUMBER_STANDARD,
268  eCurLanguage )
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, eCurLanguage ) )
287  nStdEntry = i;
288  ++i;
289  }
290  }
291 
292  append_text(SwResId(STR_DEFINE_NUMBERFORMAT));
293 
295 
296  nCurrFormatType = nFormatType;
298 
299 }
300 
301 void SwNumFormatBase::SetDefFormat(const sal_uInt32 nDefaultFormat)
302 {
303  if (nDefaultFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
304  {
305  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 
318  SetFormatType(nType);
319 
320  sal_uInt32 nFormat = pFormatter->GetFormatForLanguageIfBuiltIn(nDefaultFormat, 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  nStdEntry = i;
328  nDefFormat = GetFormat();
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;
347  while (get_id(nPos).toUInt32() == NUMBERFORMAT_ENTRY_NOT_FOUND)
348  nPos++;
349 
350  if ( lcl_isSystemFormat(nDefaultFormat, pFormatter, 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));
357  set_active(nPos);
358  nDefFormat = GetFormat();
359 }
360 
361 sal_uInt32 NumFormatListBox::GetFormat() const
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 
383  SfxItemSet aCoreSet(
384  rSh.GetAttrPool(),
385  svl::Items<
386  SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_INFO,
387  SID_ATTR_NUMBERFORMAT_ONE_AREA, SID_ATTR_NUMBERFORMAT_ONE_AREA,
388  SID_ATTR_NUMBERFORMAT_NOLANGUAGE,
389  SID_ATTR_NUMBERFORMAT_NOLANGUAGE,
390  SID_ATTR_NUMBERFORMAT_ADD_AUTO,
391  SID_ATTR_NUMBERFORMAT_ADD_AUTO>);
392 
394 
395  sal_uInt32 nFormat = pFormatter->GetStandardFormat( nCurrFormatType, eCurLanguage);
396  aCoreSet.Put( SfxUInt32Item( SID_ATTR_NUMBERFORMAT_VALUE, nFormat ));
397 
398  aCoreSet.Put( SvxNumberInfoItem( pFormatter, fValue,
399  SID_ATTR_NUMBERFORMAT_INFO ) );
400 
401  if( (SvNumFormatType::DATE | SvNumFormatType::TIME) & nCurrFormatType )
402  aCoreSet.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ONE_AREA, bOneArea));
403 
404  aCoreSet.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_NOLANGUAGE, !bShowLanguageControl));
405  aCoreSet.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ADD_AUTO, bUseAutomaticLanguage));
406 
407  // force deselect to break mouse lock on selected entry
408  set_active(-1);
409 
412 
413  if (RET_OK == pDlg->Execute())
414  {
415  const SfxPoolItem* pItem = pView->GetDocShell()->
416  GetItem( SID_ATTR_NUMBERFORMAT_INFO );
417 
418  if( pItem )
419  {
420  for ( sal_uInt32 key : static_cast<const SvxNumberInfoItem*>(pItem)->GetDelFormats() )
421  pFormatter->DeleteEntry( key );
422  }
423 
424  const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
425  if( SfxItemState::SET == pOutSet->GetItemState(
426  SID_ATTR_NUMBERFORMAT_VALUE, false, &pItem ))
427  {
428  sal_uInt32 nNumberFormat = static_cast<const SfxUInt32Item*>(pItem)->GetValue();
429  // oj #105473# change order of calls
430  const SvNumberformat* pFormat = pFormatter->GetEntry(nNumberFormat);
431  if( pFormat )
432  eCurLanguage = pFormat->GetLanguage();
433  // SetDefFormat uses eCurLanguage to look for if this format already in the list
434  SetDefFormat(nNumberFormat);
435  }
436  if( bShowLanguageControl && SfxItemState::SET == pOutSet->GetItemState(
437  SID_ATTR_NUMBERFORMAT_ADD_AUTO, false, &pItem ))
438  {
439  bUseAutomaticLanguage = static_cast<const SfxBoolItem*>(pItem)->GetValue();
440  }
441  }
442  else
443  SetDefFormat(nFormat);
444 
445 }
446 
448 {
449  CallSelectHdl();
450 }
451 
453 {
454  CallSelectHdl();
455 }
456 
458 {
460  nCurrFormatType = SvNumFormatType::ALL;
461 }
462 
464 {
465  mxControl->clear();
467 }
468 
470 {
471  mxControl->clear();
473 }
474 
475 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt32 GetFormatForLanguageIfBuiltIn(sal_uInt32 nFormat, LanguageType eLnge=LANGUAGE_DONTKNOW)
sal_Int32 nStdEntry
Definition: numfmtlb.hxx:31
virtual void Init() override
Definition: numfmtlb.cxx:161
sal_Int32 nIndex
std::unique_ptr< weld::ComboBox > mxControl
Definition: numfmtlb.hxx:75
SwView * GetActiveView()
Definition: swmodul1.cxx:116
static constexpr auto Items
NF_CURRENCY_START
NF_NUMBER_END
sal_uInt32 nDefFormat
Definition: numfmtlb.hxx:32
std::string GetValue
virtual void insert_text(int nPos, const OUString &rText)=0
NF_INDEX_TABLE_ENTRIES
sal_uInt32 GetFormatIndex(NfIndexTableOffset, LanguageType eLnge=LANGUAGE_DONTKNOW)
NF_SCIENTIFIC_START
LanguageType getLanguageType(bool bResolveSystem=true) const
NF_PERCENT_END
const SfxPoolItem * GetItem(const SwTextAttr &rAttr, sal_uInt16 nWhich)
Extracts pool item of type nWhich from rAttr.
Definition: atrstck.cxx:156
long Long
static SAL_DLLPRIVATE double GetDefValue(const SvNumFormatType nFormatType)
Definition: numfmtlb.cxx:78
virtual void clear()
Definition: numfmtlb.cxx:457
SvNumFormatType GetType(sal_uInt32 nFIndex) const
void CallSelectHdl()
Definition: numfmtlb.cxx:371
virtual sal_uInt32 GetFormat() const =0
NF_FRACTION_END
virtual weld::Widget & get_widget() const =0
const OUString & GetFormatstring() const
virtual int get_count() const =0
virtual void set_active(int nPos)=0
SwWrtShell & GetWrtShell() const
Definition: view.hxx:413
LanguageType GetCurLang() const
Definition: edattr.cxx:818
Used by the UI to modify the document model.
Definition: wrtsh.hxx:93
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:165
NF_NUMBER_STANDARD
virtual sal_uInt32 GetFormat() const override
Definition: numfmtlb.cxx:361
constexpr sal_uInt32 NUMBERFORMAT_ENTRY_NOT_FOUND
bool mbCurrFormatTypeNeedsInit
Definition: numfmtlb.hxx:36
virtual OUString get_id(int nPos) const =0
void SetDefFormat(const sal_uInt32 nDefFormat)
Definition: numfmtlb.cxx:301
int nCount
virtual sal_uInt32 GetFormat() const override
Definition: numfmtlb.cxx:366
NfIndexTableOffset
NF_CURRENCY_END
virtual void append(const OUString &rId, const OUString &rText)=0
NF_DATE_END
SvNumFormatType nCurrFormatType
Definition: numfmtlb.hxx:33
NF_PERCENT_START
std::unique_ptr< weld::TreeView > mxControl
Definition: numfmtlb.hxx:106
const SfxItemPool & GetAttrPool() const
Definition: viewsh.hxx:612
NF_BOOLEAN
void SetFormatType(const SvNumFormatType nFormatType)
Definition: numfmtlb.cxx:168
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
int i
NF_TIME_START
virtual void Init() override
Definition: numfmtlb.cxx:154
const o3tl::enumarray< SvxNumValCategory, double > fSvxNumValConst
bool bShowLanguageControl
Definition: numfmtlb.hxx:37
virtual VclPtr< SfxAbstractDialog > CreateNumFormatDialog(weld::Widget *pParent, const SfxItemSet &rAttr)=0
NF_SCIENTIFIC_END
NF_TEXT
SvNumFormatType
static SwAbstractDialogFactory * Create()
Definition: swabstdlg.cxx:36
void DeleteEntry(sal_uInt32 nKey)
virtual void append_text(const OUString &rText)=0
NumFormatListBox(std::unique_ptr< weld::ComboBox > xControl)
Definition: numfmtlb.cxx:129
SwDocShell * GetDocShell()
Definition: view.cxx:1127
NF_NUMBER_SYSTEM
virtual OUString get_text(int nPos) const =0
NF_TIME_END
NF_DATE_START
virtual void clear() override
Definition: numfmtlb.cxx:463
SwNumFormatTreeView(std::unique_ptr< weld::TreeView > xControl)
Definition: numfmtlb.cxx:135
NF_DATE_SYSTEM_LONG
const SvNumberformat * GetEntry(sal_uInt32 nKey) const
sal_uInt32 GetStandardFormat(SvNumFormatType eType, LanguageType eLnge=LANGUAGE_DONTKNOW)
NF_FRACTION_START
LanguageType GetAppLanguage()
Definition: init.cxx:723
RET_OK
virtual int get_active() const =0
NF_DATE_SYSTEM_SHORT
bool bUseAutomaticLanguage
Definition: numfmtlb.hxx:39
QPRO_FUNC_TYPE nType
const LanguageTag & GetLanguageTag() const
NF_NUMBER_START
SvxNumValCategory
IMPL_LINK_NOARG(NumFormatListBox, SelectHdl, weld::ComboBox &, void)
Definition: numfmtlb.cxx:447
virtual void Init()
Definition: numfmtlb.cxx:141
NF_NUMERIC_START
SvNumberFormatter * GetNumberFormatter()
Query NumberFormatter from document.
Definition: editsh.cxx:745
void GetOutputString(const double &fOutNumber, sal_uInt32 nFIndex, OUString &sOutString, const Color **ppColor, bool bUseStarFormat=false)
virtual void clear() override
Definition: numfmtlb.cxx:469
LanguageType GetLanguage() const
Definition: view.hxx:144
sal_uInt16 nPos
virtual void set_id(int nPos, const OUString &rId)=0