LibreOffice Module sw (master)  1
prcntfld.cxx
Go to the documentation of this file.
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 SwPercentField::SwPercentField(std::unique_ptr<weld::MetricSpinButton> pControl)
23  : m_pField(std::move(pControl))
24  , nOldMax(0)
25  , nOldMin(0)
26  , nLastPercent(-1)
27  , nLastValue(-1)
28  , nOldDigits(m_pField->get_digits())
29  , eOldUnit(FieldUnit::NONE)
30  , bLockAutoCalculation(false)
31 {
32  int nMin, nMax;
33  m_pField->get_range(nMin, nMax, FieldUnit::TWIP);
35  m_pField->get_increments(nOldSpinSize, nOldPageSize, FieldUnit::NONE);
36 }
37 
39 {
40  int nRealValue = GetRealValue(eOldUnit);
41 
42  nRefValue = nValue;
43 
44  if (!bLockAutoCalculation && (m_pField->get_unit() == FieldUnit::PERCENT))
45  set_value(nRealValue, eOldUnit);
46 }
47 
48 void SwPercentField::ShowPercent(bool bPercent)
49 {
50  if ((bPercent && m_pField->get_unit() == FieldUnit::PERCENT) ||
51  (!bPercent && m_pField->get_unit() != FieldUnit::PERCENT))
52  return;
53 
54  int nOldValue;
55 
56  if (bPercent)
57  {
58  nOldValue = get_value();
59 
60  eOldUnit = m_pField->get_unit();
61  nOldDigits = m_pField->get_digits();
62  m_pField->get_range(nOldMin, nOldMax, FieldUnit::NONE);
63  m_pField->get_increments(nOldSpinSize, nOldPageSize, FieldUnit::NONE);
64  m_pField->set_unit(FieldUnit::PERCENT);
65  m_pField->set_digits(0);
66 
67  int nCurrentWidth = MetricField::ConvertValue(nOldMin, 0, nOldDigits, eOldUnit, FieldUnit::TWIP);
68  // round to 0.5 percent
69  int nPercent = nRefValue ? (((nCurrentWidth * 10) / nRefValue + 5) / 10) : 0;
70 
71  m_pField->set_range(std::max(1, nPercent), 100, FieldUnit::NONE);
72  m_pField->set_increments(5, 10, FieldUnit::NONE);
73  if (nOldValue != nLastValue)
74  {
75  nCurrentWidth = MetricField::ConvertValue(nOldValue, 0, nOldDigits, eOldUnit, FieldUnit::TWIP);
76  nPercent = nRefValue ? (((nCurrentWidth * 10) / nRefValue + 5) / 10) : 0;
77  m_pField->set_value(nPercent, FieldUnit::NONE);
78  nLastPercent = nPercent;
79  nLastValue = nOldValue;
80  }
81  else
82  m_pField->set_value(nLastPercent, FieldUnit::NONE);
83  }
84  else
85  {
86  int nOldPercent = get_value(FieldUnit::PERCENT);
87 
88  nOldValue = Convert(get_value(), m_pField->get_unit(), eOldUnit);
89 
90  m_pField->set_unit(eOldUnit);
91  m_pField->set_digits(nOldDigits);
92  m_pField->set_range(nOldMin, nOldMax, FieldUnit::NONE);
93  m_pField->set_increments(nOldSpinSize, nOldPageSize, FieldUnit::NONE);
94 
95  if (nOldPercent != nLastPercent)
96  {
97  set_value(nOldValue, eOldUnit);
98  nLastPercent = nOldPercent;
99  nLastValue = nOldValue;
100  }
101  else
103  }
104 }
105 
106 void SwPercentField::set_value(int nNewValue, FieldUnit eInUnit)
107 {
108  if (m_pField->get_unit() != FieldUnit::PERCENT || eInUnit == FieldUnit::PERCENT)
109  m_pField->set_value(Convert(nNewValue, eInUnit, m_pField->get_unit()), FieldUnit::NONE);
110  else
111  {
112  // Overwrite output value, do not restore later
113  int nPercent, nCurrentWidth;
114  if(eInUnit == FieldUnit::TWIP)
115  {
116  nCurrentWidth = MetricField::ConvertValue(nNewValue, 0, nOldDigits, FieldUnit::TWIP, FieldUnit::TWIP);
117  }
118  else
119  {
120  int nValue = Convert(nNewValue, eInUnit, eOldUnit);
121  nCurrentWidth = MetricField::ConvertValue(nValue, 0, nOldDigits, eOldUnit, FieldUnit::TWIP);
122  }
123  nPercent = nRefValue ? (((nCurrentWidth * 10) / nRefValue + 5) / 10) : 0;
124  m_pField->set_value(nPercent, FieldUnit::NONE);
125  }
126 }
127 
129 {
130  return Convert(m_pField->get_value(FieldUnit::NONE), m_pField->get_unit(), eOutUnit);
131 }
132 
133 void SwPercentField::set_min(int nNewMin, FieldUnit eInUnit)
134 {
135  if (m_pField->get_unit() != FieldUnit::PERCENT)
136  m_pField->set_min(nNewMin, eInUnit);
137  else
138  {
139  if (eInUnit == FieldUnit::NONE)
140  eInUnit = eOldUnit;
141  nOldMin = Convert(nNewMin, eInUnit, eOldUnit);
142 
143  int nPercent = Convert(nNewMin, eInUnit, FieldUnit::PERCENT);
144  m_pField->set_min(std::max(1, nPercent), FieldUnit::NONE);
145  }
146 }
147 
148 void SwPercentField::set_max(int nNewMax, FieldUnit eInUnit)
149 {
150  if (m_pField->get_unit() != FieldUnit::PERCENT)
151  m_pField->set_max(nNewMax, eInUnit);
152 }
153 
155 {
156  if (m_pField->get_unit() != FieldUnit::PERCENT)
157  nValue = m_pField->normalize(nValue);
158  else
159  nValue = nValue * ImpPower10(nOldDigits);
160  return nValue;
161 }
162 
164 {
165  if (m_pField->get_unit() != FieldUnit::PERCENT)
166  nValue = m_pField->denormalize(nValue);
167  else
168  {
169  int nFactor = ImpPower10(nOldDigits);
170  nValue = ((nValue+(nFactor/2)) / nFactor);
171  }
172  return nValue;
173 }
174 
175 int SwPercentField::ImpPower10(sal_uInt16 n)
176 {
177  int nValue = 1;
178 
179  for (sal_uInt16 i=0; i < n; ++i)
180  nValue *= 10;
181 
182  return nValue;
183 }
184 
186 {
187  if (m_pField->get_unit() != FieldUnit::PERCENT)
188  return get_value(eOutUnit);
189  else
190  return Convert(get_value(), m_pField->get_unit(), eOutUnit);
191 }
192 
193 int SwPercentField::Convert(int nValue, FieldUnit eInUnit, FieldUnit eOutUnit)
194 {
195  if (eInUnit == eOutUnit ||
196  (eInUnit == FieldUnit::NONE && eOutUnit == m_pField->get_unit()) ||
197  (eOutUnit == FieldUnit::NONE && eInUnit == m_pField->get_unit()))
198  return nValue;
199 
200  if (eInUnit == FieldUnit::PERCENT)
201  {
202  // Convert to metric
203  int nTwipValue = (nRefValue * nValue + 50) / 100;
204 
205  if (eOutUnit == FieldUnit::TWIP) // Only convert if necessary
206  return NormalizePercent(nTwipValue);
207  else
208  return MetricField::ConvertValue(NormalizePercent(nTwipValue), 0, nOldDigits, FieldUnit::TWIP, eOutUnit);
209  }
210 
211  if (eOutUnit == FieldUnit::PERCENT)
212  {
213  // Convert to percent
214  int nCurrentWidth;
215  nValue = DenormalizePercent(nValue);
216 
217  if (eInUnit == FieldUnit::TWIP) // Only convert if necessary
218  nCurrentWidth = nValue;
219  else
220  nCurrentWidth = MetricField::ConvertValue(nValue, 0, nOldDigits, eInUnit, FieldUnit::TWIP);
221  // Round to 0.5 percent
222  return nRefValue ? (((nCurrentWidth * 1000) / nRefValue + 5) / 10) : 0;
223  }
224 
225  return MetricField::ConvertValue(nValue, 0, nOldDigits, eInUnit, eOutUnit);
226 }
227 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
FieldUnit
int Convert(int nValue, FieldUnit eInUnit, FieldUnit eOutUnit)
Definition: prcntfld.cxx:193
void SetRefValue(int nValue)
Definition: prcntfld.cxx:38
void ShowPercent(bool bPercent)
Definition: prcntfld.cxx:48
bool bLockAutoCalculation
Definition: prcntfld.hxx:41
void set_min(int nNewMin, FieldUnit eInUnit)
Definition: prcntfld.cxx:133
std::unique_ptr< weld::MetricSpinButton > m_pField
Definition: prcntfld.hxx:30
SwPercentField(std::unique_ptr< weld::MetricSpinButton > pControl)
Definition: prcntfld.cxx:22
void set_value(int nNewValue, FieldUnit eInUnit=FieldUnit::NONE)
Definition: prcntfld.cxx:106
FieldUnit eOldUnit
Definition: prcntfld.hxx:40
void set_max(int nNewMax, FieldUnit eInUnit)
Definition: prcntfld.cxx:148
int NormalizePercent(int nValue)
Definition: prcntfld.cxx:154
int get_value(FieldUnit eOutUnit=FieldUnit::NONE)
Definition: prcntfld.cxx:128
int i
int GetRealValue(FieldUnit eOutUnit)
Definition: prcntfld.cxx:185
static sal_Int64 ConvertValue(sal_Int64 nValue, sal_Int64 mnBaseValue, sal_uInt16 nDecDigits, FieldUnit eInUnit, FieldUnit eOutUnit)
int DenormalizePercent(int nValue)
Definition: prcntfld.cxx:163
sal_uInt16 nOldDigits
Definition: prcntfld.hxx:39
static SAL_DLLPRIVATE int ImpPower10(sal_uInt16 n)
Definition: prcntfld.cxx:175