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