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