summaryrefslogtreecommitdiff
path: root/sw/source/uibase/utlui/prcntfld.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/uibase/utlui/prcntfld.cxx')
-rw-r--r--sw/source/uibase/utlui/prcntfld.cxx287
1 files changed, 287 insertions, 0 deletions
diff --git a/sw/source/uibase/utlui/prcntfld.cxx b/sw/source/uibase/utlui/prcntfld.cxx
new file mode 100644
index 000000000000..cd4863753d10
--- /dev/null
+++ b/sw/source/uibase/utlui/prcntfld.cxx
@@ -0,0 +1,287 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "prcntfld.hxx"
+
+PercentField::PercentField()
+ : m_pField(NULL)
+ , nRefValue(0)
+ , nOldMax(0)
+ , nOldMin(0)
+ , nOldSpinSize(0)
+ , nOldBaseValue(0)
+ , nLastPercent(-1)
+ , nLastValue(-1)
+ , nOldDigits(0)
+ , eOldUnit(FUNIT_NONE)
+ , bLockAutoCalculation(false)
+{
+}
+
+void PercentField::set(MetricField *pField)
+{
+ m_pField = pField;
+ nOldSpinSize = m_pField->GetSpinSize();
+ nRefValue = DenormalizePercent(m_pField->GetMax(FUNIT_TWIP));
+ nOldDigits = m_pField->GetDecimalDigits();
+ m_pField->SetCustomUnitText(OUString('%'));
+}
+
+void PercentField::SetRefValue(sal_Int64 nValue)
+{
+ sal_Int64 nRealValue = GetRealValue(eOldUnit);
+
+ nRefValue = nValue;
+
+ if (!bLockAutoCalculation && (m_pField->GetUnit() == FUNIT_CUSTOM))
+ SetPrcntValue(nRealValue, eOldUnit);
+}
+
+void PercentField::ShowPercent(bool bPercent)
+{
+ if ((bPercent && m_pField->GetUnit() == FUNIT_CUSTOM) ||
+ (!bPercent && m_pField->GetUnit() != FUNIT_CUSTOM))
+ return;
+
+ sal_Int64 nOldValue;
+
+ if (bPercent)
+ {
+ sal_Int64 nAktWidth, nPercent;
+
+ nOldValue = GetValue();
+
+ eOldUnit = m_pField->GetUnit();
+ nOldDigits = m_pField->GetDecimalDigits();
+ nOldMin = m_pField->GetMin();
+ nOldMax = m_pField->GetMax();
+ nOldSpinSize = m_pField->GetSpinSize();
+ nOldBaseValue = m_pField->GetBaseValue();
+ m_pField->SetUnit(FUNIT_CUSTOM);
+ m_pField->SetDecimalDigits( 0 );
+
+ nAktWidth = m_pField->ConvertValue(nOldMin, 0, nOldDigits, eOldUnit, FUNIT_TWIP);
+ // round to 0.5 percent
+ nPercent = ((nAktWidth * 10) / nRefValue + 5) / 10;
+
+ m_pField->SetMin(std::max(static_cast< sal_Int64 >(1), nPercent));
+ m_pField->SetMax(100);
+ m_pField->SetSpinSize(5);
+ m_pField->SetBaseValue(0);
+ if (nOldValue != nLastValue)
+ {
+ nAktWidth = m_pField->ConvertValue(nOldValue, 0, nOldDigits, eOldUnit, FUNIT_TWIP);
+ nPercent = ((nAktWidth * 10) / nRefValue + 5) / 10;
+ m_pField->SetValue(nPercent);
+ nLastPercent = nPercent;
+ nLastValue = nOldValue;
+ }
+ else
+ m_pField->SetValue(nLastPercent);
+ }
+ else
+ {
+ sal_Int64 nOldPercent = GetValue(FUNIT_CUSTOM);
+
+ nOldValue = Convert(GetValue(), m_pField->GetUnit(), eOldUnit);
+
+ m_pField->SetUnit(eOldUnit);
+ m_pField->SetDecimalDigits(nOldDigits);
+ m_pField->SetMin(nOldMin);
+ m_pField->SetMax(nOldMax);
+ m_pField->SetSpinSize(nOldSpinSize);
+ m_pField->SetBaseValue(nOldBaseValue);
+
+ if (nOldPercent != nLastPercent)
+ {
+ SetPrcntValue(nOldValue, eOldUnit);
+ nLastPercent = nOldPercent;
+ nLastValue = nOldValue;
+ }
+ else
+ SetPrcntValue(nLastValue, eOldUnit);
+ }
+}
+
+void PercentField::SetPrcntValue(sal_Int64 nNewValue, FieldUnit eInUnit)
+{
+ if (m_pField->GetUnit() != FUNIT_CUSTOM || eInUnit == FUNIT_CUSTOM)
+ m_pField->SetValue(Convert(nNewValue, eInUnit, m_pField->GetUnit()));
+ else
+ {
+ // Overwrite output value, do not restore later
+ sal_Int64 nPercent, nAktWidth;
+ if(eInUnit == FUNIT_TWIP)
+ {
+ nAktWidth = m_pField->ConvertValue(nNewValue, 0, nOldDigits, FUNIT_TWIP, FUNIT_TWIP);
+ }
+ else
+ {
+ sal_Int64 nValue = Convert(nNewValue, eInUnit, eOldUnit);
+ nAktWidth = m_pField->ConvertValue(nValue, 0, nOldDigits, eOldUnit, FUNIT_TWIP);
+ }
+ nPercent = ((nAktWidth * 10) / nRefValue + 5) / 10;
+ m_pField->SetValue(nPercent);
+ }
+}
+
+void PercentField::SetBaseValue(sal_Int64 nNewValue, FieldUnit eInUnit)
+{
+ if (m_pField->GetUnit() == FUNIT_CUSTOM)
+ nOldBaseValue = m_pField->ConvertValue(nNewValue, 0, nOldDigits, eInUnit, eOldUnit);
+ else
+ m_pField->SetBaseValue(nNewValue, eInUnit);
+}
+
+sal_Int64 PercentField::GetValue(FieldUnit eOutUnit)
+{
+ return Convert(m_pField->GetValue(), m_pField->GetUnit(), eOutUnit);
+}
+
+void PercentField::SetMin(sal_Int64 nNewMin, FieldUnit eInUnit)
+{
+ if (m_pField->GetUnit() != FUNIT_CUSTOM)
+ m_pField->SetMin(nNewMin, eInUnit);
+ else
+ {
+ if (eInUnit == FUNIT_NONE)
+ eInUnit = eOldUnit;
+ nOldMin = Convert(nNewMin, eInUnit, eOldUnit);
+
+ sal_Int64 nPercent = Convert(nNewMin, eInUnit, FUNIT_CUSTOM);
+ m_pField->SetMin(std::max( static_cast< sal_Int64 >(1), nPercent));
+ }
+}
+
+void PercentField::SetMax(sal_Int64 nNewMax, FieldUnit eInUnit)
+{
+ if (m_pField->GetUnit() != FUNIT_CUSTOM)
+ m_pField->SetMax(nNewMax, eInUnit);
+ else
+ {
+ if (eInUnit == FUNIT_NONE)
+ eInUnit = eOldUnit;
+ }
+}
+
+sal_Int64 PercentField::NormalizePercent(sal_Int64 nValue)
+{
+ if (m_pField->GetUnit() != FUNIT_CUSTOM)
+ nValue = m_pField->Normalize(nValue);
+ else
+ nValue = nValue * ImpPower10(nOldDigits);
+ return nValue;
+}
+
+sal_Int64 PercentField::DenormalizePercent(sal_Int64 nValue)
+{
+ if (m_pField->GetUnit() != FUNIT_CUSTOM)
+ nValue = m_pField->Denormalize(nValue);
+ else
+ {
+ sal_Int64 nFactor = ImpPower10(nOldDigits);
+ nValue = ((nValue+(nFactor/2)) / nFactor);
+ }
+ return nValue;
+}
+
+bool PercentField::IsValueModified()
+{
+ if (m_pField->GetUnit() == FUNIT_CUSTOM)
+ return true;
+ else
+ return m_pField->IsValueModified();
+}
+
+void PercentField::SetUserValue(sal_Int64 nNewValue, FieldUnit eInUnit)
+{
+ if (m_pField->GetUnit() != FUNIT_CUSTOM || eInUnit == FUNIT_CUSTOM)
+ m_pField->SetUserValue(Convert(nNewValue, eInUnit, m_pField->GetUnit()),FUNIT_NONE);
+ else
+ {
+ // Overwrite output value, do not restore later
+ sal_Int64 nPercent, nAktWidth;
+ if (eInUnit == FUNIT_TWIP)
+ {
+ nAktWidth = m_pField->ConvertValue(nNewValue, 0, nOldDigits, FUNIT_TWIP, FUNIT_TWIP);
+ }
+ else
+ {
+ sal_Int64 nValue = Convert(nNewValue, eInUnit, eOldUnit);
+ nAktWidth = m_pField->ConvertValue(nValue, 0, nOldDigits, eOldUnit, FUNIT_TWIP);
+ }
+ nPercent = ((nAktWidth * 10) / nRefValue + 5) / 10;
+ m_pField->SetUserValue(nPercent,FUNIT_NONE);
+ }
+}
+
+sal_Int64 PercentField::ImpPower10(sal_uInt16 n)
+{
+ sal_Int64 nValue = 1;
+
+ for (sal_uInt16 i=0; i < n; ++i)
+ nValue *= 10;
+
+ return nValue;
+}
+
+sal_Int64 PercentField::GetRealValue(FieldUnit eOutUnit)
+{
+ if (m_pField->GetUnit() != FUNIT_CUSTOM)
+ return GetValue(eOutUnit);
+ else
+ return Convert(GetValue(), m_pField->GetUnit(), eOutUnit);
+}
+
+sal_Int64 PercentField::Convert(sal_Int64 nValue, FieldUnit eInUnit, FieldUnit eOutUnit)
+{
+ if (eInUnit == eOutUnit ||
+ (eInUnit == FUNIT_NONE && eOutUnit == m_pField->GetUnit()) ||
+ (eOutUnit == FUNIT_NONE && eInUnit == m_pField->GetUnit()))
+ return nValue;
+
+ if (eInUnit == FUNIT_CUSTOM)
+ {
+ // Convert to metric
+ sal_Int64 nTwipValue = (nRefValue * nValue + 50) / 100;
+
+ if (eOutUnit == FUNIT_TWIP) // Only convert if necessary
+ return NormalizePercent(nTwipValue);
+ else
+ return m_pField->ConvertValue(NormalizePercent(nTwipValue), 0, nOldDigits, FUNIT_TWIP, eOutUnit);
+ }
+
+ if (eOutUnit == FUNIT_CUSTOM)
+ {
+ // Convert to percent
+ sal_Int64 nAktWidth;
+ nValue = DenormalizePercent(nValue);
+
+ if (eInUnit == FUNIT_TWIP) // Only convert if necessary
+ nAktWidth = nValue;
+ else
+ nAktWidth = m_pField->ConvertValue(nValue, 0, nOldDigits, eInUnit, FUNIT_TWIP);
+ // Round to 0.5 percent
+ return ((nAktWidth * 1000) / nRefValue + 5) / 10;
+ }
+
+ return m_pField->ConvertValue(nValue, 0, nOldDigits, eInUnit, eOutUnit);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */