xref: /core/sc/source/ui/condformat/colorformat.cxx (revision e5c3d5f3)
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 <svx/colorbox.hxx>
16 #include <vcl/svapp.hxx>
17 #include <vcl/weld.hxx>
18 
19 namespace {
20 
21 void SetType(const ScColorScaleEntry* pEntry, weld::ComboBox& rLstBox)
22 {
23     rLstBox.set_active(pEntry->GetType());
24 }
25 
26 void GetType(const weld::ComboBox& rLstBox, const weld::Entry& rEd, ScColorScaleEntry* pEntry, SvNumberFormatter* pNumberFormatter,
27         ScDocument* pDoc, const ScAddress& rPos )
28 {
29     double nVal = 0;
30     sal_uInt32 nIndex = 0;
31     pEntry->SetType(static_cast<ScColorScaleEntryType>(rLstBox.get_active()));
32     switch (rLstBox.get_active())
33     {
34         case COLORSCALE_AUTO:
35         case COLORSCALE_MIN:
36         case COLORSCALE_MAX:
37             break;
38         case COLORSCALE_PERCENTILE:
39         case COLORSCALE_VALUE:
40         case COLORSCALE_PERCENT:
41             (void)pNumberFormatter->IsNumberFormat( rEd.get_text(), nIndex, nVal );
42             pEntry->SetValue(nVal);
43             break;
44         case COLORSCALE_FORMULA:
45             pEntry->SetFormula(rEd.get_text(), pDoc, rPos);
46             break;
47     }
48 }
49 
50 OUString convertNumberToString(double nVal, const ScDocument* pDoc)
51 {
52     SvNumberFormatter* pNumberFormatter = pDoc->GetFormatTable();
53     OUString aText;
54     pNumberFormatter->GetInputLineString(nVal, 0, aText);
55     return aText;
56 }
57 
58 void SetValue( const ScDocument* pDoc, const ScColorScaleEntry* pEntry, weld::Entry& rEdit)
59 {
60     if(pEntry->GetType() == COLORSCALE_FORMULA)
61         rEdit.set_text(pEntry->GetFormula(formula::FormulaGrammar::GRAM_DEFAULT));
62     else if(pEntry->GetType() != COLORSCALE_MIN && pEntry->GetType() != COLORSCALE_MAX)
63         rEdit.set_text(convertNumberToString(pEntry->GetValue(), pDoc));
64     else
65         rEdit.set_sensitive(false);
66 }
67 
68 }
69 
70 ScDataBarSettingsDlg::ScDataBarSettingsDlg(weld::Window* pParent, const ScDataBarFormatData& rData, ScDocument* pDoc, const ScAddress& rPos)
71     : GenericDialogController(pParent, "modules/scalc/ui/databaroptions.ui", "DataBarOptions")
72     , mpNumberFormatter(pDoc->GetFormatTable())
73     , mpDoc(pDoc)
74     , maPos(rPos)
75     , mxBtnOk(m_xBuilder->weld_button("ok"))
76     , mxBtnCancel(m_xBuilder->weld_button("cancel"))
77     , mxLbPos(new ColorListBox(m_xBuilder->weld_menu_button("positive_colour"), pParent))
78     , mxLbNeg(new ColorListBox(m_xBuilder->weld_menu_button("negative_colour"), pParent))
79     , mxLbAxisCol(new ColorListBox(m_xBuilder->weld_menu_button("axis_colour"), pParent))
80     , mxLbFillType(m_xBuilder->weld_combo_box("fill_type"))
81     , mxLbTypeMin(m_xBuilder->weld_combo_box("min"))
82     , mxLbTypeMax(m_xBuilder->weld_combo_box("max"))
83     , mxLbAxisPos(m_xBuilder->weld_combo_box("axis_pos"))
84     , mxEdMin(m_xBuilder->weld_entry("min_value"))
85     , mxEdMax(m_xBuilder->weld_entry("max_value"))
86     , mxLenMin(m_xBuilder->weld_entry("min_length"))
87     , mxLenMax(m_xBuilder->weld_entry("max_length"))
88     , mxCbOnlyBar(m_xBuilder->weld_check_button("only_bar"))
89     , mxStrSameValueFT(m_xBuilder->weld_label("str_same_value"))
90 {
91     maStrWarnSameValue = mxStrSameValueFT->get_label();
92 
93     Init();
94 
95     mxLbPos->SelectEntry(rData.maPositiveColor);
96     mxLbFillType->set_active( rData.mbGradient ? 1 : 0 );
97     if (rData.mpNegativeColor)
98         mxLbNeg->SelectEntry(*rData.mpNegativeColor);
99 
100     switch (rData.meAxisPosition)
101     {
102         case databar::NONE:
103             mxLbAxisPos->set_active(2);
104             break;
105         case databar::AUTOMATIC:
106             mxLbAxisPos->set_active(0);
107             break;
108         case databar::MIDDLE:
109             mxLbAxisPos->set_active(1);
110             break;
111     }
112     ::SetType(rData.mpLowerLimit.get(), *mxLbTypeMin);
113     ::SetType(rData.mpUpperLimit.get(), *mxLbTypeMax);
114     SetValue(mpDoc, rData.mpLowerLimit.get(), *mxEdMin);
115     SetValue(mpDoc, rData.mpUpperLimit.get(), *mxEdMax);
116     mxLenMin->set_text(convertNumberToString(rData.mnMinLength, mpDoc));
117     mxLenMax->set_text(convertNumberToString(rData.mnMaxLength, mpDoc));
118     mxLbAxisCol->SelectEntry(rData.maAxisColor);
119     mxCbOnlyBar->set_active(rData.mbOnlyBar);
120 
121     TypeSelectHdl(*mxLbTypeMin);
122     PosSelectHdl(*mxLbTypeMin);
123 }
124 
125 ScDataBarSettingsDlg::~ScDataBarSettingsDlg()
126 {
127 }
128 
129 void ScDataBarSettingsDlg::Init()
130 {
131     mxLbNeg->SelectEntry(COL_LIGHTRED);
132     mxLbAxisCol->SelectEntry(COL_BLACK);
133     mxLbPos->SelectEntry(COL_LIGHTBLUE);
134     mxBtnOk->connect_clicked( LINK( this, ScDataBarSettingsDlg, OkBtnHdl ) );
135 
136     mxLbTypeMin->connect_changed( LINK( this, ScDataBarSettingsDlg, TypeSelectHdl ) );
137     mxLbTypeMax->connect_changed( LINK( this, ScDataBarSettingsDlg, TypeSelectHdl ) );
138     mxLbAxisPos->connect_changed( LINK( this, ScDataBarSettingsDlg, PosSelectHdl ) );
139 
140 }
141 
142 namespace {
143 
144 void GetAxesPosition(ScDataBarFormatData* pData, const weld::ComboBox& rLbox)
145 {
146     switch (rLbox.get_active())
147     {
148         case 0:
149             pData->meAxisPosition = databar::AUTOMATIC;
150             break;
151         case 1:
152             pData->meAxisPosition = databar::MIDDLE;
153             break;
154         case 2:
155             pData->meAxisPosition = databar::NONE;
156             break;
157     }
158 }
159 
160 void SetBarLength(ScDataBarFormatData* pData, const OUString& minStr, const OUString& maxStr, SvNumberFormatter* mpNumberFormatter)
161 {
162     double nMinValue = 0;
163     sal_uInt32 nIndex = 0;
164     (void)mpNumberFormatter->IsNumberFormat(minStr, nIndex, nMinValue);
165     nIndex = 0;
166     double nMaxValue = 0;
167     (void)mpNumberFormatter->IsNumberFormat(maxStr, nIndex, nMaxValue);
168     pData->mnMinLength = nMinValue;
169     pData->mnMaxLength = nMaxValue;
170 }
171 
172 }
173 
174 ScDataBarFormatData* ScDataBarSettingsDlg::GetData()
175 {
176     ScDataBarFormatData* pData = new ScDataBarFormatData();
177     pData->maPositiveColor = mxLbPos->GetSelectEntryColor();
178     pData->mpNegativeColor.reset(new Color(mxLbNeg->GetSelectEntryColor()));
179     pData->mbGradient = ( mxLbFillType->get_active() == 1 );
180     pData->mpUpperLimit.reset(new ScColorScaleEntry());
181     pData->mpLowerLimit.reset(new ScColorScaleEntry());
182     pData->maAxisColor = mxLbAxisCol->GetSelectEntryColor();
183     pData->mbOnlyBar = mxCbOnlyBar->get_active();
184 
185     ::GetType(*mxLbTypeMin, *mxEdMin, pData->mpLowerLimit.get(), mpNumberFormatter, mpDoc, maPos);
186     ::GetType(*mxLbTypeMax, *mxEdMax, pData->mpUpperLimit.get(), mpNumberFormatter, mpDoc, maPos);
187     GetAxesPosition(pData, *mxLbAxisPos);
188     SetBarLength(pData, mxLenMin->get_text(), mxLenMax->get_text(), mpNumberFormatter);
189 
190     return pData;
191 }
192 
193 IMPL_LINK_NOARG(ScDataBarSettingsDlg, OkBtnHdl, weld::Button&, void)
194 {
195     //check that min < max
196     bool bWarn = false;
197     int nSelectMin = mxLbTypeMin->get_active();
198     if( nSelectMin == COLORSCALE_MAX )
199         bWarn = true;
200     int nSelectMax = mxLbTypeMax->get_active();
201     if( nSelectMax == COLORSCALE_MIN )
202         bWarn = true;
203     if(!bWarn) // databar length checks
204     {
205         OUString aMinString = mxLenMin->get_text();
206         OUString aMaxString = mxLenMax->get_text();
207         double nMinValue = 0;
208         sal_uInt32 nIndex = 0;
209         (void)mpNumberFormatter->IsNumberFormat(aMinString, nIndex, nMinValue);
210         nIndex = 0;
211         double nMaxValue = 0;
212         (void)mpNumberFormatter->IsNumberFormat(aMaxString, nIndex, nMaxValue);
213         if(rtl::math::approxEqual(nMinValue, nMaxValue) || nMinValue > nMaxValue || nMaxValue > 100 || nMinValue < 0)
214             bWarn = true;
215     }
216     if (!bWarn && mxLbTypeMin->get_active() == mxLbTypeMax->get_active())
217     {
218 
219         if(nSelectMax != COLORSCALE_FORMULA && nSelectMax != COLORSCALE_AUTO)
220         {
221             OUString aMinString = mxEdMin->get_text();
222             OUString aMaxString = mxEdMax->get_text();
223             double nMinValue = 0;
224             sal_uInt32 nIndex = 0;
225             (void)mpNumberFormatter->IsNumberFormat(aMinString, nIndex, nMinValue);
226             nIndex = 0;
227             double nMaxValue = 0;
228             (void)mpNumberFormatter->IsNumberFormat(aMaxString, nIndex, nMaxValue);
229             if(rtl::math::approxEqual(nMinValue, nMaxValue) || nMinValue > nMaxValue)
230                 bWarn = true;
231         }
232     }
233 
234     if(bWarn)
235     {
236         //show warning message and don't close
237         std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(m_xDialog.get(),
238                                                    VclMessageType::Warning, VclButtonsType::Ok,
239                                                    maStrWarnSameValue));
240         xWarn->run();
241     }
242     else
243     {
244         m_xDialog->response(RET_OK);
245     }
246 }
247 
248 IMPL_LINK_NOARG(ScDataBarSettingsDlg, TypeSelectHdl, weld::ComboBox&, void)
249 {
250     int nSelectMin = mxLbTypeMin->get_active();
251     if( nSelectMin <= COLORSCALE_MAX)
252         mxEdMin->set_sensitive(false);
253     else
254     {
255         mxEdMin->set_sensitive(true);
256         if(mxEdMin->get_text().isEmpty())
257         {
258             if(nSelectMin == COLORSCALE_PERCENTILE || nSelectMin == COLORSCALE_PERCENT)
259                 mxEdMin->set_text(OUString::number(50));
260             else
261                 mxEdMin->set_text(OUString::number(0));
262         }
263     }
264 
265     int nSelectMax = mxLbTypeMax->get_active();
266     if (nSelectMax <= COLORSCALE_MAX)
267         mxEdMax->set_sensitive(false);
268     else
269     {
270         mxEdMax->set_sensitive(true);
271         if (mxEdMax->get_text().isEmpty())
272         {
273             if(nSelectMax == COLORSCALE_PERCENTILE || nSelectMax == COLORSCALE_PERCENT)
274                 mxEdMax->set_text(OUString::number(50));
275             else
276                 mxEdMax->set_text(OUString::number(0));
277         }
278     }
279 }
280 
281 IMPL_LINK_NOARG(ScDataBarSettingsDlg, PosSelectHdl, weld::ComboBox&, void)
282 {
283     int axisPos = mxLbAxisPos->get_active();
284     if(axisPos != 2 && axisPos != 1) // disable if axis vertical position is automatic
285     {
286         mxLenMin->set_sensitive(false);
287         mxLenMax->set_sensitive(false);
288     }
289     else
290     {
291         mxLenMin->set_sensitive(true);
292         mxLenMax->set_sensitive(true);
293         if(mxLenMin->get_text().isEmpty())
294         {
295             mxLenMin->set_text(OUString::number(0));
296             mxLenMax->set_text(OUString::number(100));
297         }
298     }
299 }
300 
301 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
302 
303