diff options
author | Caolán McNamara <caolanm@redhat.com> | 2012-12-20 11:58:29 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2012-12-20 16:52:57 +0000 |
commit | 2ecf108c23c041619bb8b25338dca84ff89fe8eb (patch) | |
tree | 03c38030fdc2a546707c428d23feb98727d19113 | |
parent | 3c70c8e449253b4219c12ee4ef50384030a474ef (diff) |
make a PercentFieldWrap that wraps a MetricField
rather than inheriting from one, which means
we don't need yet-another-custom-widget
Change-Id: Iddaeedfe45fb06ee72e59143974c9a4d0d2478f6
-rw-r--r-- | sw/source/ui/inc/prcntfld.hxx | 68 | ||||
-rw-r--r-- | sw/source/ui/utlui/prcntfld.cxx | 223 |
2 files changed, 291 insertions, 0 deletions
diff --git a/sw/source/ui/inc/prcntfld.hxx b/sw/source/ui/inc/prcntfld.hxx index e33a85cd72bc..d87fe600f039 100644 --- a/sw/source/ui/inc/prcntfld.hxx +++ b/sw/source/ui/inc/prcntfld.hxx @@ -21,6 +21,74 @@ #include <vcl/field.hxx> #include "swdllapi.h" +#include "uitool.hxx" + +//Wraps a MetricField with extra features, preferred to PercentField +class SW_DLLPUBLIC PercentFieldWrap +{ + MetricField* m_pField; + + sal_Int64 nRefValue; // 100% value for conversion (in Twips) + sal_Int64 nOldMax; + sal_Int64 nOldMin; + sal_Int64 nOldSpinSize; + sal_Int64 nOldBaseValue; + sal_Int64 nLastPercent; + sal_Int64 nLastValue; + sal_uInt16 nOldDigits; + FieldUnit eOldUnit; + bool bLockAutoCalculation; //prevent recalcution of percent values when the + //reference value is changed + + SW_DLLPRIVATE sal_Int64 ImpPower10(sal_uInt16 n); + +public: + + PercentFieldWrap(); + void set(MetricField *pField); + void SetUpHdl(const Link& rLink) { m_pField->SetUpHdl(rLink); } + void SetDownHdl(const Link& rLink) { m_pField->SetDownHdl(rLink); } + void SetLoseFocusHdl(const Link& rLink) { m_pField->SetLoseFocusHdl(rLink); } + void SetMetric(FieldUnit eUnit) { ::SetMetric(*m_pField, eUnit); } + void Enable(bool bEnable = true, bool bChild = true) { m_pField->Enable(bEnable, bChild); } + void SetAccessibleName(const OUString& rName) { m_pField->SetAccessibleName(rName); } + void SetText(const OUString& rStr) { m_pField->SetText(rStr); } + void SetMetricFieldMin(sal_Int64 nNewMin) { m_pField->SetMin(nNewMin); } + void SetMetricFieldMax(sal_Int64 nNewMax) { m_pField->SetMax(nNewMax); } + + void SetValue(sal_Int64 nNewValue, FieldUnit eInUnit = FUNIT_NONE); + + void SetPrcntValue(sal_Int64 nNewValue, FieldUnit eInUnit = FUNIT_NONE); + + void SetUserValue(sal_Int64 nNewValue, FieldUnit eInUnit = FUNIT_NONE); + + void SetBaseValue(sal_Int64 nNewValue, FieldUnit eInUnit = FUNIT_NONE); + + sal_Int64 GetValue(FieldUnit eOutUnit = FUNIT_NONE); + + bool IsValueModified(); + + void SetMax(sal_Int64 nNewMax, FieldUnit eInUnit = FUNIT_NONE); + + void SetMin(sal_Int64 nNewMin, FieldUnit eInUnit = FUNIT_NONE); + + sal_Int64 NormalizePercent(sal_Int64 nValue); + sal_Int64 DenormalizePercent(sal_Int64 nValue); + + void SetRefValue(sal_Int64 nValue); + sal_Int64 GetRefValue() const { return nRefValue; } + sal_Int64 GetRealValue(FieldUnit eOutUnit = FUNIT_NONE); + + sal_Int64 Convert(sal_Int64 nValue, FieldUnit eInUnit, FieldUnit eOutUnit); + + void ShowPercent(bool bPercent); + + sal_uInt16 GetOldDigits() const {return nOldDigits;} + + void LockAutoCalculation(bool bLock) {bLockAutoCalculation = bLock;} + bool IsAutoCalculationLocked() const {return bLockAutoCalculation;} +}; + class SW_DLLPUBLIC PercentField : public MetricField { diff --git a/sw/source/ui/utlui/prcntfld.cxx b/sw/source/ui/utlui/prcntfld.cxx index 92401e91223a..0c682f88c9a1 100644 --- a/sw/source/ui/utlui/prcntfld.cxx +++ b/sw/source/ui/utlui/prcntfld.cxx @@ -37,6 +37,25 @@ PercentField::PercentField( Window* pWin, const ResId& rResId ) : SetCustomUnitText(rtl::OUString('%')); } +PercentFieldWrap::PercentFieldWrap() + : nOldMax(0) + , nOldMin(0) + , nLastPercent(-1) + , nLastValue(-1) + , eOldUnit(FUNIT_NONE) + , bLockAutoCalculation(sal_False) +{ +} + +void PercentFieldWrap::set(MetricField *pField) +{ + m_pField = pField; + nOldSpinSize = m_pField->GetSpinSize(); + nRefValue = DenormalizePercent(m_pField->GetMax(FUNIT_TWIP)); + nOldDigits = m_pField->GetDecimalDigits(); + m_pField->SetCustomUnitText(rtl::OUString('%')); +} + void PercentField::SetRefValue(sal_Int64 nValue) { sal_Int64 nRealValue = GetRealValue(eOldUnit); @@ -47,6 +66,16 @@ void PercentField::SetRefValue(sal_Int64 nValue) SetPrcntValue(nRealValue, eOldUnit); } +void PercentFieldWrap::SetRefValue(sal_Int64 nValue) +{ + sal_Int64 nRealValue = GetRealValue(eOldUnit); + + nRefValue = nValue; + + if (!bLockAutoCalculation && (m_pField->GetUnit() == FUNIT_CUSTOM)) + SetPrcntValue(nRealValue, eOldUnit); +} + void PercentField::ShowPercent(sal_Bool bPercent) { if ((bPercent && GetUnit() == FUNIT_CUSTOM) || @@ -113,6 +142,72 @@ void PercentField::ShowPercent(sal_Bool bPercent) } } +void PercentFieldWrap::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(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::SetValue(sal_Int64 nNewValue, FieldUnit eInUnit) { MetricFormatter::SetValue(nNewValue, eInUnit); @@ -141,6 +236,28 @@ void PercentField::SetPrcntValue(sal_Int64 nNewValue, FieldUnit eInUnit) } } +void PercentFieldWrap::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 + { + // Ausgangswert ueberschreiben, nicht spaeter restaurieren + 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::SetUserValue( sal_Int64 nNewValue, FieldUnit eInUnit ) { if (GetUnit() != FUNIT_CUSTOM || eInUnit == FUNIT_CUSTOM) @@ -178,6 +295,11 @@ sal_Int64 PercentField::GetValue( FieldUnit eOutUnit ) return Convert(MetricField::GetValue(), GetUnit(), eOutUnit); } +sal_Int64 PercentFieldWrap::GetValue(FieldUnit eOutUnit) +{ + return Convert(m_pField->GetValue(), m_pField->GetUnit(), eOutUnit); +} + void PercentField::SetMin(sal_Int64 nNewMin, FieldUnit eInUnit) { if (GetUnit() != FUNIT_CUSTOM) @@ -193,6 +315,21 @@ void PercentField::SetMin(sal_Int64 nNewMin, FieldUnit eInUnit) } } +void PercentFieldWrap::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(Max( static_cast< sal_Int64 >(1), nPercent)); + } +} + void PercentField::SetMax(sal_Int64 nNewMax, FieldUnit eInUnit) { if (GetUnit() != FUNIT_CUSTOM) @@ -204,6 +341,17 @@ void PercentField::SetMax(sal_Int64 nNewMax, FieldUnit eInUnit) } } +void PercentFieldWrap::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 (GetUnit() != FUNIT_CUSTOM) @@ -214,6 +362,15 @@ sal_Int64 PercentField::NormalizePercent(sal_Int64 nValue) return nValue; } +sal_Int64 PercentFieldWrap::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 (GetUnit() != FUNIT_CUSTOM) @@ -227,6 +384,18 @@ sal_Int64 PercentField::DenormalizePercent(sal_Int64 nValue) return nValue; } +sal_Int64 PercentFieldWrap::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; +} + sal_Bool PercentField::IsValueModified() { if (GetUnit() == FUNIT_CUSTOM) @@ -246,6 +415,16 @@ sal_Int64 PercentField::ImpPower10( sal_uInt16 n ) return nValue; } +sal_Int64 PercentFieldWrap::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 (GetUnit() != FUNIT_CUSTOM) @@ -254,6 +433,14 @@ sal_Int64 PercentField::GetRealValue(FieldUnit eOutUnit) return Convert(GetValue(), GetUnit(), eOutUnit); } +sal_Int64 PercentFieldWrap::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 || @@ -289,5 +476,41 @@ sal_Int64 PercentField::Convert(sal_Int64 nValue, FieldUnit eInUnit, FieldUnit e return ConvertValue(nValue, 0, nOldDigits, eInUnit, eOutUnit); } +sal_Int64 PercentFieldWrap::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) + { + // Umrechnen in Metrik + sal_Int64 nTwipValue = (nRefValue * nValue + 50) / 100; + + if (eOutUnit == FUNIT_TWIP) // Nur wandeln, wenn unbedingt notwendig + return NormalizePercent(nTwipValue); + else + return m_pField->ConvertValue(NormalizePercent(nTwipValue), 0, nOldDigits, FUNIT_TWIP, eOutUnit); + } + + if (eOutUnit == FUNIT_CUSTOM) + { + // Umrechnen in Prozent + sal_Int64 nAktWidth; + nValue = DenormalizePercent(nValue); + + if (eInUnit == FUNIT_TWIP) // Nur wandeln, wenn unbedingt notwendig + 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: */ |