LibreOffice Module sc (master)  1
colorformat.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 
10 #include <colorformat.hxx>
11 #include <colorscale.hxx>
12 
13 #include <document.hxx>
14 
15 #include <svl/numformat.hxx>
16 #include <svx/colorbox.hxx>
17 #include <vcl/svapp.hxx>
18 #include <vcl/weld.hxx>
19 
20 namespace {
21 
22 void SetType(const ScColorScaleEntry* pEntry, weld::ComboBox& rLstBox)
23 {
24  rLstBox.set_active(pEntry->GetType());
25 }
26 
27 void GetType(const weld::ComboBox& rLstBox, const weld::Entry& rEd, ScColorScaleEntry* pEntry, SvNumberFormatter* pNumberFormatter,
28  ScDocument* pDoc, const ScAddress& rPos )
29 {
30  double nVal = 0;
31  sal_uInt32 nIndex = 0;
32  pEntry->SetType(static_cast<ScColorScaleEntryType>(rLstBox.get_active()));
33  switch (rLstBox.get_active())
34  {
35  case COLORSCALE_AUTO:
36  case COLORSCALE_MIN:
37  case COLORSCALE_MAX:
38  break;
40  case COLORSCALE_VALUE:
41  case COLORSCALE_PERCENT:
42  (void)pNumberFormatter->IsNumberFormat( rEd.get_text(), nIndex, nVal );
43  pEntry->SetValue(nVal);
44  break;
45  case COLORSCALE_FORMULA:
46  pEntry->SetFormula(rEd.get_text(), *pDoc, rPos);
47  break;
48  }
49 }
50 
51 OUString convertNumberToString(double nVal, const ScDocument* pDoc)
52 {
53  SvNumberFormatter* pNumberFormatter = pDoc->GetFormatTable();
54  OUString aText;
55  pNumberFormatter->GetInputLineString(nVal, 0, aText);
56  return aText;
57 }
58 
59 void SetValue( const ScDocument* pDoc, const ScColorScaleEntry* pEntry, weld::Entry& rEdit)
60 {
61  if(pEntry->GetType() == COLORSCALE_FORMULA)
63  else if(pEntry->GetType() != COLORSCALE_MIN && pEntry->GetType() != COLORSCALE_MAX)
64  rEdit.set_text(convertNumberToString(pEntry->GetValue(), pDoc));
65  else
66  rEdit.set_sensitive(false);
67 }
68 
69 }
70 
72  : GenericDialogController(pParent, "modules/scalc/ui/databaroptions.ui", "DataBarOptions")
73  , mpNumberFormatter(pDoc->GetFormatTable())
74  , mpDoc(pDoc)
75  , maPos(rPos)
76  , mxBtnOk(m_xBuilder->weld_button("ok"))
77  , mxBtnCancel(m_xBuilder->weld_button("cancel"))
78  , mxLbPos(new ColorListBox(m_xBuilder->weld_menu_button("positive_colour"), [this]{ return m_xDialog.get(); }))
79  , mxLbNeg(new ColorListBox(m_xBuilder->weld_menu_button("negative_colour"), [this]{ return m_xDialog.get(); }))
80  , mxLbAxisCol(new ColorListBox(m_xBuilder->weld_menu_button("axis_colour"), [this]{ return m_xDialog.get(); }))
81  , mxLbFillType(m_xBuilder->weld_combo_box("fill_type"))
82  , mxLbTypeMin(m_xBuilder->weld_combo_box("min"))
83  , mxLbTypeMax(m_xBuilder->weld_combo_box("max"))
84  , mxLbAxisPos(m_xBuilder->weld_combo_box("axis_pos"))
85  , mxEdMin(m_xBuilder->weld_entry("min_value"))
86  , mxEdMax(m_xBuilder->weld_entry("max_value"))
87  , mxLenMin(m_xBuilder->weld_entry("min_length"))
88  , mxLenMax(m_xBuilder->weld_entry("max_length"))
89  , mxCbOnlyBar(m_xBuilder->weld_check_button("only_bar"))
90  , mxStrSameValueFT(m_xBuilder->weld_label("str_same_value"))
91 {
92  maStrWarnSameValue = mxStrSameValueFT->get_label();
93 
94  Init();
95 
96  mxLbPos->SelectEntry(rData.maPositiveColor);
97  mxLbFillType->set_active( rData.mbGradient ? 1 : 0 );
98  if (rData.mxNegativeColor)
99  mxLbNeg->SelectEntry(*rData.mxNegativeColor);
100 
101  switch (rData.meAxisPosition)
102  {
103  case databar::NONE:
104  mxLbAxisPos->set_active(2);
105  break;
106  case databar::AUTOMATIC:
107  mxLbAxisPos->set_active(0);
108  break;
109  case databar::MIDDLE:
110  mxLbAxisPos->set_active(1);
111  break;
112  }
113  ::SetType(rData.mpLowerLimit.get(), *mxLbTypeMin);
114  ::SetType(rData.mpUpperLimit.get(), *mxLbTypeMax);
115  SetValue(mpDoc, rData.mpLowerLimit.get(), *mxEdMin);
116  SetValue(mpDoc, rData.mpUpperLimit.get(), *mxEdMax);
117  mxLenMin->set_text(convertNumberToString(rData.mnMinLength, mpDoc));
118  mxLenMax->set_text(convertNumberToString(rData.mnMaxLength, mpDoc));
119  mxLbAxisCol->SelectEntry(rData.maAxisColor);
120  mxCbOnlyBar->set_active(rData.mbOnlyBar);
121 
122  TypeSelectHdl(*mxLbTypeMin);
123  PosSelectHdl(*mxLbTypeMin);
124 }
125 
127 {
128 }
129 
131 {
132  mxLbNeg->SelectEntry(COL_LIGHTRED);
133  mxLbAxisCol->SelectEntry(COL_BLACK);
134  mxLbPos->SelectEntry(0x2a6099);
135  mxBtnOk->connect_clicked( LINK( this, ScDataBarSettingsDlg, OkBtnHdl ) );
136 
137  mxLbTypeMin->connect_changed( LINK( this, ScDataBarSettingsDlg, TypeSelectHdl ) );
138  mxLbTypeMax->connect_changed( LINK( this, ScDataBarSettingsDlg, TypeSelectHdl ) );
139  mxLbAxisPos->connect_changed( LINK( this, ScDataBarSettingsDlg, PosSelectHdl ) );
140 
141 }
142 
143 namespace {
144 
145 void GetAxesPosition(ScDataBarFormatData* pData, const weld::ComboBox& rLbox)
146 {
147  switch (rLbox.get_active())
148  {
149  case 0:
151  break;
152  case 1:
154  break;
155  case 2:
156  pData->meAxisPosition = databar::NONE;
157  break;
158  }
159 }
160 
161 void SetBarLength(ScDataBarFormatData* pData, const OUString& minStr, const OUString& maxStr, SvNumberFormatter* mpNumberFormatter)
162 {
163  double nMinValue = 0;
164  sal_uInt32 nIndex = 0;
165  (void)mpNumberFormatter->IsNumberFormat(minStr, nIndex, nMinValue);
166  nIndex = 0;
167  double nMaxValue = 0;
168  (void)mpNumberFormatter->IsNumberFormat(maxStr, nIndex, nMaxValue);
169  pData->mnMinLength = nMinValue;
170  pData->mnMaxLength = nMaxValue;
171 }
172 
173 }
174 
176 {
178  pData->maPositiveColor = mxLbPos->GetSelectEntryColor();
179  pData->mxNegativeColor = mxLbNeg->GetSelectEntryColor();
180  pData->mbGradient = ( mxLbFillType->get_active() == 1 );
181  pData->mpUpperLimit.reset(new ScColorScaleEntry());
182  pData->mpLowerLimit.reset(new ScColorScaleEntry());
183  pData->maAxisColor = mxLbAxisCol->GetSelectEntryColor();
184  pData->mbOnlyBar = mxCbOnlyBar->get_active();
185 
186  ::GetType(*mxLbTypeMin, *mxEdMin, pData->mpLowerLimit.get(), mpNumberFormatter, mpDoc, maPos);
187  ::GetType(*mxLbTypeMax, *mxEdMax, pData->mpUpperLimit.get(), mpNumberFormatter, mpDoc, maPos);
188  GetAxesPosition(pData, *mxLbAxisPos);
189  SetBarLength(pData, mxLenMin->get_text(), mxLenMax->get_text(), mpNumberFormatter);
190 
191  return pData;
192 }
193 
195 {
196  //check that min < max
197  bool bWarn = false;
198  int nSelectMin = mxLbTypeMin->get_active();
199  if( nSelectMin == COLORSCALE_MAX )
200  bWarn = true;
201  int nSelectMax = mxLbTypeMax->get_active();
202  if( nSelectMax == COLORSCALE_MIN )
203  bWarn = true;
204  if(!bWarn) // databar length checks
205  {
206  OUString aMinString = mxLenMin->get_text();
207  OUString aMaxString = mxLenMax->get_text();
208  double nMinValue = 0;
209  sal_uInt32 nIndex = 0;
210  (void)mpNumberFormatter->IsNumberFormat(aMinString, nIndex, nMinValue);
211  nIndex = 0;
212  double nMaxValue = 0;
213  (void)mpNumberFormatter->IsNumberFormat(aMaxString, nIndex, nMaxValue);
214  if(rtl::math::approxEqual(nMinValue, nMaxValue) || nMinValue > nMaxValue || nMaxValue > 100 || nMinValue < 0)
215  bWarn = true;
216  }
217  if (!bWarn && mxLbTypeMin->get_active() == mxLbTypeMax->get_active())
218  {
219 
220  if(nSelectMax != COLORSCALE_FORMULA && nSelectMax != COLORSCALE_AUTO)
221  {
222  OUString aMinString = mxEdMin->get_text();
223  OUString aMaxString = mxEdMax->get_text();
224  double nMinValue = 0;
225  sal_uInt32 nIndex = 0;
226  (void)mpNumberFormatter->IsNumberFormat(aMinString, nIndex, nMinValue);
227  nIndex = 0;
228  double nMaxValue = 0;
229  (void)mpNumberFormatter->IsNumberFormat(aMaxString, nIndex, nMaxValue);
230  if(rtl::math::approxEqual(nMinValue, nMaxValue) || nMinValue > nMaxValue)
231  bWarn = true;
232  }
233  }
234 
235  if(bWarn)
236  {
237  //show warning message and don't close
238  std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(m_xDialog.get(),
239  VclMessageType::Warning, VclButtonsType::Ok,
240  maStrWarnSameValue));
241  xWarn->run();
242  }
243  else
244  {
245  m_xDialog->response(RET_OK);
246  }
247 }
248 
250 {
251  int nSelectMin = mxLbTypeMin->get_active();
252  if( nSelectMin <= COLORSCALE_MAX)
253  mxEdMin->set_sensitive(false);
254  else
255  {
256  mxEdMin->set_sensitive(true);
257  if(mxEdMin->get_text().isEmpty())
258  {
259  if(nSelectMin == COLORSCALE_PERCENTILE || nSelectMin == COLORSCALE_PERCENT)
260  mxEdMin->set_text(OUString::number(50));
261  else
262  mxEdMin->set_text(OUString::number(0));
263  }
264  }
265 
266  int nSelectMax = mxLbTypeMax->get_active();
267  if (nSelectMax <= COLORSCALE_MAX)
268  mxEdMax->set_sensitive(false);
269  else
270  {
271  mxEdMax->set_sensitive(true);
272  if (mxEdMax->get_text().isEmpty())
273  {
274  if(nSelectMax == COLORSCALE_PERCENTILE || nSelectMax == COLORSCALE_PERCENT)
275  mxEdMax->set_text(OUString::number(50));
276  else
277  mxEdMax->set_text(OUString::number(0));
278  }
279  }
280 }
281 
283 {
284  int axisPos = mxLbAxisPos->get_active();
285  if(axisPos != 2 && axisPos != 1) // disable if axis vertical position is automatic
286  {
287  mxLenMin->set_sensitive(false);
288  mxLenMax->set_sensitive(false);
289  }
290  else
291  {
292  mxLenMin->set_sensitive(true);
293  mxLenMax->set_sensitive(true);
294  if(mxLenMin->get_text().isEmpty())
295  {
296  mxLenMin->set_text(OUString::number(0));
297  mxLenMax->set_text(OUString::number(100));
298  }
299  }
300 }
301 
302 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
303 
double mnMaxLength
Maximal length of a databar in percent of cell length Value has to be in the range (0...
Definition: colorscale.hxx:177
std::shared_ptr< weld::Dialog > m_xDialog
std::unique_ptr< weld::Entry > mxLenMin
Definition: colorformat.hxx:43
sal_Int32 nIndex
std::unique_ptr< weld::ComboBox > mxLbTypeMin
Definition: colorformat.hxx:37
void Init()
std::unique_ptr< weld::ComboBox > mxLbFillType
Definition: colorformat.hxx:36
SvNumberFormatter * mpNumberFormatter
Definition: colorformat.hxx:24
std::unique_ptr< sal_Int32[]> pData
double mnMinLength
Minimal length of a databar in percent of cell length Value has to be in the range [0...
Definition: colorscale.hxx:172
std::unique_ptr< weld::Entry > mxLenMax
Definition: colorformat.hxx:44
std::unique_ptr< weld::CheckButton > mxCbOnlyBar
Definition: colorformat.hxx:46
std::unique_ptr< ColorListBox > mxLbNeg
Definition: colorformat.hxx:33
const ContentProperties & rData
virtual ~ScDataBarSettingsDlg() override
bool mbOnlyBar
If TRUE we only show the bar and not the value.
Definition: colorscale.hxx:182
void SetValue(double nValue)
Definition: colorscale.cxx:251
virtual int get_active() const =0
virtual void set_text(const OUString &rText)=0
std::optional< Color > mxNegativeColor
Specifies the color for negative values.
Definition: colorscale.hxx:140
std::unique_ptr< weld::Entry > mxEdMax
Definition: colorformat.hxx:42
const ScTokenArray * GetFormula() const
Definition: colorscale.cxx:217
ScDataBarFormatData * GetData()
ScColorScaleEntryType GetType() const
Definition: colorscale.hxx:76
std::unique_ptr< weld::ComboBox > mxLbAxisPos
Definition: colorformat.hxx:39
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_LIGHTRED
std::unique_ptr< weld::Entry > mxEdMin
Definition: colorformat.hxx:41
Color maPositiveColor
Color for all Positive Values and if mbNeg == false also for negative ones.
Definition: colorscale.hxx:134
Color maAxisColor
Color of the axis if used Default color is black.
Definition: colorscale.hxx:145
ScDocument * mpDoc
Definition: colorformat.hxx:26
SC_DLLPUBLIC SvNumberFormatter * GetFormatTable() const
Definition: documen2.cxx:442
bool mbGradient
Paint the bars with gradient.
Definition: colorscale.hxx:152
IMPL_LINK_NOARG(ScDataBarSettingsDlg, OkBtnHdl, weld::Button &, void)
bool IsNumberFormat(const OUString &sString, sal_uInt32 &F_Index, double &fOutNumber, SvNumInputOptions eInputOptions=SvNumInputOptions::NONE)
void GetInputLineString(const double &fOutNumber, sal_uInt32 nFIndex, OUString &rOutString, bool bFiltering=false)
virtual void set_active(int pos)=0
ScDataBarSettingsDlg(weld::Window *pParent, const ScDataBarFormatData &rData, ScDocument *pDoc, const ScAddress &rPos)
Definition: colorformat.cxx:71
std::unique_ptr< ColorListBox > mxLbAxisCol
Definition: colorformat.hxx:34
void SetFormula(const OUString &rFormula, ScDocument &rDoc, const ScAddress &rAddr, formula::FormulaGrammar::Grammar eGrammar=formula::FormulaGrammar::GRAM_DEFAULT)
Definition: colorscale.cxx:208
virtual OUString get_text() const =0
databar::ScAxisPosition meAxisPosition
Paint negative values into the same direction as positive values If false we will set the mid point a...
Definition: colorscale.hxx:167
std::unique_ptr< ScColorScaleEntry, o3tl::default_delete< ScColorScaleEntry > > mpUpperLimit
Definition: colorscale.hxx:184
RET_OK
Reference< XExecutableDialog > m_xDialog
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
std::unique_ptr< weld::Button > mxBtnOk
Definition: colorformat.hxx:29
std::unique_ptr< weld::ComboBox > mxLbTypeMax
Definition: colorformat.hxx:38
void SetType(ScColorScaleEntryType eType)
Definition: colorscale.cxx:324
std::unique_ptr< ScColorScaleEntry, o3tl::default_delete< ScColorScaleEntry > > mpLowerLimit
Definition: colorscale.hxx:185
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, bool bMobile=false)
double GetValue() const
Definition: colorscale.cxx:237
virtual void set_sensitive(bool sensitive)=0
virtual void SetValue(tools::Long nNew) override
std::unique_ptr< ColorListBox > mxLbPos
Definition: colorformat.hxx:32
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo