xref: /trunk/main/sw/source/ui/utlui/prcntfld.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 
31 // include ---------------------------------------------------------------
32 
33 
34 #include "prcntfld.hxx"
35 
36 // STATIC DATA -----------------------------------------------------------
37 
38 /*--------------------------------------------------------------------
39     Beschreibung:
40  --------------------------------------------------------------------*/
41 
42 PercentField::PercentField( Window* pWin, const ResId& rResId ) :
43         MetricField ( pWin, rResId ),
44 
45         nOldMax     (0),
46         nOldMin     (0),
47         nLastPercent(-1),
48         nLastValue  (-1),
49         eOldUnit    (FUNIT_NONE),
50         bLockAutoCalculation(sal_False)
51 {
52 
53     nOldSpinSize = GetSpinSize();
54     nRefValue = DenormalizePercent(MetricField::GetMax(FUNIT_TWIP));
55     nOldDigits = GetDecimalDigits();
56     SetCustomUnitText('%');
57 }
58 
59 /*--------------------------------------------------------------------
60     Beschreibung:
61  --------------------------------------------------------------------*/
62 
63 void PercentField::SetRefValue(sal_Int64 nValue)
64 {
65     sal_Int64 nRealValue = GetRealValue(eOldUnit);
66 
67     nRefValue = nValue;
68 
69     if (!bLockAutoCalculation && (GetUnit() == FUNIT_CUSTOM))
70         SetPrcntValue(nRealValue, eOldUnit);
71 }
72 
73 /*--------------------------------------------------------------------
74     Beschreibung:
75  --------------------------------------------------------------------*/
76 
77 void PercentField::ShowPercent(sal_Bool bPercent)
78 {
79     if ((bPercent && GetUnit() == FUNIT_CUSTOM) ||
80         (!bPercent && GetUnit() != FUNIT_CUSTOM))
81         return;
82 
83     sal_Int64 nOldValue;
84 
85     if (bPercent)
86     {
87         sal_Int64 nAktWidth, nPercent;
88 
89         nOldValue = GetValue();
90 
91         eOldUnit = GetUnit();
92         nOldDigits = GetDecimalDigits();
93         nOldMin = GetMin();
94         nOldMax = GetMax();
95         nOldSpinSize = GetSpinSize();
96         nOldBaseValue = GetBaseValue();
97         SetUnit(FUNIT_CUSTOM);
98         SetDecimalDigits( 0 );
99 
100         nAktWidth = ConvertValue(nOldMin, 0, nOldDigits, eOldUnit, FUNIT_TWIP);
101         // Um 0.5 Prozent aufrunden
102         nPercent = ((nAktWidth * 10) / nRefValue + 5) / 10;
103 
104         MetricField::SetMin(Max(static_cast< sal_Int64 >(1), nPercent));
105         MetricField::SetMax(100);
106         SetSpinSize(5);
107         MetricField::SetBaseValue(0);
108         if (nOldValue != nLastValue)
109         {
110             nAktWidth = ConvertValue(nOldValue, 0, nOldDigits, eOldUnit, FUNIT_TWIP);
111             nPercent = ((nAktWidth * 10) / nRefValue + 5) / 10;
112             MetricFormatter::SetValue(nPercent);
113             nLastPercent = nPercent;
114             nLastValue = nOldValue;
115         }
116         else
117             MetricFormatter::SetValue(nLastPercent);
118 //      SetValue(100, FUNIT_CUSTOM);
119     }
120     else
121     {
122         sal_Int64 nOldPercent = GetValue(FUNIT_CUSTOM);
123 
124         nOldValue = Convert(GetValue(), GetUnit(), eOldUnit);
125 
126         SetUnit(eOldUnit);
127         SetDecimalDigits(nOldDigits);
128         MetricField::SetMin(nOldMin);
129         MetricField::SetMax(nOldMax);
130         SetSpinSize(nOldSpinSize);
131         MetricField::SetBaseValue(nOldBaseValue);
132 
133         if (nOldPercent != nLastPercent)
134         {
135             SetPrcntValue(nOldValue, eOldUnit);
136             nLastPercent = nOldPercent;
137             nLastValue = nOldValue;
138         }
139         else
140             SetPrcntValue(nLastValue, eOldUnit);
141     }
142 }
143 
144 /*--------------------------------------------------------------------
145     Beschreibung:
146  --------------------------------------------------------------------*/
147 void PercentField::SetValue(sal_Int64 nNewValue, FieldUnit eInUnit)
148 {
149    MetricFormatter::SetValue(nNewValue, eInUnit);
150 }
151 /*--------------------------------------------------------------------
152     Beschreibung:
153  --------------------------------------------------------------------*/
154 void PercentField::SetPrcntValue(sal_Int64 nNewValue, FieldUnit eInUnit)
155 {
156     if (GetUnit() != FUNIT_CUSTOM || eInUnit == FUNIT_CUSTOM)
157         MetricFormatter::SetValue(Convert(nNewValue, eInUnit, GetUnit()));
158 
159     else
160     {
161         // Ausgangswert ueberschreiben, nicht spaeter restaurieren
162         sal_Int64 nPercent, nAktWidth;
163         if(eInUnit == FUNIT_TWIP)
164         {
165             nAktWidth = ConvertValue(nNewValue, 0, nOldDigits, FUNIT_TWIP, FUNIT_TWIP);
166         }
167         else
168         {
169             sal_Int64 nValue = Convert(nNewValue, eInUnit, eOldUnit);
170             nAktWidth = ConvertValue(nValue, 0, nOldDigits, eOldUnit, FUNIT_TWIP);
171         }
172         nPercent = ((nAktWidth * 10) / nRefValue + 5) / 10;
173         MetricFormatter::SetValue(nPercent);
174     }
175 }
176 
177 /*--------------------------------------------------------------------
178     Beschreibung:
179  --------------------------------------------------------------------*/
180 
181 void PercentField::SetUserValue( sal_Int64 nNewValue, FieldUnit eInUnit )
182 {
183     if (GetUnit() != FUNIT_CUSTOM || eInUnit == FUNIT_CUSTOM)
184         MetricField::SetUserValue(Convert(nNewValue, eInUnit, GetUnit()),FUNIT_NONE);
185 
186     else
187     {
188         // Ausgangswert ueberschreiben, nicht spaeter restaurieren
189         sal_Int64 nPercent, nAktWidth;
190         if(eInUnit == FUNIT_TWIP)
191         {
192             nAktWidth = ConvertValue(nNewValue, 0, nOldDigits, FUNIT_TWIP, FUNIT_TWIP);
193         }
194         else
195         {
196             sal_Int64 nValue = Convert(nNewValue, eInUnit, eOldUnit);
197             nAktWidth = ConvertValue(nValue, 0, nOldDigits, eOldUnit, FUNIT_TWIP);
198         }
199         nPercent = ((nAktWidth * 10) / nRefValue + 5) / 10;
200         MetricField::SetUserValue(nPercent,FUNIT_NONE);
201     }
202 
203 }
204 
205 /*--------------------------------------------------------------------
206     Beschreibung:
207  --------------------------------------------------------------------*/
208 
209 void PercentField::SetBaseValue(sal_Int64 nNewValue, FieldUnit eInUnit)
210 {
211     if (GetUnit() == FUNIT_CUSTOM)
212         nOldBaseValue = ConvertValue(nNewValue, 0, nOldDigits, eInUnit, eOldUnit);
213     else
214         MetricField::SetBaseValue(nNewValue, eInUnit);
215 }
216 
217 /*--------------------------------------------------------------------
218     Beschreibung:
219  --------------------------------------------------------------------*/
220 
221 sal_Int64 PercentField::GetValue( FieldUnit eOutUnit )
222 {
223     return Convert(MetricField::GetValue(), GetUnit(), eOutUnit);
224 }
225 
226 /*--------------------------------------------------------------------
227     Beschreibung:
228  --------------------------------------------------------------------*/
229 
230 void PercentField::SetMin(sal_Int64 nNewMin, FieldUnit eInUnit)
231 {
232     if (GetUnit() != FUNIT_CUSTOM)
233         MetricField::SetMin(nNewMin, eInUnit);
234     else
235     {
236         if (eInUnit == FUNIT_NONE)
237             eInUnit = eOldUnit;
238         nOldMin = Convert(nNewMin, eInUnit, eOldUnit);
239 
240         sal_Int64 nPercent = Convert(nNewMin, eInUnit, FUNIT_CUSTOM);
241         MetricField::SetMin(Max( static_cast< sal_Int64 >(1), nPercent));
242     }
243 }
244 
245 /*--------------------------------------------------------------------
246     Beschreibung:
247  --------------------------------------------------------------------*/
248 
249 void PercentField::SetMax(sal_Int64 nNewMax, FieldUnit eInUnit)
250 {
251     if (GetUnit() != FUNIT_CUSTOM)
252         MetricField::SetMax(nNewMax, eInUnit);
253     else
254     {
255         if (eInUnit == FUNIT_NONE)
256             eInUnit = eOldUnit;
257 //      SetRefValue(Convert(nNewMax, eInUnit, FUNIT_TWIP));
258     }
259 }
260 
261 /*--------------------------------------------------------------------
262     Beschreibung:
263  --------------------------------------------------------------------*/
264 
265 sal_Int64 PercentField::NormalizePercent(sal_Int64 nValue)
266 {
267     if (GetUnit() != FUNIT_CUSTOM)
268         nValue = MetricField::Normalize(nValue);
269     else
270         nValue = nValue * ImpPower10(nOldDigits);
271 
272     return nValue;
273 }
274 
275 /*--------------------------------------------------------------------
276     Beschreibung:
277  --------------------------------------------------------------------*/
278 
279 sal_Int64 PercentField::DenormalizePercent(sal_Int64 nValue)
280 {
281     if (GetUnit() != FUNIT_CUSTOM)
282         nValue = MetricField::Denormalize(nValue);
283     else
284     {
285         sal_Int64 nFactor = ImpPower10(nOldDigits);
286         nValue = ((nValue+(nFactor/2)) / nFactor);
287     }
288 
289     return nValue;
290 }
291 
292 /*--------------------------------------------------------------------
293     Beschreibung:
294  --------------------------------------------------------------------*/
295 
296 sal_Bool PercentField::IsValueModified()
297 {
298     if (GetUnit() == FUNIT_CUSTOM)
299         return sal_True;
300     else
301         return MetricField::IsValueModified();
302 }
303 
304 /*--------------------------------------------------------------------
305     Beschreibung:
306  --------------------------------------------------------------------*/
307 
308 sal_Int64 PercentField::ImpPower10( sal_uInt16 n )
309 {
310     sal_uInt16 i;
311     sal_Int64   nValue = 1;
312 
313     for ( i=0; i < n; i++ )
314         nValue *= 10;
315 
316     return nValue;
317 }
318 
319 /*--------------------------------------------------------------------
320     Beschreibung:
321  --------------------------------------------------------------------*/
322 
323 sal_Int64 PercentField::GetRealValue(FieldUnit eOutUnit)
324 {
325     if (GetUnit() != FUNIT_CUSTOM)
326         return GetValue(eOutUnit);
327     else
328         return Convert(GetValue(), GetUnit(), eOutUnit);
329 }
330 
331 /*--------------------------------------------------------------------
332     Beschreibung:
333  --------------------------------------------------------------------*/
334 
335 sal_Int64 PercentField::Convert(sal_Int64 nValue, FieldUnit eInUnit, FieldUnit eOutUnit)
336 {
337     if (eInUnit == eOutUnit ||
338         (eInUnit == FUNIT_NONE && eOutUnit == GetUnit()) ||
339         (eOutUnit == FUNIT_NONE && eInUnit == GetUnit()))
340         return nValue;
341 
342     if (eInUnit == FUNIT_CUSTOM)
343     {
344         // Umrechnen in Metrik
345         sal_Int64 nTwipValue = (nRefValue * nValue + 50) / 100;
346 
347         if (eOutUnit == FUNIT_TWIP) // Nur wandeln, wenn unbedingt notwendig
348             return NormalizePercent(nTwipValue);
349         else
350             return ConvertValue(NormalizePercent(nTwipValue), 0, nOldDigits, FUNIT_TWIP, eOutUnit);
351     }
352 
353     if (eOutUnit == FUNIT_CUSTOM)
354     {
355         // Umrechnen in Prozent
356         sal_Int64 nAktWidth;
357         nValue = DenormalizePercent(nValue);
358 
359         if (eInUnit == FUNIT_TWIP)  // Nur wandeln, wenn unbedingt notwendig
360             nAktWidth = nValue;
361         else
362             nAktWidth = ConvertValue(nValue, 0, nOldDigits, eInUnit, FUNIT_TWIP);
363         // Um 0.5 Prozent runden
364         return ((nAktWidth * 1000) / nRefValue + 5) / 10;
365     }
366 
367     return ConvertValue(nValue, 0, nOldDigits, eInUnit, eOutUnit);
368 }
369 
370 
371