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