LibreOffice Module sc (master) 1
NumberFormatPropertyPanel.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
21#include <sc.hrc>
22#include <sfx2/bindings.hxx>
23#include <sfx2/dispatch.hxx>
24#include <svl/intitem.hxx>
25#include <svl/stritem.hxx>
26#include <svx/numfmtsh.hxx>
27#include <o3tl/string_view.hxx>
28#include <com/sun/star/lang/IllegalArgumentException.hpp>
29
30using namespace css;
31using namespace css::uno;
32
33namespace sc::sidebar {
34
36 weld::Widget* pParent,
37 const css::uno::Reference<css::frame::XFrame>& rxFrame,
38 SfxBindings* pBindings)
39 : PanelLayout(pParent,"NumberFormatPropertyPanel", "modules/scalc/ui/sidebarnumberformat.ui")
40 , mxLbCategory(m_xBuilder->weld_combo_box("numberformatcombobox"))
41 , mxTBCategory(m_xBuilder->weld_toolbar("numberformat"))
42 , mxCategoryDispatch(new ToolbarUnoDispatcher(*mxTBCategory, *m_xBuilder, rxFrame))
43 , mxFtDecimals(m_xBuilder->weld_label("decimalplaceslabel"))
44 , mxEdDecimals(m_xBuilder->weld_spin_button("decimalplaces"))
45 , mxFtDenominator(m_xBuilder->weld_label("denominatorplaceslabel"))
46 , mxEdDenominator(m_xBuilder->weld_spin_button("denominatorplaces"))
47 , mxFtLeadZeroes(m_xBuilder->weld_label("leadingzeroeslabel"))
48 , mxEdLeadZeroes(m_xBuilder->weld_spin_button("leadingzeroes"))
49 , mxBtnNegRed(m_xBuilder->weld_check_button("negativenumbersred"))
50 , mxBtnThousand(m_xBuilder->weld_check_button("thousandseparator"))
51 , mxBtnEngineering(m_xBuilder->weld_check_button("engineeringnotation"))
52 , maNumFormatControl(SID_NUMBER_TYPE_FORMAT, *pBindings, *this)
53 , maFormatControl(SID_NUMBER_FORMAT, *pBindings, *this)
54 , mnCategorySelected(0)
55 , mpBindings(pBindings)
56{
57 Initialize();
58}
59
61{
62 mxLbCategory.reset();
63 mxCategoryDispatch.reset();
64 mxTBCategory.reset();
65 mxFtDecimals.reset();
66 mxEdDecimals.reset();
67 mxFtDenominator.reset();
68 mxEdDenominator.reset();
69 mxFtLeadZeroes.reset();
70 mxEdLeadZeroes.reset();
71 mxBtnNegRed.reset();
72 mxBtnThousand.reset();
73 mxBtnEngineering.reset();
74
77}
78
80{
81 mxLbCategory->connect_changed( LINK(this, NumberFormatPropertyPanel, NumFormatSelectHdl) );
82 mxLbCategory->set_active(0);
83
84 Link<weld::SpinButton&,void> aLink = LINK(this, NumberFormatPropertyPanel, NumFormatValueHdl);
85
86 mxEdDecimals->connect_value_changed( aLink );
87 mxEdDenominator->connect_value_changed( aLink );
88 mxEdLeadZeroes->connect_value_changed( aLink );
89
90 mxBtnNegRed->connect_toggled( LINK(this, NumberFormatPropertyPanel, NumFormatValueClickHdl) );
91 mxBtnThousand->connect_toggled( LINK(this, NumberFormatPropertyPanel, NumFormatValueClickHdl) );
92 mxBtnEngineering->connect_toggled( LINK(this, NumberFormatPropertyPanel, NumFormatValueClickHdl) );
93}
94
95IMPL_LINK( NumberFormatPropertyPanel, NumFormatSelectHdl, weld::ComboBox&, rBox, void )
96{
97 const sal_Int32 nVal = rBox.get_active();
98 if( nVal != mnCategorySelected )
99 {
100 SfxUInt16Item aItem( SID_NUMBER_TYPE_FORMAT, nVal );
101 GetBindings()->GetDispatcher()->ExecuteList(SID_NUMBER_TYPE_FORMAT,
102 SfxCallMode::RECORD, { &aItem });
103 mnCategorySelected = nVal;
104 }
105}
106
108{
109 NumFormatValueHdl(*mxEdDecimals);
110}
111
113{
114 OUString aFormat;
115 OUString sBreak = ",";
116 bool bThousand = ( mxBtnThousand->get_visible() && mxBtnThousand->get_sensitive() && mxBtnThousand->get_active() )
117 || ( mxBtnEngineering->get_visible() && mxBtnEngineering->get_sensitive() && mxBtnEngineering->get_active() );
118 bool bNegRed = mxBtnNegRed->get_sensitive() && mxBtnNegRed->get_active();
119 sal_uInt16 nPrecision = (mxEdDecimals->get_sensitive() && mxEdDecimals->get_visible())
120 ? static_cast<sal_uInt16>(mxEdDecimals->get_value())
121 : (mxEdDenominator->get_sensitive() && mxEdDenominator->get_visible())
122 ? static_cast<sal_uInt16>(mxEdDenominator->get_value())
123 : sal_uInt16(0);
124 sal_uInt16 nLeadZeroes = (mxEdLeadZeroes->get_sensitive())
125 ? static_cast<sal_uInt16>(mxEdLeadZeroes->get_value())
126 : sal_uInt16(0);
127
128 OUString sThousand = OUString::number(static_cast<sal_Int32>(bThousand));
129 OUString sNegRed = OUString::number(static_cast<sal_Int32>(bNegRed));
130 OUString sPrecision = OUString::number(nPrecision);
131 OUString sLeadZeroes = OUString::number(nLeadZeroes);
132
133 aFormat += sThousand +
134 sBreak +
135 sNegRed +
136 sBreak +
137 sPrecision +
138 sBreak +
139 sLeadZeroes +
140 sBreak;
141
142 SfxStringItem aItem( SID_NUMBER_FORMAT, aFormat );
143 GetBindings()->GetDispatcher()->ExecuteList(SID_NUMBER_FORMAT,
144 SfxCallMode::RECORD, { &aItem });
145}
146
147std::unique_ptr<PanelLayout> NumberFormatPropertyPanel::Create (
148 weld::Widget* pParent,
149 const css::uno::Reference<css::frame::XFrame>& rxFrame,
150 SfxBindings* pBindings)
151{
152 if (pParent == nullptr)
153 throw lang::IllegalArgumentException("no parent Window given to NumberFormatPropertyPanel::Create", nullptr, 0);
154 if ( ! rxFrame.is())
155 throw lang::IllegalArgumentException("no XFrame given to NumberFormatPropertyPanel::Create", nullptr, 1);
156 if (pBindings == nullptr)
157 throw lang::IllegalArgumentException("no SfxBindings given to NumberFormatPropertyPanel::Create", nullptr, 2);
158
159 return std::make_unique<NumberFormatPropertyPanel>(pParent, rxFrame, pBindings);
160}
161
163 const vcl::EnumContext& rContext)
164{
165 if(maContext == rContext)
166 {
167 // Nothing to do.
168 return;
169 }
170
171 maContext = rContext;
172}
173
175 sal_uInt16 nSID,
176 SfxItemState eState,
177 const SfxPoolItem* pState)
178{
179 switch(nSID)
180 {
181 case SID_NUMBER_TYPE_FORMAT:
182 {
183 if( eState >= SfxItemState::DEFAULT)
184 {
185 const SfxUInt16Item* pItem = static_cast<const SfxUInt16Item*>(pState);
186 sal_uInt16 nVal = pItem->GetValue();
187 mnCategorySelected = nVal;
188 mxLbCategory->set_active(nVal);
189 // There is an offset between category list enum and listbox in side panel
190 SvxNumberFormatCategory nCategory = static_cast< SvxNumberFormatCategory >( nVal + 1 );
191 if (nCategory <= CAT_FRACTION && // General, Number, Percent, Currency, Time, Scientific, Fraction
192 nCategory != CAT_DATE ) // not Date
193 {
194 // For scientific, Thousand separator is replaced by Engineering notation
195 bool bIsScientific ( nCategory == CAT_SCIENTIFIC );
196 // For fraction, Decimal places is replaced by Denominator places
197 bool bIsFraction ( nCategory == CAT_FRACTION );
198 // For Time, Decimal places and NegRed available
199 bool bIsTime ( nCategory == CAT_TIME );
200 mxBtnThousand->set_visible( !bIsScientific );
201 mxBtnThousand->set_sensitive( !bIsScientific && !bIsTime );
202 mxBtnThousand->set_active(false);
203 mxBtnEngineering->set_visible(bIsScientific);
204 mxBtnEngineering->set_sensitive(bIsScientific);
205 mxBtnEngineering->set_active(false);
206 mxBtnNegRed->set_sensitive(true);
207 mxFtDenominator->set_visible(bIsFraction);
208 mxEdDenominator->set_visible(bIsFraction);
209 mxFtDenominator->set_sensitive(bIsFraction);
210 mxEdDenominator->set_sensitive(bIsFraction);
211 mxFtDecimals->set_visible(!bIsFraction);
212 mxEdDecimals->set_visible(!bIsFraction);
213 mxFtDecimals->set_sensitive(!bIsFraction);
214 mxEdDecimals->set_sensitive(!bIsFraction);
215 mxFtLeadZeroes->set_sensitive( !bIsTime );
216 mxEdLeadZeroes->set_sensitive( !bIsTime );
217 }
218 else
220 }
221 else
222 {
224 mxLbCategory->set_active(-1);
226 }
227 }
228 break;
229 case SID_NUMBER_FORMAT:
230 {
231 bool bThousand = false;
232 bool bNegRed = false;
233 sal_uInt16 nPrecision = 0;
234 sal_uInt16 nLeadZeroes = 0;
235 bool bNatNum12 = false;
237 if( eState >= SfxItemState::DEFAULT)
238 {
239 const SfxStringItem* pItem = static_cast<const SfxStringItem*>(pState);
240 const OUString& aCode = pItem->GetValue();
241 sal_Int32 nIndex = 0;
242 sal_Int32 aFormat[5] = {0};
243 for (sal_Int32 & rn : aFormat)
244 {
245 rn = o3tl::toInt32(o3tl::getToken(aCode, 0, ',', nIndex));
246 if (nIndex<0)
247 break;
248 }
249 bThousand = static_cast<bool>(aFormat[0]);
250 bNegRed = static_cast<bool>(aFormat[1]);
251 nPrecision = static_cast<sal_uInt16>(aFormat[2]);
252 nLeadZeroes = static_cast<sal_uInt16>(aFormat[3]);
253 bNatNum12 = static_cast< bool >( aFormat[4] );
254 }
255 else
256 {
257 bThousand = false;
258 bNegRed = false;
259 nPrecision = 0;
260 nLeadZeroes = 1;
261 }
262 if ( nCategory == CAT_NUMBER ||
263 nCategory == CAT_PERCENT ||
264 nCategory == CAT_CURRENCY ||
265 nCategory == CAT_FRACTION )
266 mxBtnThousand->set_sensitive( !bNatNum12 );
267 if ( mxBtnThousand->get_visible() )
268 mxBtnThousand->set_active(bThousand);
269 else if ( mxBtnEngineering->get_visible() )
270 mxBtnEngineering->set_active(bThousand);
271 mxBtnNegRed->set_active(bNegRed);
272 if ( mxLbCategory->get_active() == 0 )
273 mxEdDecimals->set_text(""); // tdf#44399
274 else if ( mxEdDecimals->get_visible() )
275 mxEdDecimals->set_value(nPrecision);
276 else if ( mxEdDenominator->get_visible() )
277 mxEdDenominator->set_value(nPrecision);
278 mxEdLeadZeroes->set_value(nLeadZeroes);
279 }
280 break;
281 default:
282 break;
283 }
284}
285
287{
288 mxBtnEngineering->hide();
289 mxBtnThousand->show();
290 mxBtnThousand->set_sensitive(false);
291 mxBtnNegRed->set_sensitive(false);
292 mxFtDenominator->hide();
293 mxEdDenominator->hide();
294 mxFtDecimals->show();
295 mxEdDecimals->show();
296 mxFtDecimals->set_sensitive(false);
297 mxEdDecimals->set_sensitive(false);
298 mxFtLeadZeroes->set_sensitive(false);
299 mxEdLeadZeroes->set_sensitive(false);
300}
301
302} // end of namespace ::sc::sidebar
303
304/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt16 GetValue() const
const OUString & GetValue() const
SfxDispatcher * GetDispatcher() const
virtual void dispose()
const SfxPoolItem * ExecuteList(sal_uInt16 nSlot, SfxCallMode nCall, std::initializer_list< SfxPoolItem const * > args, std::initializer_list< SfxPoolItem const * > internalargs=std::initializer_list< SfxPoolItem const * >())
std::unique_ptr< weld::Label > mxFtDenominator
std::unique_ptr< weld::SpinButton > mxEdDenominator
std::unique_ptr< weld::Toolbar > mxTBCategory
std::unique_ptr< weld::CheckButton > mxBtnThousand
std::unique_ptr< weld::SpinButton > mxEdDecimals
std::unique_ptr< weld::CheckButton > mxBtnNegRed
std::unique_ptr< weld::CheckButton > mxBtnEngineering
std::unique_ptr< ToolbarUnoDispatcher > mxCategoryDispatch
std::unique_ptr< weld::ComboBox > mxLbCategory
::sfx2::sidebar::ControllerItem maNumFormatControl
::sfx2::sidebar::ControllerItem maFormatControl
static std::unique_ptr< PanelLayout > Create(weld::Widget *pParent, const css::uno::Reference< css::frame::XFrame > &rxFrame, SfxBindings *pBindings)
virtual void NotifyItemUpdate(const sal_uInt16 nSId, const SfxItemState eState, const SfxPoolItem *pState) override
std::unique_ptr< weld::SpinButton > mxEdLeadZeroes
virtual void HandleContextChange(const vcl::EnumContext &rContext) override
NumberFormatPropertyPanel(weld::Widget *pParent, const css::uno::Reference< css::frame::XFrame > &rxFrame, SfxBindings *pBindings)
virtual SfxBindings & GetBindings() override
sal_Int32 nIndex
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
IMPL_LINK(AlignmentPropertyPanel, ReferenceEdgeHdl, weld::Button &, rToggle, void)
IMPL_LINK_NOARG(AlignmentPropertyPanel, AngleModifiedHdl, weld::MetricSpinButton &, void)
SvxNumberFormatCategory
CAT_TIME
CAT_NUMBER
CAT_DATE
CAT_CURRENCY
CAT_PERCENT
CAT_SCIENTIFIC
CAT_FRACTION
SfxItemState