xref: /aoo42x/main/sw/source/ui/utlui/prcntfld.cxx (revision cdf0e10c)
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