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