Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / uibase / utlui / numfmtlb.cxx
blob4dffed15d2194b131909a4337c0449bb47efe403
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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>
39 using namespace ::com::sun::star::uno;
40 using namespace ::com::sun::star::lang;
42 /**
43 * Description:
44 * nFormatType: Display the formats of this Type
45 * nDefaultFormat: Select this format and possibly insert it
48 namespace
51 bool lcl_isSystemFormat(sal_uInt32 nDefaultFormat, SvNumberFormatter* pFormatter, LanguageType eCurLanguage)
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;
63 if ( eCurLanguage != GetAppLanguage() )
64 return false;
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;
73 return false;
78 double SwNumFormatBase::GetDefValue(const SvNumFormatType nFormatType)
80 SvxNumValCategory nDefValue = SvxNumValCategory::Standard;
82 switch (nFormatType)
84 case SvNumFormatType::DATE:
85 case SvNumFormatType::DATE|SvNumFormatType::TIME:
86 nDefValue = SvxNumValCategory::Date;
87 break;
89 case SvNumFormatType::TIME:
90 nDefValue = SvxNumValCategory::Time;
91 break;
93 case SvNumFormatType::TEXT:
94 case SvNumFormatType::UNDEFINED:
95 nDefValue = SvxNumValCategory::Standard;
96 break;
98 case SvNumFormatType::CURRENCY:
99 nDefValue = SvxNumValCategory::Currency;
100 break;
102 case SvNumFormatType::PERCENT:
103 nDefValue = SvxNumValCategory::Percent;
104 break;
106 case SvNumFormatType::LOGICAL:
107 nDefValue = SvxNumValCategory::Boolean;
108 break;
110 default:
111 nDefValue = SvxNumValCategory::Standard;
112 break;
115 return fSvxNumValConst[nDefValue];
118 SwNumFormatBase::SwNumFormatBase()
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)
129 NumFormatListBox::NumFormatListBox(std::unique_ptr<weld::ComboBox> xControl)
130 : mxControl(std::move(xControl))
132 Init();
135 SwNumFormatTreeView::SwNumFormatTreeView(std::unique_ptr<weld::TreeView> xControl)
136 : mxControl(std::move(xControl))
138 Init();
141 void SwNumFormatBase::Init()
143 if (SwView *pView = GetActiveView())
144 m_eCurLanguage = pView->GetWrtShell().GetCurLang();
145 else
146 m_eCurLanguage = SvtSysLocale().GetLanguageTag().getLanguageType();
148 SetFormatType(SvNumFormatType::NUMBER);
149 SetDefFormat(m_nDefFormat);
152 void NumFormatListBox::Init()
154 SwNumFormatBase::Init();
156 mxControl->connect_changed(LINK(this, NumFormatListBox, SelectHdl));
159 void SwNumFormatTreeView::Init()
161 SwNumFormatBase::Init();
163 mxControl->connect_changed(LINK(this, SwNumFormatTreeView, SelectHdl));
166 void SwNumFormatBase::SetFormatType(const SvNumFormatType nFormatType)
168 if (!mbCurrFormatTypeNeedsInit &&
169 (m_nCurrFormatType & nFormatType)) // there are mixed formats, like for example DateTime
170 return;
172 SwView *pView = GetActiveView();
173 if(!pView)
174 return;
175 SwWrtShell &rSh = pView->GetWrtShell();
176 SvNumberFormatter* pFormatter = rSh.GetNumberFormatter();
178 clear(); // Remove all entries from the Listbox
180 NfIndexTableOffset eOffsetStart = NF_NUMBER_START;
181 NfIndexTableOffset eOffsetEnd = NF_NUMBER_START;
183 switch( nFormatType )
185 case SvNumFormatType::NUMBER:
186 eOffsetStart=NF_NUMBER_START;
187 eOffsetEnd=NF_NUMBER_END;
188 break;
190 case SvNumFormatType::PERCENT:
191 eOffsetStart=NF_PERCENT_START;
192 eOffsetEnd=NF_PERCENT_END;
193 break;
195 case SvNumFormatType::CURRENCY:
196 eOffsetStart=NF_CURRENCY_START;
197 eOffsetEnd=NF_CURRENCY_END;
198 break;
200 case SvNumFormatType::DATETIME:
201 eOffsetStart=NF_DATE_START;
202 eOffsetEnd=NF_TIME_END;
203 break;
205 case SvNumFormatType::DATE:
206 eOffsetStart=NF_DATE_START;
207 eOffsetEnd=NF_DATE_END;
208 break;
210 case SvNumFormatType::TIME:
211 eOffsetStart=NF_TIME_START;
212 eOffsetEnd=NF_TIME_END;
213 break;
215 case SvNumFormatType::SCIENTIFIC:
216 eOffsetStart=NF_SCIENTIFIC_START;
217 eOffsetEnd=NF_SCIENTIFIC_END;
218 break;
220 case SvNumFormatType::FRACTION:
221 eOffsetStart=NF_FRACTION_START;
222 eOffsetEnd=NF_FRACTION_END;
223 break;
225 case SvNumFormatType::LOGICAL:
226 eOffsetStart=NF_BOOLEAN;
227 eOffsetEnd=NF_BOOLEAN;
228 break;
230 case SvNumFormatType::TEXT:
231 eOffsetStart=NF_TEXT;
232 eOffsetEnd=NF_TEXT;
233 break;
235 case SvNumFormatType::ALL:
236 eOffsetStart=NF_NUMERIC_START;
237 eOffsetEnd = NfIndexTableOffset( NF_INDEX_TABLE_ENTRIES - 1 );
238 break;
240 default:
241 OSL_FAIL("what a format?");
242 break;
245 const SvNumberformat* pFormat;
246 sal_Int32 i = 0;
247 const Color* pCol;
248 double fVal = SwNumFormatBase::GetDefValue(nFormatType);
249 OUString sValue;
251 const sal_uInt32 nSysNumFormat = pFormatter->GetFormatIndex(
252 NF_NUMBER_SYSTEM, m_eCurLanguage );
253 const sal_uInt32 nSysShortDateFormat = pFormatter->GetFormatIndex(
254 NF_DATE_SYSTEM_SHORT, m_eCurLanguage );
255 const sal_uInt32 nSysLongDateFormat = pFormatter->GetFormatIndex(
256 NF_DATE_SYSTEM_LONG, m_eCurLanguage );
258 for( tools::Long nIndex = eOffsetStart; nIndex <= eOffsetEnd; ++nIndex )
260 const sal_uInt32 nFormat = pFormatter->GetFormatIndex(
261 static_cast<NfIndexTableOffset>(nIndex), m_eCurLanguage );
262 pFormat = pFormatter->GetEntry( nFormat );
264 if( nFormat == pFormatter->GetFormatIndex( NF_NUMBER_STANDARD,
265 m_eCurLanguage )
266 || const_cast<SvNumberformat*>(pFormat)->GetOutputString( fVal, sValue, &pCol )
267 || nFormatType == SvNumFormatType::UNDEFINED )
269 sValue = pFormat->GetFormatstring();
271 else if( nFormatType == SvNumFormatType::TEXT )
273 pFormatter->GetOutputString( "\"ABC\"", nFormat, sValue, &pCol);
276 if (nFormat != nSysNumFormat &&
277 nFormat != nSysShortDateFormat &&
278 nFormat != nSysLongDateFormat)
280 append(OUString::number(nFormat), sValue);
282 if( nFormat == pFormatter->GetStandardFormat(
283 nFormatType, m_eCurLanguage ) )
284 m_nStdEntry = i;
285 ++i;
289 append_text(SwResId(STR_DEFINE_NUMBERFORMAT));
291 set_active(m_nStdEntry);
293 m_nCurrFormatType = nFormatType;
294 mbCurrFormatTypeNeedsInit = false;
298 void SwNumFormatBase::SetDefFormat(const sal_uInt32 nDefaultFormat)
300 if (nDefaultFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
302 m_nDefFormat = nDefaultFormat;
303 return;
306 SwView *pView = GetActiveView();
307 if(!pView)
308 return;
309 SwWrtShell &rSh = pView->GetWrtShell();
310 SvNumberFormatter* pFormatter = rSh.GetNumberFormatter();
312 SvNumFormatType nType = pFormatter->GetType(nDefaultFormat);
314 SetFormatType(nType);
316 sal_uInt32 nFormat = pFormatter->GetFormatForLanguageIfBuiltIn(nDefaultFormat, m_eCurLanguage);
318 for (sal_Int32 i = 0, nCount = get_count(); i < nCount; ++i)
320 if (nFormat == get_id(i).toUInt32())
322 set_active(i);
323 m_nStdEntry = i;
324 m_nDefFormat = GetFormat();
325 return;
329 // No entry found:
330 OUString sValue;
331 const Color* pCol = nullptr;
333 if (nType == SvNumFormatType::TEXT)
335 pFormatter->GetOutputString("\"ABC\"", nDefaultFormat, sValue, &pCol);
337 else
339 pFormatter->GetOutputString(SwNumFormatBase::GetDefValue(nType), nDefaultFormat, sValue, &pCol);
342 sal_Int32 nPos = 0;
343 while (get_id(nPos).toUInt32() == NUMBERFORMAT_ENTRY_NOT_FOUND)
344 nPos++;
346 if ( lcl_isSystemFormat(nDefaultFormat, pFormatter, m_eCurLanguage) )
348 sValue += SwResId(RID_STR_SYSTEM);
351 insert_text(nPos, sValue); // Insert as first numeric entry
352 set_id(nPos, OUString::number(nDefaultFormat));
353 set_active(nPos);
354 m_nDefFormat = GetFormat();
357 sal_uInt32 NumFormatListBox::GetFormat() const
359 return mxControl->get_active_id().toUInt32();
362 sal_uInt32 SwNumFormatTreeView::GetFormat() const
364 return mxControl->get_selected_id().toUInt32();
367 void SwNumFormatBase::CallSelectHdl()
369 const sal_Int32 nPos = get_active();
370 OUString sDefine(SwResId( STR_DEFINE_NUMBERFORMAT ));
371 SwView *pView = GetActiveView();
373 if (!pView || nPos != get_count() - 1 || get_text(nPos) != sDefine)
374 return;
376 SwWrtShell &rSh = pView->GetWrtShell();
377 SvNumberFormatter* pFormatter = rSh.GetNumberFormatter();
379 SfxItemSetFixed<
380 SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_INFO,
381 SID_ATTR_NUMBERFORMAT_ONE_AREA, SID_ATTR_NUMBERFORMAT_ONE_AREA,
382 SID_ATTR_NUMBERFORMAT_NOLANGUAGE,
383 SID_ATTR_NUMBERFORMAT_NOLANGUAGE,
384 SID_ATTR_NUMBERFORMAT_ADD_AUTO,
385 SID_ATTR_NUMBERFORMAT_ADD_AUTO> aCoreSet( rSh.GetAttrPool() );
387 double fValue = SwNumFormatBase::GetDefValue(m_nCurrFormatType);
389 sal_uInt32 nFormat = pFormatter->GetStandardFormat( m_nCurrFormatType, m_eCurLanguage);
390 aCoreSet.Put( SfxUInt32Item( SID_ATTR_NUMBERFORMAT_VALUE, nFormat ));
392 aCoreSet.Put( SvxNumberInfoItem( pFormatter, fValue,
393 SID_ATTR_NUMBERFORMAT_INFO ) );
395 if( (SvNumFormatType::DATE | SvNumFormatType::TIME) & m_nCurrFormatType )
396 aCoreSet.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ONE_AREA, m_bOneArea));
398 aCoreSet.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_NOLANGUAGE, !m_bShowLanguageControl));
399 aCoreSet.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ADD_AUTO, m_bUseAutomaticLanguage));
401 // force deselect to break mouse lock on selected entry
402 set_active(-1);
404 SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
405 ScopedVclPtr<SfxAbstractDialog> pDlg(pFact->CreateNumFormatDialog(&get_widget(), aCoreSet));
407 if (RET_OK == pDlg->Execute())
409 const SvxNumberInfoItem* pFormatInfoItem = pView->GetDocShell()->
410 GetItem( SID_ATTR_NUMBERFORMAT_INFO );
412 if( pFormatInfoItem )
414 for ( sal_uInt32 key : pFormatInfoItem->GetDelFormats() )
415 pFormatter->DeleteEntry( key );
418 const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
419 if( const SfxUInt32Item* pFormatValueItem = pOutSet->GetItemIfSet(
420 SID_ATTR_NUMBERFORMAT_VALUE, false ))
422 sal_uInt32 nNumberFormat = pFormatValueItem->GetValue();
423 // oj #105473# change order of calls
424 const SvNumberformat* pFormat = pFormatter->GetEntry(nNumberFormat);
425 if( pFormat )
426 m_eCurLanguage = pFormat->GetLanguage();
427 // SetDefFormat uses eCurLanguage to look for if this format already in the list
428 SetDefFormat(nNumberFormat);
430 const SfxBoolItem* pAddAutoItem;
431 if( m_bShowLanguageControl && (pAddAutoItem = pOutSet->GetItemIfSet(
432 SID_ATTR_NUMBERFORMAT_ADD_AUTO, false)))
434 m_bUseAutomaticLanguage = pAddAutoItem->GetValue();
437 else
438 SetDefFormat(nFormat);
442 IMPL_LINK_NOARG(NumFormatListBox, SelectHdl, weld::ComboBox&, void)
444 CallSelectHdl();
447 IMPL_LINK_NOARG(SwNumFormatTreeView, SelectHdl, weld::TreeView&, void)
449 CallSelectHdl();
452 void SwNumFormatBase::clear()
454 mbCurrFormatTypeNeedsInit = true;
455 m_nCurrFormatType = SvNumFormatType::ALL;
458 void NumFormatListBox::clear()
460 mxControl->clear();
461 SwNumFormatBase::clear();
464 void SwNumFormatTreeView::clear()
466 mxControl->clear();
467 SwNumFormatBase::clear();
470 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */