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/zformat.hxx>
22 #include <svl/eitem.hxx>
23 #include <svx/svxids.hrc>
24 #include <svx/numinf.hxx>
25 #include <svx/flagsdef.hxx>
26 #include <svl/itemset.hxx>
27 #include <docsh.hxx>
28 #include <swtypes.hxx>
29 #include <swmodule.hxx>
30 #include <view.hxx>
31 #include <wrtsh.hxx>
32 #include <numfmtlb.hxx>
33 #include <strings.hrc>
34 #include <swabstdlg.hxx>
35 #include <memory>
36 
37 using namespace ::com::sun::star::uno;
38 using namespace ::com::sun::star::lang;
39 
46 namespace
47 {
48 
49 bool lcl_isSystemFormat(sal_uInt32 nDefaultFormat, SvNumberFormatter* pFormatter, LanguageType eCurLanguage)
50 {
51  const sal_uInt32 nSysNumFormat = pFormatter->GetFormatIndex(NF_NUMBER_SYSTEM, eCurLanguage);
52  if (nDefaultFormat == nSysNumFormat)
53  return true;
54  const sal_uInt32 nSysShortDateFormat = pFormatter->GetFormatIndex(NF_DATE_SYSTEM_SHORT, eCurLanguage);
55  if (nDefaultFormat == nSysShortDateFormat)
56  return true;
57  const sal_uInt32 nSysLongDateFormat = pFormatter->GetFormatIndex(NF_DATE_SYSTEM_LONG, eCurLanguage);
58  if (nDefaultFormat == nSysLongDateFormat)
59  return true;
60 
61  if ( eCurLanguage != GetAppLanguage() )
62  return false;
63 
64  if (nDefaultFormat == pFormatter->GetFormatForLanguageIfBuiltIn(nSysNumFormat, LANGUAGE_SYSTEM))
65  return true;
66  if (nDefaultFormat == pFormatter->GetFormatForLanguageIfBuiltIn(nSysShortDateFormat, LANGUAGE_SYSTEM))
67  return true;
68  if (nDefaultFormat == pFormatter->GetFormatForLanguageIfBuiltIn(nSysLongDateFormat, LANGUAGE_SYSTEM))
69  return true;
70 
71  return false;
72 }
73 
74 }
75 
77 {
78  SvxNumValCategory nDefValue = SvxNumValCategory::Standard;
79 
80  switch (nFormatType)
81  {
82  case SvNumFormatType::DATE:
83  case SvNumFormatType::DATE|SvNumFormatType::TIME:
84  nDefValue = SvxNumValCategory::Date;
85  break;
86 
87  case SvNumFormatType::TIME:
88  nDefValue = SvxNumValCategory::Time;
89  break;
90 
91  case SvNumFormatType::TEXT:
92  case SvNumFormatType::UNDEFINED:
93  nDefValue = SvxNumValCategory::Standard;
94  break;
95 
96  case SvNumFormatType::CURRENCY:
97  nDefValue = SvxNumValCategory::Currency;
98  break;
99 
100  case SvNumFormatType::PERCENT:
101  nDefValue = SvxNumValCategory::Percent;
102  break;
103 
104  case SvNumFormatType::LOGICAL:
105  nDefValue = SvxNumValCategory::Boolean;
106  break;
107 
108  default:
109  nDefValue = SvxNumValCategory::Standard;
110  break;
111  }
112 
113  return fSvxNumValConst[nDefValue];
114 }
115 
117  : nStdEntry(0)
118  , nDefFormat(0)
119  , nCurrFormatType(SvNumFormatType::ALL)
120  , bOneArea(false)
121  , mbCurrFormatTypeNeedsInit(true)
122  , bShowLanguageControl(false)
123  , bUseAutomaticLanguage(true)
124 {
125 }
126 
127 NumFormatListBox::NumFormatListBox(std::unique_ptr<weld::ComboBox> xControl)
128  : mxControl(std::move(xControl))
129 {
130  Init();
131 }
132 
133 SwNumFormatTreeView::SwNumFormatTreeView(std::unique_ptr<weld::TreeView> xControl)
134  : mxControl(std::move(xControl))
135 {
136  Init();
137 }
138 
140 {
141  SwView *pView = GetActiveView();
142 
143  if (pView)
144  eCurLanguage = pView->GetWrtShell().GetCurLang();
145  else
146  eCurLanguage = SvtSysLocale().GetLanguageTag().getLanguageType();
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  (nCurrFormatType & nFormatType)) // there are mixed formats, like for example DateTime
170  return;
171 
172  SwView *pView = GetActiveView();
173  OSL_ENSURE(pView, "no view found");
174  if(!pView)
175  return;
176  SwWrtShell &rSh = pView->GetWrtShell();
177  SvNumberFormatter* pFormatter = rSh.GetNumberFormatter();
178 
179  clear(); // Remove all entries from the Listbox
180 
181  NfIndexTableOffset eOffsetStart = NF_NUMBER_START;
182  NfIndexTableOffset eOffsetEnd = NF_NUMBER_START;
183 
184  switch( nFormatType )
185  {
186  case SvNumFormatType::NUMBER:
187  eOffsetStart=NF_NUMBER_START;
188  eOffsetEnd=NF_NUMBER_END;
189  break;
190 
191  case SvNumFormatType::PERCENT:
192  eOffsetStart=NF_PERCENT_START;
193  eOffsetEnd=NF_PERCENT_END;
194  break;
195 
196  case SvNumFormatType::CURRENCY:
197  eOffsetStart=NF_CURRENCY_START;
198  eOffsetEnd=NF_CURRENCY_END;
199  break;
200 
201  case SvNumFormatType::DATETIME:
202  eOffsetStart=NF_DATE_START;
203  eOffsetEnd=NF_TIME_END;
204  break;
205 
206  case SvNumFormatType::DATE:
207  eOffsetStart=NF_DATE_START;
208  eOffsetEnd=NF_DATE_END;
209  break;
210 
211  case SvNumFormatType::TIME:
212  eOffsetStart=NF_TIME_START;
213  eOffsetEnd=NF_TIME_END;
214  break;
215 
216  case SvNumFormatType::SCIENTIFIC:
217  eOffsetStart=NF_SCIENTIFIC_START;
218  eOffsetEnd=NF_SCIENTIFIC_END;
219  break;
220 
221  case SvNumFormatType::FRACTION:
222  eOffsetStart=NF_FRACTION_START;
223  eOffsetEnd=NF_FRACTION_END;
224  break;
225 
226  case SvNumFormatType::LOGICAL:
227  eOffsetStart=NF_BOOLEAN;
228  eOffsetEnd=NF_BOOLEAN;
229  break;
230 
231  case SvNumFormatType::TEXT:
232  eOffsetStart=NF_TEXT;
233  eOffsetEnd=NF_TEXT;
234  break;
235 
236  case SvNumFormatType::ALL:
237  eOffsetStart=NF_NUMERIC_START;
238  eOffsetEnd = NfIndexTableOffset( NF_INDEX_TABLE_ENTRIES - 1 );
239  break;
240 
241  default:
242  OSL_FAIL("what a format?");
243  break;
244  }
245 
246  const SvNumberformat* pFormat;
247  sal_Int32 i = 0;
248  const Color* pCol;
249  double fVal = SwNumFormatBase::GetDefValue(nFormatType);
250  OUString sValue;
251 
252  const sal_uInt32 nSysNumFormat = pFormatter->GetFormatIndex(
253  NF_NUMBER_SYSTEM, eCurLanguage );
254  const sal_uInt32 nSysShortDateFormat = pFormatter->GetFormatIndex(
255  NF_DATE_SYSTEM_SHORT, eCurLanguage );
256  const sal_uInt32 nSysLongDateFormat = pFormatter->GetFormatIndex(
257  NF_DATE_SYSTEM_LONG, eCurLanguage );
258 
259  for( tools::Long nIndex = eOffsetStart; nIndex <= eOffsetEnd; ++nIndex )
260  {
261  const sal_uInt32 nFormat = pFormatter->GetFormatIndex(
262  static_cast<NfIndexTableOffset>(nIndex), eCurLanguage );
263  pFormat = pFormatter->GetEntry( nFormat );
264 
265  if( nFormat == pFormatter->GetFormatIndex( NF_NUMBER_STANDARD,
266  eCurLanguage )
267  || const_cast<SvNumberformat*>(pFormat)->GetOutputString( fVal, sValue, &pCol )
268  || nFormatType == SvNumFormatType::UNDEFINED )
269  {
270  sValue = pFormat->GetFormatstring();
271  }
272  else if( nFormatType == SvNumFormatType::TEXT )
273  {
274  pFormatter->GetOutputString( "\"ABC\"", nFormat, sValue, &pCol);
275  }
276 
277  if (nFormat != nSysNumFormat &&
278  nFormat != nSysShortDateFormat &&
279  nFormat != nSysLongDateFormat)
280  {
281  append(OUString::number(nFormat), sValue);
282 
283  if( nFormat == pFormatter->GetStandardFormat(
284  nFormatType, eCurLanguage ) )
285  nStdEntry = i;
286  ++i;
287  }
288  }
289 
290  append_text(SwResId(STR_DEFINE_NUMBERFORMAT));
291 
293 
294  nCurrFormatType = nFormatType;
296 
297 }
298 
299 void SwNumFormatBase::SetDefFormat(const sal_uInt32 nDefaultFormat)
300 {
301  if (nDefaultFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
302  {
303  nDefFormat = nDefaultFormat;
304  return;
305  }
306 
307  SwView *pView = GetActiveView();
308  OSL_ENSURE(pView, "no view found");
309  if(!pView)
310  return;
311  SwWrtShell &rSh = pView->GetWrtShell();
312  SvNumberFormatter* pFormatter = rSh.GetNumberFormatter();
313 
314  SvNumFormatType nType = pFormatter->GetType(nDefaultFormat);
315 
316  SetFormatType(nType);
317 
318  sal_uInt32 nFormat = pFormatter->GetFormatForLanguageIfBuiltIn(nDefaultFormat, eCurLanguage);
319 
320  for (sal_Int32 i = 0, nCount = get_count(); i < nCount; ++i)
321  {
322  if (nFormat == get_id(i).toUInt32())
323  {
324  set_active(i);
325  nStdEntry = i;
326  nDefFormat = GetFormat();
327  return;
328  }
329  }
330 
331  // No entry found:
332  OUString sValue;
333  const Color* pCol = nullptr;
334 
335  if (nType == SvNumFormatType::TEXT)
336  {
337  pFormatter->GetOutputString("\"ABC\"", nDefaultFormat, sValue, &pCol);
338  }
339  else
340  {
341  pFormatter->GetOutputString(SwNumFormatBase::GetDefValue(nType), nDefaultFormat, sValue, &pCol);
342  }
343 
344  sal_Int32 nPos = 0;
345  while (get_id(nPos).toUInt32() == NUMBERFORMAT_ENTRY_NOT_FOUND)
346  nPos++;
347 
348  if ( lcl_isSystemFormat(nDefaultFormat, pFormatter, eCurLanguage) )
349  {
350  sValue += SwResId(RID_STR_SYSTEM);
351  }
352 
353  insert_text(nPos, sValue); // Insert as first numeric entry
354  set_id(nPos, OUString::number(nDefaultFormat));
355  set_active(nPos);
356  nDefFormat = GetFormat();
357 }
358 
359 sal_uInt32 NumFormatListBox::GetFormat() const
360 {
361  return mxControl->get_active_id().toUInt32();
362 }
363 
365 {
366  return mxControl->get_selected_id().toUInt32();
367 }
368 
370 {
371  const sal_Int32 nPos = get_active();
372  OUString sDefine(SwResId( STR_DEFINE_NUMBERFORMAT ));
373  SwView *pView = GetActiveView();
374 
375  if (!pView || nPos != get_count() - 1 || get_text(nPos) != sDefine)
376  return;
377 
378  SwWrtShell &rSh = pView->GetWrtShell();
379  SvNumberFormatter* pFormatter = rSh.GetNumberFormatter();
380 
381  SfxItemSet aCoreSet(
382  rSh.GetAttrPool(),
383  svl::Items<
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>{});
390 
392 
393  sal_uInt32 nFormat = pFormatter->GetStandardFormat( nCurrFormatType, 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) & nCurrFormatType )
400  aCoreSet.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ONE_AREA, bOneArea));
401 
402  aCoreSet.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_NOLANGUAGE, !bShowLanguageControl));
403  aCoreSet.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ADD_AUTO, 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 SfxPoolItem* pItem = pView->GetDocShell()->
414  GetItem( SID_ATTR_NUMBERFORMAT_INFO );
415 
416  if( pItem )
417  {
418  for ( sal_uInt32 key : static_cast<const SvxNumberInfoItem*>(pItem)->GetDelFormats() )
419  pFormatter->DeleteEntry( key );
420  }
421 
422  const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
423  if( SfxItemState::SET == pOutSet->GetItemState(
424  SID_ATTR_NUMBERFORMAT_VALUE, false, &pItem ))
425  {
426  sal_uInt32 nNumberFormat = static_cast<const SfxUInt32Item*>(pItem)->GetValue();
427  // oj #105473# change order of calls
428  const SvNumberformat* pFormat = pFormatter->GetEntry(nNumberFormat);
429  if( pFormat )
430  eCurLanguage = pFormat->GetLanguage();
431  // SetDefFormat uses eCurLanguage to look for if this format already in the list
432  SetDefFormat(nNumberFormat);
433  }
434  if( bShowLanguageControl && SfxItemState::SET == pOutSet->GetItemState(
435  SID_ATTR_NUMBERFORMAT_ADD_AUTO, false, &pItem ))
436  {
437  bUseAutomaticLanguage = static_cast<const SfxBoolItem*>(pItem)->GetValue();
438  }
439  }
440  else
441  SetDefFormat(nFormat);
442 
443 }
444 
446 {
447  CallSelectHdl();
448 }
449 
451 {
452  CallSelectHdl();
453 }
454 
456 {
458  nCurrFormatType = SvNumFormatType::ALL;
459 }
460 
462 {
463  mxControl->clear();
465 }
466 
468 {
469  mxControl->clear();
471 }
472 
473 /* 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:159
sal_Int32 nIndex
std::unique_ptr< weld::ComboBox > mxControl
Definition: numfmtlb.hxx:75
SwView * GetActiveView()
Definition: swmodul1.cxx:116
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:157
long Long
static SAL_DLLPRIVATE double GetDefValue(const SvNumFormatType nFormatType)
Definition: numfmtlb.cxx:76
virtual void clear()
Definition: numfmtlb.cxx:455
SvNumFormatType GetType(sal_uInt32 nFIndex) const
void CallSelectHdl()
Definition: numfmtlb.cxx:369
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:399
LanguageType GetCurLang() const
Definition: edattr.cxx:814
Used by the UI to modify the document model.
Definition: wrtsh.hxx:90
NF_NUMBER_STANDARD
virtual sal_uInt32 GetFormat() const override
Definition: numfmtlb.cxx:359
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:299
int nCount
virtual sal_uInt32 GetFormat() const override
Definition: numfmtlb.cxx:364
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:166
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:152
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
OUString SwResId(const char *pId)
Definition: swmodule.cxx:165
void DeleteEntry(sal_uInt32 nKey)
virtual void append_text(const OUString &rText)=0
NumFormatListBox(std::unique_ptr< weld::ComboBox > xControl)
Definition: numfmtlb.cxx:127
SwDocShell * GetDocShell()
Definition: view.cxx:1109
NF_NUMBER_SYSTEM
virtual OUString get_text(int nPos) const =0
NF_TIME_END
NF_DATE_START
virtual void clear() override
Definition: numfmtlb.cxx:461
SwNumFormatTreeView(std::unique_ptr< weld::TreeView > xControl)
Definition: numfmtlb.cxx:133
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:728
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:445
virtual void Init()
Definition: numfmtlb.cxx:139
NF_NUMERIC_START
SvNumberFormatter * GetNumberFormatter()
Query NumberFormatter from document.
Definition: editsh.cxx:744
void GetOutputString(const double &fOutNumber, sal_uInt32 nFIndex, OUString &sOutString, const Color **ppColor, bool bUseStarFormat=false)
virtual void clear() override
Definition: numfmtlb.cxx:467
LanguageType GetLanguage() const
Definition: view.hxx:144
sal_uInt16 nPos
virtual void set_id(int nPos, const OUString &rId)=0