Line data Source code
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 :
20 : #include "prcntfld.hxx"
21 :
22 0 : PercentField::PercentField()
23 : : m_pField(NULL)
24 : , nRefValue(0)
25 : , nOldMax(0)
26 : , nOldMin(0)
27 : , nOldSpinSize(0)
28 : , nOldBaseValue(0)
29 : , nLastPercent(-1)
30 : , nLastValue(-1)
31 : , nOldDigits(0)
32 : , eOldUnit(FUNIT_NONE)
33 0 : , bLockAutoCalculation(false)
34 : {
35 0 : }
36 :
37 0 : void PercentField::set(MetricField *pField)
38 : {
39 0 : m_pField = pField;
40 0 : nOldSpinSize = m_pField->GetSpinSize();
41 0 : nRefValue = DenormalizePercent(m_pField->GetMax(FUNIT_TWIP));
42 0 : nOldDigits = m_pField->GetDecimalDigits();
43 0 : m_pField->SetCustomUnitText(OUString('%'));
44 0 : }
45 :
46 0 : void PercentField::SetRefValue(sal_Int64 nValue)
47 : {
48 0 : sal_Int64 nRealValue = GetRealValue(eOldUnit);
49 :
50 0 : nRefValue = nValue;
51 :
52 0 : if (!bLockAutoCalculation && (m_pField->GetUnit() == FUNIT_CUSTOM))
53 0 : SetPrcntValue(nRealValue, eOldUnit);
54 0 : }
55 :
56 0 : void PercentField::ShowPercent(bool bPercent)
57 : {
58 0 : if ((bPercent && m_pField->GetUnit() == FUNIT_CUSTOM) ||
59 0 : (!bPercent && m_pField->GetUnit() != FUNIT_CUSTOM))
60 0 : return;
61 :
62 : sal_Int64 nOldValue;
63 :
64 0 : if (bPercent)
65 : {
66 : sal_Int64 nAktWidth, nPercent;
67 :
68 0 : nOldValue = GetValue();
69 :
70 0 : eOldUnit = m_pField->GetUnit();
71 0 : nOldDigits = m_pField->GetDecimalDigits();
72 0 : nOldMin = m_pField->GetMin();
73 0 : nOldMax = m_pField->GetMax();
74 0 : nOldSpinSize = m_pField->GetSpinSize();
75 0 : nOldBaseValue = m_pField->GetBaseValue();
76 0 : m_pField->SetUnit(FUNIT_CUSTOM);
77 0 : m_pField->SetDecimalDigits( 0 );
78 :
79 0 : nAktWidth = MetricField::ConvertValue(nOldMin, 0, nOldDigits, eOldUnit, FUNIT_TWIP);
80 : // round to 0.5 percent
81 0 : nPercent = ((nAktWidth * 10) / nRefValue + 5) / 10;
82 :
83 0 : m_pField->SetMin(std::max(static_cast< sal_Int64 >(1), nPercent));
84 0 : m_pField->SetMax(100);
85 0 : m_pField->SetSpinSize(5);
86 0 : m_pField->SetBaseValue(0);
87 0 : if (nOldValue != nLastValue)
88 : {
89 0 : nAktWidth = MetricField::ConvertValue(nOldValue, 0, nOldDigits, eOldUnit, FUNIT_TWIP);
90 0 : nPercent = ((nAktWidth * 10) / nRefValue + 5) / 10;
91 0 : m_pField->SetValue(nPercent);
92 0 : nLastPercent = nPercent;
93 0 : nLastValue = nOldValue;
94 : }
95 : else
96 0 : m_pField->SetValue(nLastPercent);
97 : }
98 : else
99 : {
100 0 : sal_Int64 nOldPercent = GetValue(FUNIT_CUSTOM);
101 :
102 0 : nOldValue = Convert(GetValue(), m_pField->GetUnit(), eOldUnit);
103 :
104 0 : m_pField->SetUnit(eOldUnit);
105 0 : m_pField->SetDecimalDigits(nOldDigits);
106 0 : m_pField->SetMin(nOldMin);
107 0 : m_pField->SetMax(nOldMax);
108 0 : m_pField->SetSpinSize(nOldSpinSize);
109 0 : m_pField->SetBaseValue(nOldBaseValue);
110 :
111 0 : if (nOldPercent != nLastPercent)
112 : {
113 0 : SetPrcntValue(nOldValue, eOldUnit);
114 0 : nLastPercent = nOldPercent;
115 0 : nLastValue = nOldValue;
116 : }
117 : else
118 0 : SetPrcntValue(nLastValue, eOldUnit);
119 : }
120 : }
121 :
122 0 : void PercentField::SetPrcntValue(sal_Int64 nNewValue, FieldUnit eInUnit)
123 : {
124 0 : if (m_pField->GetUnit() != FUNIT_CUSTOM || eInUnit == FUNIT_CUSTOM)
125 0 : m_pField->SetValue(Convert(nNewValue, eInUnit, m_pField->GetUnit()));
126 : else
127 : {
128 : // Overwrite output value, do not restore later
129 : sal_Int64 nPercent, nAktWidth;
130 0 : if(eInUnit == FUNIT_TWIP)
131 : {
132 0 : nAktWidth = MetricField::ConvertValue(nNewValue, 0, nOldDigits, FUNIT_TWIP, FUNIT_TWIP);
133 : }
134 : else
135 : {
136 0 : sal_Int64 nValue = Convert(nNewValue, eInUnit, eOldUnit);
137 0 : nAktWidth = MetricField::ConvertValue(nValue, 0, nOldDigits, eOldUnit, FUNIT_TWIP);
138 : }
139 0 : nPercent = ((nAktWidth * 10) / nRefValue + 5) / 10;
140 0 : m_pField->SetValue(nPercent);
141 : }
142 0 : }
143 :
144 0 : void PercentField::SetBaseValue(sal_Int64 nNewValue, FieldUnit eInUnit)
145 : {
146 0 : if (m_pField->GetUnit() == FUNIT_CUSTOM)
147 0 : nOldBaseValue = MetricField::ConvertValue(nNewValue, 0, nOldDigits, eInUnit, eOldUnit);
148 : else
149 0 : m_pField->SetBaseValue(nNewValue, eInUnit);
150 0 : }
151 :
152 0 : sal_Int64 PercentField::GetValue(FieldUnit eOutUnit)
153 : {
154 0 : return Convert(m_pField->GetValue(), m_pField->GetUnit(), eOutUnit);
155 : }
156 :
157 0 : void PercentField::SetMin(sal_Int64 nNewMin, FieldUnit eInUnit)
158 : {
159 0 : if (m_pField->GetUnit() != FUNIT_CUSTOM)
160 0 : m_pField->SetMin(nNewMin, eInUnit);
161 : else
162 : {
163 0 : if (eInUnit == FUNIT_NONE)
164 0 : eInUnit = eOldUnit;
165 0 : nOldMin = Convert(nNewMin, eInUnit, eOldUnit);
166 :
167 0 : sal_Int64 nPercent = Convert(nNewMin, eInUnit, FUNIT_CUSTOM);
168 0 : m_pField->SetMin(std::max( static_cast< sal_Int64 >(1), nPercent));
169 : }
170 0 : }
171 :
172 0 : void PercentField::SetMax(sal_Int64 nNewMax, FieldUnit eInUnit)
173 : {
174 0 : if (m_pField->GetUnit() != FUNIT_CUSTOM)
175 0 : m_pField->SetMax(nNewMax, eInUnit);
176 : else
177 : {
178 0 : if (eInUnit == FUNIT_NONE)
179 0 : eInUnit = eOldUnit;
180 : }
181 0 : }
182 :
183 0 : sal_Int64 PercentField::NormalizePercent(sal_Int64 nValue)
184 : {
185 0 : if (m_pField->GetUnit() != FUNIT_CUSTOM)
186 0 : nValue = m_pField->Normalize(nValue);
187 : else
188 0 : nValue = nValue * ImpPower10(nOldDigits);
189 0 : return nValue;
190 : }
191 :
192 0 : sal_Int64 PercentField::DenormalizePercent(sal_Int64 nValue)
193 : {
194 0 : if (m_pField->GetUnit() != FUNIT_CUSTOM)
195 0 : nValue = m_pField->Denormalize(nValue);
196 : else
197 : {
198 0 : sal_Int64 nFactor = ImpPower10(nOldDigits);
199 0 : nValue = ((nValue+(nFactor/2)) / nFactor);
200 : }
201 0 : return nValue;
202 : }
203 :
204 0 : bool PercentField::IsValueModified()
205 : {
206 0 : if (m_pField->GetUnit() == FUNIT_CUSTOM)
207 0 : return true;
208 : else
209 0 : return m_pField->IsValueModified();
210 : }
211 :
212 0 : void PercentField::SetUserValue(sal_Int64 nNewValue, FieldUnit eInUnit)
213 : {
214 0 : if (m_pField->GetUnit() != FUNIT_CUSTOM || eInUnit == FUNIT_CUSTOM)
215 0 : m_pField->SetUserValue(Convert(nNewValue, eInUnit, m_pField->GetUnit()),FUNIT_NONE);
216 : else
217 : {
218 : // Overwrite output value, do not restore later
219 : sal_Int64 nPercent, nAktWidth;
220 0 : if (eInUnit == FUNIT_TWIP)
221 : {
222 0 : nAktWidth = MetricField::ConvertValue(nNewValue, 0, nOldDigits, FUNIT_TWIP, FUNIT_TWIP);
223 : }
224 : else
225 : {
226 0 : sal_Int64 nValue = Convert(nNewValue, eInUnit, eOldUnit);
227 0 : nAktWidth = MetricField::ConvertValue(nValue, 0, nOldDigits, eOldUnit, FUNIT_TWIP);
228 : }
229 0 : nPercent = ((nAktWidth * 10) / nRefValue + 5) / 10;
230 0 : m_pField->SetUserValue(nPercent,FUNIT_NONE);
231 : }
232 0 : }
233 :
234 0 : sal_Int64 PercentField::ImpPower10(sal_uInt16 n)
235 : {
236 0 : sal_Int64 nValue = 1;
237 :
238 0 : for (sal_uInt16 i=0; i < n; ++i)
239 0 : nValue *= 10;
240 :
241 0 : return nValue;
242 : }
243 :
244 0 : sal_Int64 PercentField::GetRealValue(FieldUnit eOutUnit)
245 : {
246 0 : if (m_pField->GetUnit() != FUNIT_CUSTOM)
247 0 : return GetValue(eOutUnit);
248 : else
249 0 : return Convert(GetValue(), m_pField->GetUnit(), eOutUnit);
250 : }
251 :
252 0 : sal_Int64 PercentField::Convert(sal_Int64 nValue, FieldUnit eInUnit, FieldUnit eOutUnit)
253 : {
254 0 : if (eInUnit == eOutUnit ||
255 0 : (eInUnit == FUNIT_NONE && eOutUnit == m_pField->GetUnit()) ||
256 0 : (eOutUnit == FUNIT_NONE && eInUnit == m_pField->GetUnit()))
257 0 : return nValue;
258 :
259 0 : if (eInUnit == FUNIT_CUSTOM)
260 : {
261 : // Convert to metric
262 0 : sal_Int64 nTwipValue = (nRefValue * nValue + 50) / 100;
263 :
264 0 : if (eOutUnit == FUNIT_TWIP) // Only convert if necessary
265 0 : return NormalizePercent(nTwipValue);
266 : else
267 0 : return MetricField::ConvertValue(NormalizePercent(nTwipValue), 0, nOldDigits, FUNIT_TWIP, eOutUnit);
268 : }
269 :
270 0 : if (eOutUnit == FUNIT_CUSTOM)
271 : {
272 : // Convert to percent
273 : sal_Int64 nAktWidth;
274 0 : nValue = DenormalizePercent(nValue);
275 :
276 0 : if (eInUnit == FUNIT_TWIP) // Only convert if necessary
277 0 : nAktWidth = nValue;
278 : else
279 0 : nAktWidth = MetricField::ConvertValue(nValue, 0, nOldDigits, eInUnit, FUNIT_TWIP);
280 : // Round to 0.5 percent
281 0 : return ((nAktWidth * 1000) / nRefValue + 5) / 10;
282 : }
283 :
284 0 : return MetricField::ConvertValue(nValue, 0, nOldDigits, eInUnit, eOutUnit);
285 270 : }
286 :
287 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|