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