cui/source/tabpages/paragrph.cxx | 68 +++++++++++++++++++-------- editeng/source/uno/unoipset.cxx | 4 - include/svx/relfld.hxx | 12 ++++ include/tools/fldunit.hxx | 2 include/vcl/fieldvalues.hxx | 1 svx/source/dialog/relfld.cxx | 95 ++++++++++++++++++++++++++++++--------- vcl/inc/units.hrc | 6 ++ vcl/source/control/field.cxx | 10 ++++ 8 files changed, 153 insertions(+), 45 deletions(-)
New commits: commit 78a18a5dc6986c9f5612f26d164c62202a1b94f8 Author: Jonathan Clark <jonat...@libreoffice.org> AuthorDate: Wed Nov 13 03:24:21 2024 -0700 Commit: Jonathan Clark <jonat...@libreoffice.org> CommitDate: Thu Nov 14 17:30:06 2024 +0100 tdf#36709 GUI changes for font-relative first-line indent This change includes GUI element changes to support viewing and editing first-line indent values with font-relative units in the paragraph style dialog. Change-Id: I72ada2565f51d70475eb17096a1317be9316b770 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176595 Reviewed-by: Jonathan Clark <jonat...@libreoffice.org> Tested-by: Jenkins diff --git a/cui/source/tabpages/paragrph.cxx b/cui/source/tabpages/paragrph.cxx index 2889ea2cdf76..a8f6150d0dab 100644 --- a/cui/source/tabpages/paragrph.cxx +++ b/cui/source/tabpages/paragrph.cxx @@ -102,6 +102,44 @@ enum LineSpaceList LLINESPACE_FIX = 7 }; +SvxIndentValue lcl_GetFontRelativeValue(SvxRelativeField& rField, MapUnit eUnit) +{ + switch (rField.GetCurrentUnit()) + { + case FieldUnit::FONT_EM: + return SvxIndentValue{ static_cast<double>(rField.get_value(FieldUnit::NONE)) / 100.0, + css::util::MeasureUnit::FONT_EM }; + + case FieldUnit::FONT_CJK_ADVANCE: + return SvxIndentValue{ static_cast<double>(rField.get_value(FieldUnit::NONE)) / 100.0, + css::util::MeasureUnit::FONT_CJK_ADVANCE }; + + default: + return SvxIndentValue::twips(static_cast<double>(rField.GetCoreValue(eUnit))); + } +} + +void lcl_SetFontRelativeValue(SvxRelativeField& rField, const SvxIndentValue& rValue, MapUnit eUnit) +{ + switch (rValue.m_nUnit) + { + case css::util::MeasureUnit::FONT_EM: + rField.SetFontRelative(FieldUnit::FONT_EM); + rField.set_value(static_cast<sal_Int64>(std::llround(rValue.m_dValue * 100.0)), + FieldUnit::FONT_EM); + break; + + case css::util::MeasureUnit::FONT_CJK_ADVANCE: + rField.SetFontRelative(FieldUnit::FONT_CJK_ADVANCE); + rField.set_value(static_cast<sal_Int64>(std::llround(rValue.m_dValue * 100.0)), + FieldUnit::FONT_CJK_ADVANCE); + break; + + default: + rField.SetMetricValue(static_cast<sal_Int64>(std::llround(rValue.m_dValue)), eUnit); + break; + } +} } static void SetLineSpace_Impl( SvxLineSpacingItem&, int, tools::Long lValue = 0 ); @@ -417,16 +455,12 @@ bool SvxStdParagraphTabPage::FillItemSet( SfxItemSet* rOutSet ) } else { - // tdf#36709: TODO: Handle font-relative units from GUI - item.SetTextFirstLineOffset( - SvxIndentValue::twips(m_aFLineIndent.GetCoreValue(eUnit)), - css::util::MeasureUnit::TWIP); + item.SetTextFirstLineOffset(lcl_GetFontRelativeValue(m_aFLineIndent, eUnit)); } } else { - // tdf#36709: TODO: Handle font-relative units from GUI - item.SetTextFirstLineOffset(SvxIndentValue::twips(m_aFLineIndent.GetCoreValue(eUnit))); + item.SetTextFirstLineOffset(lcl_GetFontRelativeValue(m_aFLineIndent, eUnit)); } item.SetAutoFirst(m_xAutoCB->get_active()); if (item.GetTextFirstLineOffsetValue() < 0) @@ -478,18 +512,14 @@ bool SvxStdParagraphTabPage::FillItemSet( SfxItemSet* rOutSet ) static_cast<sal_uInt16>(m_aFLineIndent.get_value(FieldUnit::NONE))); else { - // tdf#36709: TODO: Handle font-relative units from GUI - aMargin.SetTextFirstLineOffset( - SvxIndentValue::twips(m_aFLineIndent.GetCoreValue(eUnit))); + aMargin.SetTextFirstLineOffset(lcl_GetFontRelativeValue(m_aFLineIndent, eUnit)); } } else { aMargin.SetTextLeft(m_aLeftIndent.GetCoreValue(eUnit)); aMargin.SetRight(m_aRightIndent.GetCoreValue(eUnit)); - // tdf#36709: TODO: Handle font-relative units from GUI - aMargin.SetTextFirstLineOffset( - SvxIndentValue::twips(m_aFLineIndent.GetCoreValue(eUnit))); + aMargin.SetTextFirstLineOffset(lcl_GetFontRelativeValue(m_aFLineIndent, eUnit)); } aMargin.SetAutoFirst(m_xAutoCB->get_active()); if ( aMargin.GetTextFirstLineOffsetValue() < 0.0 ) @@ -672,18 +702,17 @@ void SvxStdParagraphTabPage::Reset( const SfxItemSet* rSet ) } else { - // tdf#36709: TODO: Handle font-relative units from GUI m_aFLineIndent.SetRelative(false); m_aFLineIndent.set_min(-9999, FieldUnit::NONE); m_aFLineIndent.SetFieldUnit(eFUnit); - m_aFLineIndent.SetMetricValue(rOldFirstLine.GetTextFirstLineOffsetValue(), eUnit); + lcl_SetFontRelativeValue(m_aFLineIndent, rOldFirstLine.GetTextFirstLineOffset(), + eUnit); } m_xAutoCB->set_active(rOldFirstLine.IsAutoFirst()); } else { - // tdf#36709: TODO: Handle font-relative units from GUI - m_aFLineIndent.SetMetricValue(rOldFirstLine.GetTextFirstLineOffsetValue(), eUnit); + lcl_SetFontRelativeValue(m_aFLineIndent, rOldFirstLine.GetTextFirstLineOffset(), eUnit); m_xAutoCB->set_active(rOldFirstLine.IsAutoFirst()); } AutoHdl_Impl(*m_xAutoCB); @@ -739,8 +768,7 @@ void SvxStdParagraphTabPage::Reset( const SfxItemSet* rSet ) m_aFLineIndent.SetRelative(false); m_aFLineIndent.set_min(-9999, FieldUnit::NONE); m_aFLineIndent.SetFieldUnit(eFUnit); - // tdf#36709: TODO: Populate GUI with font-relative unit - m_aFLineIndent.SetMetricValue(rOldItem.GetTextFirstLineOffsetValue(), eUnit); + lcl_SetFontRelativeValue(m_aFLineIndent, rOldItem.GetTextFirstLineOffset(), eUnit); } m_xAutoCB->set_active(rOldItem.IsAutoFirst()); } @@ -751,8 +779,7 @@ void SvxStdParagraphTabPage::Reset( const SfxItemSet* rSet ) m_aLeftIndent.SetMetricValue(rSpace.GetTextLeft(), eUnit); m_aRightIndent.SetMetricValue(rSpace.GetRight(), eUnit); - // tdf#36709: TODO: Populate GUI with font-relative units - m_aFLineIndent.SetMetricValue(rSpace.GetTextFirstLineOffsetValue(), eUnit); + lcl_SetFontRelativeValue(m_aFLineIndent, rSpace.GetTextFirstLineOffset(), eUnit); m_xAutoCB->set_active(rSpace.IsAutoFirst()); } AutoHdl_Impl(*m_xAutoCB); @@ -951,6 +978,7 @@ SvxStdParagraphTabPage::SvxStdParagraphTabPage(weld::Container* pPage, weld::Dia Init_Impl(); m_aFLineIndent.set_min(-9999, FieldUnit::NONE); // is set to 0 on default + m_aFLineIndent.EnableFontRelativeMode(); } SvxStdParagraphTabPage::~SvxStdParagraphTabPage() diff --git a/editeng/source/uno/unoipset.cxx b/editeng/source/uno/unoipset.cxx index a17783637818..43cb71aa0a86 100644 --- a/editeng/source/uno/unoipset.cxx +++ b/editeng/source/uno/unoipset.cxx @@ -72,10 +72,10 @@ uno::Any SvxItemPropertySet::getPropertyValue( const SfxItemPropertyMapEntry* pM if(pItem) { - pItem->QueryValue( aVal, nMemberId ); + auto bQuerySucceeded = pItem->QueryValue(aVal, nMemberId); if( pMap->nMoreFlags & PropertyMoreFlags::METRIC_ITEM ) { - if( eMapUnit != MapUnit::Map100thMM ) + if (bQuerySucceeded && eMapUnit != MapUnit::Map100thMM) { if ( !bDontConvertNegativeValues || SvxUnoCheckForPositiveValue( aVal ) ) SvxUnoConvertToMM( eMapUnit, aVal ); diff --git a/include/svx/relfld.hxx b/include/svx/relfld.hxx index f035762da825..6cb3c8e9eb0b 100644 --- a/include/svx/relfld.hxx +++ b/include/svx/relfld.hxx @@ -29,11 +29,14 @@ class SVX_DLLPUBLIC SvxRelativeField private: std::unique_ptr<weld::MetricSpinButton> m_xSpinButton; + FieldUnit eAbsoluteFieldUnit = FieldUnit::NONE; + FieldUnit eFontRelativeFieldUnit = FieldUnit::NONE; sal_uInt16 nRelMin; sal_uInt16 nRelMax; bool bRelativeMode; bool bRelative; bool bNegativeEnabled; + bool bFontRelativeMode; DECL_DLLPRIVATE_LINK(ModifyHdl, weld::Entry&, void); @@ -41,9 +44,12 @@ public: SvxRelativeField(std::unique_ptr<weld::MetricSpinButton> pControl); void EnableRelativeMode( sal_uInt16 nMin, sal_uInt16 nMax ); + void EnableFontRelativeMode(); void SetRelative( bool bRelative ); + void SetFontRelative(FieldUnit eNewRelativeUnit); bool IsRelative() const { return bRelative; } void EnableNegativeMode() {bNegativeEnabled = true;} + FieldUnit GetCurrentUnit() const { return eFontRelativeFieldUnit; } void set_sensitive(bool sensitive) { m_xSpinButton->set_sensitive(sensitive); } bool get_sensitive() const { return m_xSpinButton->get_sensitive(); } @@ -62,7 +68,11 @@ public: weld::SpinButton& get_widget() { return m_xSpinButton->get_widget(); } sal_Int64 GetCoreValue(MapUnit eUnit) const { return ::GetCoreValue(*m_xSpinButton, eUnit); } - void SetFieldUnit(FieldUnit eUnit, bool bAll = false) { ::SetFieldUnit(*m_xSpinButton, eUnit, bAll); } + void SetFieldUnit(FieldUnit eUnit, bool bAll = false) + { + ::SetFieldUnit(*m_xSpinButton, eUnit, bAll); + eAbsoluteFieldUnit = m_xSpinButton->get_unit(); + } void SetMetricValue(sal_Int64 lCoreValue, MapUnit eUnit) { ::SetMetricValue(*m_xSpinButton, lCoreValue, eUnit); } }; diff --git a/include/tools/fldunit.hxx b/include/tools/fldunit.hxx index 72ab9ad92d87..28649be98c00 100644 --- a/include/tools/fldunit.hxx +++ b/include/tools/fldunit.hxx @@ -47,6 +47,8 @@ enum class FieldUnit : sal_uInt16 DEGREE, SECOND, MILLISECOND, + FONT_EM, + FONT_CJK_ADVANCE, }; constexpr o3tl::Length FieldToO3tlLength(FieldUnit eU, o3tl::Length ePixelValue = o3tl::Length::px) diff --git a/include/vcl/fieldvalues.hxx b/include/vcl/fieldvalues.hxx index 220aef2e3b1a..c21b52c14e4f 100644 --- a/include/vcl/fieldvalues.hxx +++ b/include/vcl/fieldvalues.hxx @@ -38,6 +38,7 @@ VCL_DLLPUBLIC FieldUnit EnglishStringToMetric(std::u16string_view rEnglishMetric VCL_DLLPUBLIC bool TextToValue(const OUString& rStr, double& rValue, sal_Int64 nBaseValue, sal_uInt16 nDecDigits, const LocaleDataWrapper& rLocaleDataWrapper, FieldUnit eUnit); +VCL_DLLPUBLIC FieldUnit GetTextMetricUnit(std::u16string_view aStr); VCL_DLLPUBLIC sal_Int64 ConvertValue(sal_Int64 nValue, sal_Int64 mnBaseValue, sal_uInt16 nDecDigits, FieldUnit eInUnit, FieldUnit eOutUnit); diff --git a/svx/source/dialog/relfld.cxx b/svx/source/dialog/relfld.cxx index 3929e4fcf7df..77da81b0c77b 100644 --- a/svx/source/dialog/relfld.cxx +++ b/svx/source/dialog/relfld.cxx @@ -18,6 +18,7 @@ */ #include <svx/relfld.hxx> +#include <vcl/fieldvalues.hxx> SvxRelativeField::SvxRelativeField(std::unique_ptr<weld::MetricSpinButton> pControl) : m_xSpinButton(std::move(pControl)) @@ -26,7 +27,7 @@ SvxRelativeField::SvxRelativeField(std::unique_ptr<weld::MetricSpinButton> pCont , bRelativeMode(false) , bRelative(false) , bNegativeEnabled(false) - + , bFontRelativeMode(false) { weld::SpinButton& rSpinButton = m_xSpinButton->get_widget(); rSpinButton.connect_changed(LINK(this, SvxRelativeField, ModifyHdl)); @@ -34,35 +35,57 @@ SvxRelativeField::SvxRelativeField(std::unique_ptr<weld::MetricSpinButton> pCont IMPL_LINK_NOARG(SvxRelativeField, ModifyHdl, weld::Entry&, void) { - if (!bRelativeMode) - return; - - OUString aStr = m_xSpinButton->get_text(); - bool bNewMode = bRelative; - - if ( bRelative ) + if (bRelativeMode) { - const sal_Unicode* pStr = aStr.getStr(); + OUString aStr = m_xSpinButton->get_text(); + bool bNewMode = bRelative; - while ( *pStr ) + if (bRelative) { - if( ( ( *pStr < '0' ) || ( *pStr > '9' ) ) && - ( *pStr != '%' ) ) + const sal_Unicode* pStr = aStr.getStr(); + + while (*pStr) { - bNewMode = false; - break; + if (((*pStr < '0') || (*pStr > '9')) && (*pStr != '%')) + { + bNewMode = false; + break; + } + pStr++; } - pStr++; } + else + { + if (aStr.indexOf("%") != -1) + bNewMode = true; + } + + if (bNewMode != bRelative) + SetRelative(bNewMode); } - else + + if (bFontRelativeMode) { - if ( aStr.indexOf( "%" ) != -1 ) - bNewMode = true; - } + OUString aStr = m_xSpinButton->get_text(); + FieldUnit eNewFieldUnit = vcl::GetTextMetricUnit(aStr); + + // Only allow font-relative units + switch (eNewFieldUnit) + { + default: + eNewFieldUnit = FieldUnit::NONE; + break; + + case FieldUnit::FONT_EM: + case FieldUnit::FONT_CJK_ADVANCE: + break; + } - if ( bNewMode != bRelative ) - SetRelative( bNewMode ); + if (eNewFieldUnit != eFontRelativeFieldUnit) + { + SetFontRelative(eNewFieldUnit); + } + } } void SvxRelativeField::EnableRelativeMode(sal_uInt16 nMin, sal_uInt16 nMax) @@ -73,6 +96,8 @@ void SvxRelativeField::EnableRelativeMode(sal_uInt16 nMin, sal_uInt16 nMax) m_xSpinButton->set_unit(FieldUnit::CM); } +void SvxRelativeField::EnableFontRelativeMode() { bFontRelativeMode = true; } + void SvxRelativeField::SetRelative( bool bNewRelative ) { weld::SpinButton& rSpinButton = m_xSpinButton->get_widget(); @@ -81,6 +106,8 @@ void SvxRelativeField::SetRelative( bool bNewRelative ) rSpinButton.get_selection_bounds(nStartPos, nEndPos); OUString aStr = rSpinButton.get_text(); + eFontRelativeFieldUnit = FieldUnit::NONE; + if ( bNewRelative ) { bRelative = true; @@ -100,4 +127,30 @@ void SvxRelativeField::SetRelative( bool bNewRelative ) rSpinButton.select_region(nStartPos, nEndPos); } +void SvxRelativeField::SetFontRelative(FieldUnit eNewRelativeUnit) +{ + weld::SpinButton& rSpinButton = m_xSpinButton->get_widget(); + + int nStartPos, nEndPos; + rSpinButton.get_selection_bounds(nStartPos, nEndPos); + OUString aStr = rSpinButton.get_text(); + + bRelative = false; + eFontRelativeFieldUnit = eNewRelativeUnit; + m_xSpinButton->set_digits(2); + m_xSpinButton->set_range(bNegativeEnabled ? -9999 : 0, 9999, FieldUnit::NONE); + + if (eNewRelativeUnit == FieldUnit::NONE) + { + m_xSpinButton->set_unit(eAbsoluteFieldUnit); + } + else + { + m_xSpinButton->set_unit(eNewRelativeUnit); + } + + rSpinButton.set_text(aStr); + rSpinButton.select_region(nStartPos, nEndPos); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/units.hrc b/vcl/inc/units.hrc index 677f9f5cefee..516cc12477d6 100644 --- a/vcl/inc/units.hrc +++ b/vcl/inc/units.hrc @@ -56,8 +56,12 @@ std::pair<TranslateId, FieldUnit> SV_FUNIT_STRINGS[] = /* To translators: degree */ { NC_("SV_FUNIT_STRINGS", "°"), FieldUnit::DEGREE }, { NC_("SV_FUNIT_STRINGS", "sec"), FieldUnit::SECOND }, + { NC_("SV_FUNIT_STRINGS", "ms"), FieldUnit::MILLISECOND }, + /* To translators: standard typographical metric 'em' */ + { NC_("SV_FUNIT_STRINGS", "em"), FieldUnit::FONT_EM }, // To translators: This is the last entry of the sequence of measurement unit names - { NC_("SV_FUNIT_STRINGS", "ms"), FieldUnit::MILLISECOND } + /* To translators: CSS unit 'ic'; CJK full-width advance in the current font */ + { NC_("SV_FUNIT_STRINGS", "ic"), FieldUnit::FONT_CJK_ADVANCE } }; #endif // INCLUDED_VCL_INC_UNITS_HRC diff --git a/vcl/source/control/field.cxx b/vcl/source/control/field.cxx index cfbef9171efc..d0ae78e907bf 100644 --- a/vcl/source/control/field.cxx +++ b/vcl/source/control/field.cxx @@ -117,6 +117,12 @@ std::string FieldUnitToString(FieldUnit unit) case FieldUnit::MILLISECOND: return "millisecond"; + + case FieldUnit::FONT_EM: + return "em"; + + case FieldUnit::FONT_CJK_ADVANCE: + return "ic"; } return ""; @@ -1161,6 +1167,8 @@ namespace vcl eInUnit == FieldUnit::SECOND || eInUnit == FieldUnit::MILLISECOND || eInUnit == FieldUnit::PIXEL || + eInUnit == FieldUnit::FONT_EM || + eInUnit == FieldUnit::FONT_CJK_ADVANCE || eOutUnit == MapUnit::MapPixel || eOutUnit == MapUnit::MapSysFont || eOutUnit == MapUnit::MapAppFont || @@ -1212,6 +1220,8 @@ namespace vcl return true; } + + FieldUnit GetTextMetricUnit(std::u16string_view aStr) { return ImplMetricGetUnit(aStr); } } void MetricFormatter::ImplMetricReformat( const OUString& rStr, double& rValue, OUString& rOutStr )