summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2018-11-14 13:52:06 +0000
committerCaolán McNamara <caolanm@redhat.com>2018-11-15 18:17:35 +0100
commit4ce5d39689fda418e8f2d7d9c1124190b2cbad7a (patch)
tree1e261f9e2b305fbdf56e3784c6589efbd683755b /vcl
parent9e0a099fb66c303bec0489198ba7cfe770b28684 (diff)
bind SalInstanceSpinButton to FormattedField
Change-Id: I71190343739fae51b1c17d74ea1c4a548bca0b01 Reviewed-on: https://gerrit.libreoffice.org/63371 Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/source/app/salvtables.cxx41
-rw-r--r--vcl/source/control/field.cxx26
-rw-r--r--vcl/source/control/fmtfield.cxx145
-rw-r--r--vcl/source/window/builder.cxx62
4 files changed, 189 insertions, 85 deletions
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index d3d776278632..cd6f0fc39417 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -38,6 +38,7 @@
#include <vcl/lstbox.hxx>
#include <vcl/dialog.hxx>
#include <vcl/fixed.hxx>
+#include <vcl/fmtfield.hxx>
#include <vcl/layout.hxx>
#include <vcl/menubtn.hxx>
#include <vcl/prgsbar.hxx>
@@ -1963,19 +1964,29 @@ IMPL_LINK_NOARG(SalInstanceTreeView, DoubleClickHdl, SvTreeListBox*, bool)
class SalInstanceSpinButton : public SalInstanceEntry, public virtual weld::SpinButton
{
private:
- VclPtr<NumericField> m_xButton;
+ VclPtr<FormattedField> m_xButton;
DECL_LINK(UpDownHdl, SpinField&, void);
DECL_LINK(LoseFocusHdl, Control&, void);
DECL_LINK(OutputHdl, Edit&, bool);
DECL_LINK(InputHdl, sal_Int64*, TriState);
+ double toField(int nValue) const
+ {
+ return static_cast<double>(nValue) / Power10(get_digits());
+ }
+
+ int fromField(double fValue) const
+ {
+ return FRound(fValue * Power10(get_digits()));
+ }
+
public:
- SalInstanceSpinButton(NumericField* pButton, bool bTakeOwnership)
+ SalInstanceSpinButton(FormattedField* pButton, bool bTakeOwnership)
: SalInstanceEntry(pButton, bTakeOwnership)
, m_xButton(pButton)
{
- m_xButton->SetUseThousandSep(false); //off by default, MetricSpinButton enables it
+ m_xButton->SetThousandsSep(false); //off by default, MetricSpinButton enables it
m_xButton->SetUpHdl(LINK(this, SalInstanceSpinButton, UpDownHdl));
m_xButton->SetDownHdl(LINK(this, SalInstanceSpinButton, UpDownHdl));
m_xButton->SetLoseFocusHdl(LINK(this, SalInstanceSpinButton, LoseFocusHdl));
@@ -1985,37 +1996,35 @@ public:
virtual int get_value() const override
{
- return m_xButton->GetValue();
+ return fromField(m_xButton->GetValue());
}
virtual void set_value(int value) override
{
- m_xButton->SetValue(value);
+ m_xButton->SetValue(toField(value));
}
virtual void set_range(int min, int max) override
{
- m_xButton->SetMin(min);
- m_xButton->SetFirst(min);
- m_xButton->SetMax(max);
- m_xButton->SetLast(max);
+ m_xButton->SetMinValue(toField(min));
+ m_xButton->SetMaxValue(toField(max));
}
virtual void get_range(int& min, int& max) const override
{
- min = m_xButton->GetMin();
- max = m_xButton->GetMax();
+ min = fromField(m_xButton->GetMinValue());
+ max = fromField(m_xButton->GetMaxValue());
}
virtual void set_increments(int step, int /*page*/) override
{
- m_xButton->SetSpinSize(step);
+ m_xButton->SetSpinSize(toField(step));
}
virtual void get_increments(int& step, int& page) const override
{
- step = m_xButton->GetSpinSize();
- page = m_xButton->GetSpinSize();
+ step = fromField(m_xButton->GetSpinSize());
+ page = fromField(m_xButton->GetSpinSize());
}
virtual void set_digits(unsigned int digits) override
@@ -2032,7 +2041,7 @@ public:
//off by default for direct SpinButtons, MetricSpinButton enables it
void SetUseThousandSep()
{
- m_xButton->SetUseThousandSep(true);
+ m_xButton->SetThousandsSep(true);
}
virtual unsigned int get_digits() const override
@@ -2915,7 +2924,7 @@ public:
virtual std::unique_ptr<weld::SpinButton> weld_spin_button(const OString &id, bool bTakeOwnership) override
{
- NumericField* pSpinButton = m_xBuilder->get<NumericField>(id);
+ FormattedField* pSpinButton = m_xBuilder->get<FormattedField>(id);
return pSpinButton ? o3tl::make_unique<SalInstanceSpinButton>(pSpinButton, bTakeOwnership) : nullptr;
}
diff --git a/vcl/source/control/field.cxx b/vcl/source/control/field.cxx
index 8cf40c6e7682..519eb8aa5a49 100644
--- a/vcl/source/control/field.cxx
+++ b/vcl/source/control/field.cxx
@@ -454,8 +454,7 @@ bool FormatterBase::IsEmptyFieldValue() const
void NumericFormatter::FormatValue(Selection const * pNewSelection)
{
mbFormatting = true;
- if (!m_aOutputHdl.IsSet() || !m_aOutputHdl.Call(*GetField()))
- ImplSetText(CreateFieldText(mnLastValue), pNewSelection);
+ ImplSetText(CreateFieldText(mnLastValue), pNewSelection);
mbFormatting = false;
}
@@ -478,7 +477,6 @@ void NumericFormatter::ImplInit()
mbShowTrailingZeros = true;
mbWrapOnLimits = false;
mbFormatting = false;
- mbDisableRemainderFactor = false;
// for fields
mnSpinSize = 1;
@@ -578,19 +576,6 @@ sal_Int64 NumericFormatter::GetValue() const
if (mbFormatting) //don't parse the entry if we're currently formatting what to put in it
return mnLastValue;
- if (m_aInputHdl.IsSet())
- {
- sal_Int64 nResult;
- TriState eState = m_aInputHdl.Call(&nResult);
- if (eState != TRISTATE_INDET)
- {
- if (eState == TRISTATE_TRUE)
- return ClipAgainstMinMax(nResult);
- else
- return mnLastValue;
- }
- }
-
return GetField() ? GetValueFromString(GetField()->GetText()) : 0;
}
@@ -642,15 +627,10 @@ void NumericFormatter::Reformat()
ImplNumericReformat();
}
-void NumericFormatter::DisableRemainderFactor()
-{
- mbDisableRemainderFactor = true;
-}
-
void NumericFormatter::FieldUp()
{
sal_Int64 nValue = GetValue();
- sal_Int64 nRemainder = mbDisableRemainderFactor ? 0 : (nValue % mnSpinSize);
+ sal_Int64 nRemainder = nValue % mnSpinSize;
if (nValue >= 0)
nValue = (nRemainder == 0) ? nValue + mnSpinSize : nValue + mnSpinSize - nRemainder;
else
@@ -664,7 +644,7 @@ void NumericFormatter::FieldUp()
void NumericFormatter::FieldDown()
{
sal_Int64 nValue = GetValue();
- sal_Int64 nRemainder = mbDisableRemainderFactor ? 0 : (nValue % mnSpinSize);
+ sal_Int64 nRemainder = nValue % mnSpinSize;
if (nValue >= 0)
nValue = (nRemainder == 0) ? nValue - mnSpinSize : nValue - nRemainder;
else
diff --git a/vcl/source/control/fmtfield.cxx b/vcl/source/control/fmtfield.cxx
index d443f2c1a8e3..280bf06649f5 100644
--- a/vcl/source/control/fmtfield.cxx
+++ b/vcl/source/control/fmtfield.cxx
@@ -26,6 +26,7 @@
#include <vcl/settings.hxx>
#include <svl/zformat.hxx>
#include <vcl/fmtfield.hxx>
+#include <vcl/weld.hxx>
#include <i18nlangtag/languagetag.hxx>
#include <com/sun/star/lang/Locale.hpp>
#include <com/sun/star/util/SearchOptions.hpp>
@@ -304,6 +305,7 @@ FormattedField::FormattedField(vcl::Window* pParent, WinBits nStyle)
,m_bEnableEmptyField(true)
,m_bAutoColor(false)
,m_bEnableNaN(false)
+ ,m_bDisableRemainderFactor(false)
,m_ValueState(valueDirty)
,m_dCurrentValue(0)
,m_dDefaultValue(0)
@@ -859,35 +861,37 @@ void FormattedField::ImplSetValue(double dVal, bool bForce)
m_ValueState = valueDouble;
m_dCurrentValue = dVal;
- OUString sNewText;
- if (ImplGetFormatter()->IsTextFormat(m_nFormatKey))
+ if (!m_aOutputHdl.IsSet() || !m_aOutputHdl.Call(*this))
{
- // first convert the number as string in standard format
- OUString sTemp;
- ImplGetFormatter()->GetOutputString(dVal, 0, sTemp, &m_pLastOutputColor);
- // then encode the string in the corresponding text format
- ImplGetFormatter()->GetOutputString(sTemp, m_nFormatKey, sNewText, &m_pLastOutputColor);
- }
- else
- {
- if( IsUsingInputStringForFormatting())
+ OUString sNewText;
+ if (ImplGetFormatter()->IsTextFormat(m_nFormatKey))
{
- ImplGetFormatter()->GetInputLineString(dVal, m_nFormatKey, sNewText);
+ // first convert the number as string in standard format
+ OUString sTemp;
+ ImplGetFormatter()->GetOutputString(dVal, 0, sTemp, &m_pLastOutputColor);
+ // then encode the string in the corresponding text format
+ ImplGetFormatter()->GetOutputString(sTemp, m_nFormatKey, sNewText, &m_pLastOutputColor);
}
else
{
- ImplGetFormatter()->GetOutputString(dVal, m_nFormatKey, sNewText, &m_pLastOutputColor);
+ if( IsUsingInputStringForFormatting())
+ {
+ ImplGetFormatter()->GetInputLineString(dVal, m_nFormatKey, sNewText);
+ }
+ else
+ {
+ ImplGetFormatter()->GetOutputString(dVal, m_nFormatKey, sNewText, &m_pLastOutputColor);
+ }
}
+ ImplSetTextImpl(sNewText, nullptr);
+ DBG_ASSERT(CheckText(sNewText), "FormattedField::ImplSetValue : formatted string doesn't match the criteria !");
}
- ImplSetTextImpl(sNewText, nullptr);
m_ValueState = valueDouble;
- DBG_ASSERT(CheckText(sNewText), "FormattedField::ImplSetValue : formatted string doesn't match the criteria !");
}
bool FormattedField::ImplGetValue(double& dNewVal)
{
-
dNewVal = m_dCurrentValue;
if (m_ValueState == valueDouble)
return true;
@@ -897,34 +901,55 @@ bool FormattedField::ImplGetValue(double& dNewVal)
if (sText.isEmpty())
return true;
- DBG_ASSERT(ImplGetFormatter() != nullptr, "FormattedField::ImplGetValue : can't give you a current value without a formatter !");
+ bool bUseExternalFormatterValue = false;
+ if (m_aInputHdl.IsSet())
+ {
+ sal_Int64 nResult;
+ auto eState = m_aInputHdl.Call(&nResult);
+ bUseExternalFormatterValue = eState != TRISTATE_INDET;
+ if (bUseExternalFormatterValue)
+ {
+ if (eState == TRISTATE_TRUE)
+ {
+ dNewVal = nResult;
+ dNewVal /= weld::SpinButton::Power10(GetDecimalDigits());
+ }
+ else
+ dNewVal = m_dCurrentValue;
+ }
+ }
+
+ if (!bUseExternalFormatterValue)
+ {
+ DBG_ASSERT(ImplGetFormatter() != nullptr, "FormattedField::ImplGetValue : can't give you a current value without a formatter !");
- sal_uInt32 nFormatKey = m_nFormatKey; // IsNumberFormat changes the FormatKey!
+ sal_uInt32 nFormatKey = m_nFormatKey; // IsNumberFormat changes the FormatKey!
- if (ImplGetFormatter()->IsTextFormat(nFormatKey) && m_bTreatAsNumber)
- // for detection of values like "1,1" in fields that are formatted as text
- nFormatKey = 0;
+ if (ImplGetFormatter()->IsTextFormat(nFormatKey) && m_bTreatAsNumber)
+ // for detection of values like "1,1" in fields that are formatted as text
+ nFormatKey = 0;
- // special treatment for percentage formatting
- if (ImplGetFormatter()->GetType(m_nFormatKey) == SvNumFormatType::PERCENT)
- {
- // the language of our format
- LanguageType eLanguage = m_pFormatter->GetEntry(m_nFormatKey)->GetLanguage();
- // the default number format for this language
- sal_uLong nStandardNumericFormat = m_pFormatter->GetStandardFormat(SvNumFormatType::NUMBER, eLanguage);
-
- sal_uInt32 nTempFormat = nStandardNumericFormat;
- double dTemp;
- if (m_pFormatter->IsNumberFormat(sText, nTempFormat, dTemp) &&
- SvNumFormatType::NUMBER == m_pFormatter->GetType(nTempFormat))
- // the string is equivalent to a number formatted one (has no % sign) -> append it
- sText += "%";
- // (with this, a input of '3' becomes '3%', which then by the formatter is translated
- // into 0.03. Without this, the formatter would give us the double 3 for an input '3',
- // which equals 300 percent.
+ // special treatment for percentage formatting
+ if (ImplGetFormatter()->GetType(m_nFormatKey) == SvNumFormatType::PERCENT)
+ {
+ // the language of our format
+ LanguageType eLanguage = m_pFormatter->GetEntry(m_nFormatKey)->GetLanguage();
+ // the default number format for this language
+ sal_uLong nStandardNumericFormat = m_pFormatter->GetStandardFormat(SvNumFormatType::NUMBER, eLanguage);
+
+ sal_uInt32 nTempFormat = nStandardNumericFormat;
+ double dTemp;
+ if (m_pFormatter->IsNumberFormat(sText, nTempFormat, dTemp) &&
+ SvNumFormatType::NUMBER == m_pFormatter->GetType(nTempFormat))
+ // the string is equivalent to a number formatted one (has no % sign) -> append it
+ sText += "%";
+ // (with this, a input of '3' becomes '3%', which then by the formatter is translated
+ // into 0.03. Without this, the formatter would give us the double 3 for an input '3',
+ // which equals 300 percent.
+ }
+ if (!ImplGetFormatter()->IsNumberFormat(sText, nFormatKey, dNewVal))
+ return false;
}
- if (!ImplGetFormatter()->IsNumberFormat(sText, nFormatKey, dNewVal))
- return false;
if (m_bHasMin && (dNewVal<m_dMinValue))
dNewVal = m_dMinValue;
@@ -953,10 +978,34 @@ double FormattedField::GetValue()
return m_dCurrentValue;
}
+void FormattedField::DisableRemainderFactor()
+{
+ m_bDisableRemainderFactor = true;
+}
+
+bool FormattedField::set_property(const OString &rKey, const OUString &rValue)
+{
+ if (rKey == "digits")
+ SetDecimalDigits(rValue.toInt32());
+ else
+ return SpinField::set_property(rKey, rValue);
+ return true;
+}
+
void FormattedField::Up()
{
+ auto nScale = weld::SpinButton::Power10(GetDecimalDigits());
+
+ sal_Int64 nValue = std::round(GetValue() * nScale);
+ sal_Int64 nSpinSize = std::round(m_dSpinSize * nScale);
+ sal_Int64 nRemainder = m_bDisableRemainderFactor ? 0 : nValue % nSpinSize;
+ if (nValue >= 0)
+ nValue = (nRemainder == 0) ? nValue + nSpinSize : nValue + nSpinSize - nRemainder;
+ else
+ nValue = (nRemainder == 0) ? nValue + nSpinSize : nValue - nRemainder;
+
// setValue handles under- and overflows (min/max) automatically
- SetValue(GetValue() + m_dSpinSize);
+ SetValue(static_cast<double>(nValue) / nScale);
SetModifyFlag();
Modify();
@@ -965,7 +1014,18 @@ void FormattedField::Up()
void FormattedField::Down()
{
- SetValue(GetValue() - m_dSpinSize);
+ auto nScale = weld::SpinButton::Power10(GetDecimalDigits());
+
+ sal_Int64 nValue = std::round(GetValue() * nScale);
+ sal_Int64 nSpinSize = std::round(m_dSpinSize * nScale);
+ sal_Int64 nRemainder = m_bDisableRemainderFactor ? 0 : nValue % nSpinSize;
+ if (nValue >= 0)
+ nValue = (nRemainder == 0) ? nValue - nSpinSize : nValue - nRemainder;
+ else
+ nValue = (nRemainder == 0) ? nValue - nSpinSize : nValue - nSpinSize - nRemainder;
+
+ // setValue handles under- and overflows (min/max) automatically
+ SetValue(static_cast<double>(nValue) / nScale);
SetModifyFlag();
Modify();
@@ -1001,7 +1061,6 @@ void FormattedField::UseInputStringForFormatting()
m_bUseInputStringForFormatting = true;
}
-
DoubleNumericField::DoubleNumericField(vcl::Window* pParent, WinBits nStyle)
: FormattedField(pParent, nStyle)
{
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index e022ab0d7ef1..5f14f9cc0dc5 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -25,6 +25,7 @@
#include <vcl/dialog.hxx>
#include <vcl/edit.hxx>
#include <vcl/field.hxx>
+#include <vcl/fmtfield.hxx>
#include <vcl/fixed.hxx>
#include <vcl/fixedhyper.hxx>
#include <vcl/IPrioritable.hxx>
@@ -546,6 +547,16 @@ VclBuilder::VclBuilder(vcl::Window *pParent, const OUString& sUIDir, const OUStr
mungeAdjustment(*pTarget, *pAdjustment);
}
+ for (auto const& elem : m_pParserState->m_aFormattedFormatterAdjustmentMaps)
+ {
+ FormattedField *pTarget = dynamic_cast<FormattedField*>(get<vcl::Window>(elem.m_sID));
+ const Adjustment *pAdjustment = get_adjustment_by_name(elem.m_sValue.toUtf8());
+ SAL_WARN_IF(!pTarget, "vcl", "missing FormattedField element of spinbutton/adjustment");
+ SAL_WARN_IF(!pAdjustment, "vcl", "missing Adjustment element of spinbutton/adjustment");
+ if (pTarget && pAdjustment)
+ mungeAdjustment(*pTarget, *pAdjustment);
+ }
+
for (auto const& elem : m_pParserState->m_aTimeFormatterAdjustmentMaps)
{
TimeField *pTarget = dynamic_cast<TimeField*>(get<vcl::Window>(elem.m_sID));
@@ -1312,6 +1323,12 @@ void VclBuilder::connectNumericFormatterAdjustment(const OString &id, const OUSt
m_pParserState->m_aNumericFormatterAdjustmentMaps.emplace_back(id, rAdjustment);
}
+void VclBuilder::connectFormattedFormatterAdjustment(const OString &id, const OUString &rAdjustment)
+{
+ if (!rAdjustment.isEmpty())
+ m_pParserState->m_aFormattedFormatterAdjustmentMaps.emplace_back(id, rAdjustment);
+}
+
void VclBuilder::connectTimeFormatterAdjustment(const OString &id, const OUString &rAdjustment)
{
if (!rAdjustment.isEmpty())
@@ -1721,9 +1738,19 @@ VclPtr<vcl::Window> VclBuilder::makeObject(vcl::Window *pParent, const OString &
if (sPattern.isEmpty())
{
- connectNumericFormatterAdjustment(id, sAdjustment);
SAL_INFO("vcl.layout", "making numeric field for " << name << " " << sUnit);
- xWindow = VclPtr<NumericField>::Create(pParent, nBits);
+ if (m_bLegacy)
+ {
+ connectNumericFormatterAdjustment(id, sAdjustment);
+ xWindow = VclPtr<NumericField>::Create(pParent, nBits);
+ }
+ else
+ {
+ connectFormattedFormatterAdjustment(id, sAdjustment);
+ VclPtrInstance<FormattedField> xField(pParent, nBits);
+ xField->SetMinValue(0);
+ xWindow = xField;
+ }
}
else
{
@@ -4075,7 +4102,6 @@ void VclBuilder::mungeModel(SvTreeListBox &rTarget, const ListStore &rStore, sal
}
}
-
void VclBuilder::mungeAdjustment(NumericFormatter &rTarget, const Adjustment &rAdjustment)
{
int nMul = rtl_math_pow10Exp(1, rTarget.GetDecimalDigits());
@@ -4114,6 +4140,36 @@ void VclBuilder::mungeAdjustment(NumericFormatter &rTarget, const Adjustment &rA
}
}
+void VclBuilder::mungeAdjustment(FormattedField &rTarget, const Adjustment &rAdjustment)
+{
+ for (auto const& elem : rAdjustment)
+ {
+ const OString &rKey = elem.first;
+ const OUString &rValue = elem.second;
+
+ if (rKey == "upper")
+ {
+ rTarget.SetMaxValue(rValue.toDouble());
+ }
+ else if (rKey == "lower")
+ {
+ rTarget.SetMinValue(rValue.toDouble());
+ }
+ else if (rKey == "value")
+ {
+ rTarget.SetValue(rValue.toDouble());
+ }
+ else if (rKey == "step-increment")
+ {
+ rTarget.SetSpinSize(rValue.toDouble());
+ }
+ else
+ {
+ SAL_INFO("vcl.layout", "unhandled property :" << rKey);
+ }
+ }
+}
+
void VclBuilder::mungeAdjustment(TimeField &rTarget, const Adjustment &rAdjustment)
{
for (auto const& elem : rAdjustment)