cui/source/tabpages/page.cxx | 22 cui/source/tabpages/paragrph.cxx | 39 cui/source/tabpages/tabstpge.cxx | 3 editeng/source/editeng/editdbg.cxx | 4 editeng/source/editeng/editdoc.cxx | 11 editeng/source/editeng/impedit.hxx | 3 editeng/source/editeng/impedit2.cxx | 7 editeng/source/editeng/impedit3.cxx | 37 editeng/source/editeng/impedit4.cxx | 4 editeng/source/items/frmitems.cxx | 880 ++++++---- editeng/source/outliner/outliner.cxx | 2 editeng/source/rtf/rtfitem.cxx | 4 filter/source/msfilter/svdfppt.cxx | 2 include/editeng/lrspitem.hxx | 83 include/editeng/memberids.h | 2 include/editeng/unoprnms.hxx | 2 include/editeng/unotext.hxx | 2 reportdesign/source/ui/report/ReportController.cxx | 9 sc/source/core/data/docpool.cxx | 4 sc/source/core/data/stlsheet.cxx | 7 sc/source/filter/excel/xepage.cxx | 4 sc/source/filter/excel/xipage.cxx | 6 sc/source/filter/html/htmlimp.cxx | 4 sc/source/ui/unoobj/docuno.cxx | 2 sc/source/ui/view/preview.cxx | 26 sc/source/ui/view/printfun.cxx | 8 schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng | 24 sd/source/core/sdpage.cxx | 2 sd/source/core/stlpool.cxx | 5 sd/source/core/stlsheet.cxx | 8 sd/source/filter/xml/sdtransform.cxx | 4 sd/source/ui/func/fupage.cxx | 8 sd/source/ui/func/fuparagr.cxx | 2 sd/source/ui/view/drtxtob1.cxx | 7 sd/source/ui/view/drviews3.cxx | 9 sd/source/ui/view/outlview.cxx | 20 svx/source/dialog/hdft.cxx | 20 svx/source/dialog/svxruler.cxx | 31 svx/source/sidebar/paragraph/ParaPropertyPanel.cxx | 11 svx/source/sidebar/paragraph/ParaSpacingWindow.cxx | 8 sw/inc/unoprnms.hxx | 2 sw/qa/extras/layout/layout3.cxx | 4 sw/qa/extras/odfexport/data/tdf163913.fodt | 131 + sw/qa/extras/odfexport/odfexport2.cxx | 44 sw/qa/extras/uiwriter/uiwriter2.cxx | 4 sw/qa/extras/uiwriter/uiwriter7.cxx | 40 sw/qa/extras/uiwriter/uiwriter8.cxx | 33 sw/qa/extras/ww8import/ww8import.cxx | 8 sw/source/core/attr/format.cxx | 3 sw/source/core/crsr/crstrvl.cxx | 2 sw/source/core/doc/DocumentStylePoolManager.cxx | 71 sw/source/core/doc/docdesc.cxx | 4 sw/source/core/doc/docfmt.cxx | 7 sw/source/core/doc/fmtcol.cxx | 12 sw/source/core/doc/tblrwcl.cxx | 33 sw/source/core/doc/textboxhelper.cxx | 4 sw/source/core/docnode/ndtbl.cxx | 5 sw/source/core/edit/autofmt.cxx | 25 sw/source/core/edit/edattr.cxx | 2 sw/source/core/layout/anchoredobject.cxx | 4 sw/source/core/layout/colfrm.cxx | 16 sw/source/core/layout/fly.cxx | 10 sw/source/core/layout/frmtool.cxx | 27 sw/source/core/layout/pagedesc.cxx | 4 sw/source/core/layout/sectfrm.cxx | 9 sw/source/core/objectpositioning/anchoredobjectposition.cxx | 65 sw/source/core/objectpositioning/ascharanchoredobjectposition.cxx | 16 sw/source/core/objectpositioning/tocntntanchoredobjectposition.cxx | 18 sw/source/core/objectpositioning/tolayoutanchoredobjectposition.cxx | 9 sw/source/core/table/swtable.cxx | 4 sw/source/core/text/frmcrsr.cxx | 8 sw/source/core/text/frmpaint.cxx | 2 sw/source/core/text/itratr.cxx | 20 sw/source/core/text/itrcrsr.cxx | 64 sw/source/core/text/txtfly.cxx | 12 sw/source/core/tox/ToxTabStopTokenHandler.cxx | 11 sw/source/core/txtnode/ndtxt.cxx | 29 sw/source/core/txtnode/thints.cxx | 3 sw/source/core/unocore/unomapproperties.hxx | 6 sw/source/filter/html/css1atr.cxx | 34 sw/source/filter/html/htmlatr.cxx | 25 sw/source/filter/html/htmlcss1.cxx | 2 sw/source/filter/html/htmlctxt.cxx | 21 sw/source/filter/html/htmldrawreader.cxx | 8 sw/source/filter/html/htmlflywriter.cxx | 8 sw/source/filter/html/htmlform.cxx | 4 sw/source/filter/html/htmlplug.cxx | 8 sw/source/filter/html/htmltab.cxx | 11 sw/source/filter/html/htmltabw.cxx | 20 sw/source/filter/html/svxcss1.cxx | 13 sw/source/filter/html/swhtml.cxx | 43 sw/source/filter/html/wrthtml.cxx | 6 sw/source/filter/ww8/docxattributeoutput.cxx | 51 sw/source/filter/ww8/docxsdrexport.cxx | 4 sw/source/filter/ww8/docxtableexport.cxx | 6 sw/source/filter/ww8/rtfattributeoutput.cxx | 39 sw/source/filter/ww8/rtfexport.cxx | 6 sw/source/filter/ww8/writerwordglue.cxx | 10 sw/source/filter/ww8/wrtw8esh.cxx | 6 sw/source/filter/ww8/wrtw8nds.cxx | 18 sw/source/filter/ww8/wrtw8sty.cxx | 11 sw/source/filter/ww8/wrtww8.cxx | 12 sw/source/filter/ww8/ww8atr.cxx | 32 sw/source/filter/ww8/ww8graf.cxx | 12 sw/source/filter/ww8/ww8par.cxx | 8 sw/source/filter/ww8/ww8par2.cxx | 2 sw/source/filter/ww8/ww8par3.cxx | 6 sw/source/filter/ww8/ww8par6.cxx | 42 sw/source/filter/xml/xmlexpit.cxx | 24 sw/source/filter/xml/xmlimpit.cxx | 6 sw/source/ui/dialog/uiregionsw.cxx | 12 sw/source/ui/envelp/envfmt.cxx | 2 sw/source/ui/frmdlg/column.cxx | 7 sw/source/ui/frmdlg/wrap.cxx | 10 sw/source/ui/misc/pggrid.cxx | 2 sw/source/uibase/app/appenv.cxx | 4 sw/source/uibase/app/applab.cxx | 7 sw/source/uibase/app/docstyle.cxx | 6 sw/source/uibase/frmdlg/colex.cxx | 12 sw/source/uibase/frmdlg/colmgr.cxx | 4 sw/source/uibase/frmdlg/frmmgr.cxx | 8 sw/source/uibase/shells/drwtxtex.cxx | 3 sw/source/uibase/shells/tabsh.cxx | 16 sw/source/uibase/shells/textsh1.cxx | 6 sw/source/uibase/sidebar/WrapPropertyPanel.cxx | 7 sw/source/uibase/uiview/view2.cxx | 2 sw/source/uibase/uiview/viewmdi.cxx | 8 sw/source/uibase/uiview/viewtab.cxx | 168 + sw/source/uibase/uno/unotxvw.cxx | 2 sw/source/uibase/utlui/uitool.cxx | 2 sw/source/uibase/wrtsh/delete.cxx | 7 vcl/qa/cppunit/pdfexport/data/tdf163913.fodt | 147 + vcl/qa/cppunit/pdfexport/pdfexport2.cxx | 56 xmloff/inc/xmlprop.hxx | 2 xmloff/source/text/txtprmap.cxx | 9 135 files changed, 1981 insertions(+), 1133 deletions(-)
New commits: commit 7e4f4a0ccd3c56093dec44c7dcdd14c8b34623c3 Author: Jonathan Clark <[email protected]> AuthorDate: Mon Nov 18 10:03:13 2024 -0700 Commit: Jonathan Clark <[email protected]> CommitDate: Thu Nov 28 22:10:05 2024 +0100 tdf#163913 Implement font-relative margins This change adds loext:margin-left and loext:margin-right, which implement margins that support font-relative units. See tdf#36709 for additional details. Change-Id: I31b0dd2b6f98cb5b02fd4dca3608db6fdee4054c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177473 Tested-by: Jenkins Reviewed-by: Jonathan Clark <[email protected]> diff --git a/cui/source/tabpages/page.cxx b/cui/source/tabpages/page.cxx index 809bd672817b..3f13a6bf6324 100644 --- a/cui/source/tabpages/page.cxx +++ b/cui/source/tabpages/page.cxx @@ -336,13 +336,13 @@ void SvxPageDescPage::Reset( const SfxItemSet* rSet ) if ( pItem ) { const SvxLRSpaceItem& rLRSpace = static_cast<const SvxLRSpaceItem&>(*pItem); - SetMetricValue( *m_xLeftMarginEdit, rLRSpace.GetLeft(), eUnit ); + SetMetricValue(*m_xLeftMarginEdit, rLRSpace.ResolveLeft({}), eUnit); SetMetricValue(*m_xGutterMarginEdit, rLRSpace.GetGutterMargin(), eUnit); m_aBspWin.SetLeft( - static_cast<sal_uInt16>(ConvertLong_Impl( rLRSpace.GetLeft(), eUnit )) ); - SetMetricValue( *m_xRightMarginEdit, rLRSpace.GetRight(), eUnit ); + static_cast<sal_uInt16>(ConvertLong_Impl(rLRSpace.ResolveLeft({}), eUnit))); + SetMetricValue(*m_xRightMarginEdit, rLRSpace.ResolveRight({}), eUnit); m_aBspWin.SetRight( - static_cast<sal_uInt16>(ConvertLong_Impl( rLRSpace.GetRight(), eUnit )) ); + static_cast<sal_uInt16>(ConvertLong_Impl(rLRSpace.ResolveRight({}), eUnit))); } // adjust margins (top/bottom) @@ -633,13 +633,15 @@ bool SvxPageDescPage::FillItemSet( SfxItemSet* rSet ) if (m_xLeftMarginEdit->get_value_changed_from_saved()) { - aMargin.SetLeft( static_cast<sal_uInt16>(GetCoreValue( *m_xLeftMarginEdit, eUnit )) ); + aMargin.SetLeft(SvxIndentValue::twips( + static_cast<sal_uInt16>(GetCoreValue(*m_xLeftMarginEdit, eUnit)))); bModified = true; } if (m_xRightMarginEdit->get_value_changed_from_saved()) { - aMargin.SetRight( static_cast<sal_uInt16>(GetCoreValue( *m_xRightMarginEdit, eUnit )) ); + aMargin.SetRight(SvxIndentValue::twips( + static_cast<sal_uInt16>(GetCoreValue(*m_xRightMarginEdit, eUnit)))); bModified = true; } @@ -1254,8 +1256,8 @@ void SvxPageDescPage::InitHeadFoot_Impl( const SfxItemSet& rSet ) m_aBspWin.SetHdDist( nDist ); const SvxLRSpaceItem& rLR = rHeaderSet.Get( GetWhich( SID_ATTR_LRSPACE ) ); - m_aBspWin.SetHdLeft( rLR.GetLeft() ); - m_aBspWin.SetHdRight( rLR.GetRight() ); + m_aBspWin.SetHdLeft(rLR.ResolveLeft({})); + m_aBspWin.SetHdRight(rLR.ResolveRight({})); m_aBspWin.SetHeader( true ); } else @@ -1309,8 +1311,8 @@ void SvxPageDescPage::InitHeadFoot_Impl( const SfxItemSet& rSet ) m_aBspWin.SetFtDist( nDist ); const SvxLRSpaceItem& rLR = rFooterSet.Get( GetWhich( SID_ATTR_LRSPACE ) ); - m_aBspWin.SetFtLeft( rLR.GetLeft() ); - m_aBspWin.SetFtRight( rLR.GetRight() ); + m_aBspWin.SetFtLeft(rLR.ResolveLeft({})); + m_aBspWin.SetFtRight(rLR.ResolveRight({})); m_aBspWin.SetFooter( true ); } else diff --git a/cui/source/tabpages/paragrph.cxx b/cui/source/tabpages/paragrph.cxx index a8f6150d0dab..ea8b6a4def38 100644 --- a/cui/source/tabpages/paragrph.cxx +++ b/cui/source/tabpages/paragrph.cxx @@ -381,12 +381,12 @@ bool SvxStdParagraphTabPage::FillItemSet( SfxItemSet* rOutSet ) } else { - item.SetTextLeft(m_aLeftIndent.GetCoreValue(eUnit)); + item.SetTextLeft(lcl_GetFontRelativeValue(m_aLeftIndent, eUnit)); } } else { - item.SetTextLeft(m_aLeftIndent.GetCoreValue(eUnit)); + item.SetTextLeft(lcl_GetFontRelativeValue(m_aLeftIndent, eUnit)); } if (!pOld || *static_cast<const SvxTextLeftMarginItem*>(pOld) != item || SfxItemState::INVALID == GetItemSet().GetItemState(nWhich)) @@ -417,12 +417,12 @@ bool SvxStdParagraphTabPage::FillItemSet( SfxItemSet* rOutSet ) } else { - item.SetRight(m_aRightIndent.GetCoreValue(eUnit)); + item.SetRight(lcl_GetFontRelativeValue(m_aRightIndent, eUnit)); } } else { - item.SetRight(m_aRightIndent.GetCoreValue(eUnit)); + item.SetRight(lcl_GetFontRelativeValue(m_aRightIndent, eUnit)); } if (!pOld || *static_cast<const SvxRightMarginItem*>(pOld) != item || SfxItemState::INVALID == GetItemSet().GetItemState(nWhich)) @@ -463,7 +463,7 @@ bool SvxStdParagraphTabPage::FillItemSet( SfxItemSet* rOutSet ) item.SetTextFirstLineOffset(lcl_GetFontRelativeValue(m_aFLineIndent, eUnit)); } item.SetAutoFirst(m_xAutoCB->get_active()); - if (item.GetTextFirstLineOffsetValue() < 0) + if (item.GetTextFirstLineOffset().m_dValue < 0.0) { bNullTab = true; } @@ -498,13 +498,13 @@ bool SvxStdParagraphTabPage::FillItemSet( SfxItemSet* rOutSet ) aMargin.SetTextLeft( rOldItem.GetTextLeft(), static_cast<sal_uInt16>(m_aLeftIndent.get_value(FieldUnit::NONE)) ); else - aMargin.SetTextLeft(m_aLeftIndent.GetCoreValue(eUnit)); + aMargin.SetTextLeft(lcl_GetFontRelativeValue(m_aLeftIndent, eUnit)); if ( m_aRightIndent.IsRelative() ) aMargin.SetRight( rOldItem.GetRight(), static_cast<sal_uInt16>(m_aRightIndent.get_value(FieldUnit::NONE)) ); else - aMargin.SetRight(m_aRightIndent.GetCoreValue(eUnit)); + aMargin.SetRight(lcl_GetFontRelativeValue(m_aRightIndent, eUnit)); if ( m_aFLineIndent.IsRelative() ) aMargin.SetTextFirstLineOffset( @@ -517,12 +517,12 @@ bool SvxStdParagraphTabPage::FillItemSet( SfxItemSet* rOutSet ) } else { - aMargin.SetTextLeft(m_aLeftIndent.GetCoreValue(eUnit)); - aMargin.SetRight(m_aRightIndent.GetCoreValue(eUnit)); + aMargin.SetTextLeft(lcl_GetFontRelativeValue(m_aLeftIndent, eUnit)); + aMargin.SetRight(lcl_GetFontRelativeValue(m_aRightIndent, eUnit)); aMargin.SetTextFirstLineOffset(lcl_GetFontRelativeValue(m_aFLineIndent, eUnit)); } aMargin.SetAutoFirst(m_xAutoCB->get_active()); - if ( aMargin.GetTextFirstLineOffsetValue() < 0.0 ) + if (aMargin.GetTextFirstLineOffset().m_dValue < 0.0) bNullTab = true; if ( !pOld || *static_cast<const SvxLRSpaceItem*>(pOld) != aMargin || @@ -642,12 +642,12 @@ void SvxStdParagraphTabPage::Reset( const SfxItemSet* rSet ) { m_aLeftIndent.SetRelative(false); m_aLeftIndent.SetFieldUnit(eFUnit); - m_aLeftIndent.SetMetricValue(rOldLeftMargin.GetTextLeft(), eUnit); + lcl_SetFontRelativeValue(m_aLeftIndent, rOldLeftMargin.GetTextLeft(), eUnit); } } else { - m_aLeftIndent.SetMetricValue(rOldLeftMargin.GetTextLeft(), eUnit); + lcl_SetFontRelativeValue(m_aLeftIndent, rOldLeftMargin.GetTextLeft(), eUnit); } } else if (m_bSplitLRSpace) @@ -673,12 +673,12 @@ void SvxStdParagraphTabPage::Reset( const SfxItemSet* rSet ) { m_aRightIndent.SetRelative(false); m_aRightIndent.SetFieldUnit(eFUnit); - m_aRightIndent.SetMetricValue(rOldRightMargin.GetRight(), eUnit); + lcl_SetFontRelativeValue(m_aRightIndent, rOldRightMargin.GetRight(), eUnit); } } else { - m_aRightIndent.SetMetricValue(rOldRightMargin.GetRight(), eUnit); + lcl_SetFontRelativeValue(m_aRightIndent, rOldRightMargin.GetRight(), eUnit); } } else if (m_bSplitLRSpace) @@ -743,7 +743,7 @@ void SvxStdParagraphTabPage::Reset( const SfxItemSet* rSet ) { m_aLeftIndent.SetRelative(false); m_aLeftIndent.SetFieldUnit(eFUnit); - m_aLeftIndent.SetMetricValue(rOldItem.GetTextLeft(), eUnit); + lcl_SetFontRelativeValue(m_aLeftIndent, rOldItem.GetTextLeft(), eUnit); } if ( rOldItem.GetPropRight() != 100 ) @@ -755,7 +755,7 @@ void SvxStdParagraphTabPage::Reset( const SfxItemSet* rSet ) { m_aRightIndent.SetRelative(false); m_aRightIndent.SetFieldUnit(eFUnit); - m_aRightIndent.SetMetricValue(rOldItem.GetRight(), eUnit); + lcl_SetFontRelativeValue(m_aRightIndent, rOldItem.GetRight(), eUnit); } if ( rOldItem.GetPropTextFirstLineOffset() != 100 ) @@ -777,8 +777,8 @@ void SvxStdParagraphTabPage::Reset( const SfxItemSet* rSet ) const SvxLRSpaceItem& rSpace = static_cast<const SvxLRSpaceItem&>(rSet->Get( _nWhich )); - m_aLeftIndent.SetMetricValue(rSpace.GetTextLeft(), eUnit); - m_aRightIndent.SetMetricValue(rSpace.GetRight(), eUnit); + lcl_SetFontRelativeValue(m_aLeftIndent, rSpace.GetTextLeft(), eUnit); + lcl_SetFontRelativeValue(m_aRightIndent, rSpace.GetRight(), eUnit); lcl_SetFontRelativeValue(m_aFLineIndent, rSpace.GetTextFirstLineOffset(), eUnit); m_xAutoCB->set_active(rSpace.IsAutoFirst()); } @@ -979,6 +979,9 @@ 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(); + + m_aLeftIndent.EnableFontRelativeMode(); + m_aRightIndent.EnableFontRelativeMode(); } SvxStdParagraphTabPage::~SvxStdParagraphTabPage() diff --git a/cui/source/tabpages/tabstpge.cxx b/cui/source/tabpages/tabstpge.cxx index 34b0b631af3a..78e9aec3b739 100644 --- a/cui/source/tabpages/tabstpge.cxx +++ b/cui/source/tabpages/tabstpge.cxx @@ -177,7 +177,8 @@ bool SvxTabulatorTabPage::FillItemSet(SfxItemSet* rSet) pLRSpace = GetOldItem(*rSet, SID_ATTR_LRSPACE); if (pLRSpace - && static_cast<const SvxLRSpaceItem*>(pLRSpace)->GetTextFirstLineOffsetValue() < 0.0) + && static_cast<const SvxLRSpaceItem*>(pLRSpace)->GetTextFirstLineOffset().m_dValue + < 0.0) { SvxTabStop aNull(0, SvxTabAdjust::Default); aNewTabs->Insert(aNull); diff --git a/editeng/source/editeng/editdbg.cxx b/editeng/source/editeng/editdbg.cxx index 2b4d3956eefd..d2a9290dae00 100644 --- a/editeng/source/editeng/editdbg.cxx +++ b/editeng/source/editeng/editdbg.cxx @@ -71,8 +71,8 @@ struct DebOutBuffer { str.append(OString::Concat(descr) + "FI=" + OString::number(rItem.ResolveTextFirstLineOffset({})) - + ", LI=" + OString::number(rItem.GetTextLeft()) - + ", RI=" + OString::number(rItem.GetRight())); + + ", LI=" + OString::number(rItem.ResolveTextLeft({})) + + ", RI=" + OString::number(rItem.ResolveRight({}))); } void append(std::string_view descr, const SvxNumBulletItem& rItem) { diff --git a/editeng/source/editeng/editdoc.cxx b/editeng/source/editeng/editdoc.cxx index 63961daefe27..d0e6d987b424 100644 --- a/editeng/source/editeng/editdoc.cxx +++ b/editeng/source/editeng/editdoc.cxx @@ -574,14 +574,19 @@ void ConvertItem( std::unique_ptr<SfxPoolItem>& rPoolItem, MapUnit eSourceUnit, { assert(dynamic_cast<const SvxLRSpaceItem *>(rPoolItem.get()) != nullptr); SvxLRSpaceItem& rItem = static_cast<SvxLRSpaceItem&>(*rPoolItem); - if (rItem.GetTextFirstLineOffsetUnit() == css::util::MeasureUnit::TWIP) + if (rItem.GetTextFirstLineOffset().m_nUnit == css::util::MeasureUnit::TWIP) { rItem.SetTextFirstLineOffset( SvxIndentValue::twips(sal::static_int_cast<short>(OutputDevice::LogicToLogic( rItem.ResolveTextFirstLineOffset({}), eSourceUnit, eDestUnit)))); } - rItem.SetTextLeft( OutputDevice::LogicToLogic( rItem.GetTextLeft(), eSourceUnit, eDestUnit ) ); - rItem.SetRight( OutputDevice::LogicToLogic( rItem.GetRight(), eSourceUnit, eDestUnit ) ); + rItem.SetTextLeft(SvxIndentValue::twips( + OutputDevice::LogicToLogic(rItem.ResolveTextLeft({}), eSourceUnit, eDestUnit))); + if (rItem.GetRight().m_nUnit == css::util::MeasureUnit::TWIP) + { + rItem.SetRight(SvxIndentValue::twips( + OutputDevice::LogicToLogic(rItem.ResolveRight({}), eSourceUnit, eDestUnit))); + } } break; case EE_PARA_ULSPACE: diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx index 029ae6a9e223..24d30ba3b559 100644 --- a/editeng/source/editeng/impedit.hxx +++ b/editeng/source/editeng/impedit.hxx @@ -686,7 +686,8 @@ private: EditPaM RemoveText(); bool createLinesForEmptyParagraph(ParaPortion& rParaPortion); - tools::Long calculateMaxLineWidth(tools::Long nStartX, SvxLRSpaceItem const& rLRItem); + tools::Long calculateMaxLineWidth(tools::Long nStartX, SvxLRSpaceItem const& rLRItem, + const SvxFontUnitMetrics& rMetrics); bool CreateLines(sal_Int32 nPara, sal_uInt32 nStartPosY); void CreateAndInsertEmptyLine(ParaPortion& rParaPortion); diff --git a/editeng/source/editeng/impedit2.cxx b/editeng/source/editeng/impedit2.cxx index 95ea82178989..4fcf6e142a7a 100644 --- a/editeng/source/editeng/impedit2.cxx +++ b/editeng/source/editeng/impedit2.cxx @@ -3473,7 +3473,8 @@ sal_uInt32 ImpEditEngine::CalcParaWidth( sal_Int32 nPara, bool bIgnoreExtraSpace // width, here not preferred. I general, it is best not leave it // to StartPosX, also the right indents have to be taken into // account! - tools::Long nCurWidth = scaleXSpacingValue(rLRItem.GetTextLeft() + nSpaceBeforeAndMinLabelWidth); + tools::Long nCurWidth + = scaleXSpacingValue(rLRItem.ResolveTextLeft({}) + nSpaceBeforeAndMinLabelWidth); if ( nLine == 0 ) { tools::Long nFI = scaleXSpacingValue(rLRItem.ResolveTextFirstLineOffset(stMetrics)); @@ -3485,7 +3486,7 @@ sal_uInt32 ImpEditEngine::CalcParaWidth( sal_Int32 nPara, bool bIgnoreExtraSpace nCurWidth = pPortion->GetBulletX(); } } - nCurWidth += scaleXSpacingValue(rLRItem.GetRight()); + nCurWidth += scaleXSpacingValue(rLRItem.ResolveRight({})); nCurWidth += CalcLineWidth(*pPortion, rLine, bIgnoreExtraSpace); if ( nCurWidth > nMaxWidth ) { @@ -3800,7 +3801,7 @@ Point ImpEditEngine::GetDocPosTopLeft( sal_Int32 nParagraph ) const SvxLRSpaceItem& rLRItem = GetLRSpaceItem(pPPortion->GetNode()); sal_Int32 nSpaceBefore = 0; GetSpaceBeforeAndMinLabelWidth(pPPortion->GetNode(), &nSpaceBefore); - short nX = static_cast<short>(rLRItem.GetTextLeft() + short nX = static_cast<short>(rLRItem.ResolveTextLeft(stMetrics) + rLRItem.ResolveTextFirstLineOffset(stMetrics) + nSpaceBefore); diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx index b060d35fbc0a..068a6b56aa0f 100644 --- a/editeng/source/editeng/impedit3.cxx +++ b/editeng/source/editeng/impedit3.cxx @@ -605,18 +605,20 @@ bool ImpEditEngine::createLinesForEmptyParagraph(ParaPortion& rParaPortion) return FinishCreateLines(rParaPortion); } -tools::Long ImpEditEngine::calculateMaxLineWidth(tools::Long nStartX, SvxLRSpaceItem const& rLRItem) +tools::Long ImpEditEngine::calculateMaxLineWidth(tools::Long nStartX, SvxLRSpaceItem const& rLRItem, + const SvxFontUnitMetrics& rMetrics) { const bool bAutoSize = IsEffectivelyVertical() ? maStatus.AutoPageHeight() : maStatus.AutoPageWidth(); tools::Long nMaxLineWidth = GetColumnWidth(bAutoSize ? maMaxAutoPaperSize : maPaperSize); - nMaxLineWidth -= scaleXSpacingValue(rLRItem.GetRight()); + nMaxLineWidth -= scaleXSpacingValue(rLRItem.ResolveRight(rMetrics)); nMaxLineWidth -= nStartX; // If PaperSize == long_max, one cannot take away any negative // first line indent. (Overflow) if (nMaxLineWidth < 0 && nStartX < 0) - nMaxLineWidth = GetColumnWidth(maPaperSize) - scaleXSpacingValue(rLRItem.GetRight()); + nMaxLineWidth + = GetColumnWidth(maPaperSize) - scaleXSpacingValue(rLRItem.ResolveRight(rMetrics)); // If still less than 0, it may be just the right edge. if (nMaxLineWidth <= 0) @@ -810,12 +812,13 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY ) sal_Int32 nPortionStart = 0; sal_Int32 nPortionEnd = 0; - tools::Long nStartX = scaleXSpacingValue(rLRItem.GetTextLeft() + nSpaceBeforeAndMinLabelWidth); + auto stMetrics = GetFontUnitMetrics(pNode); + tools::Long nStartX + = scaleXSpacingValue(rLRItem.ResolveTextLeft(stMetrics) + nSpaceBeforeAndMinLabelWidth); // Multiline hyperlink may need to know if the next line is bigger. tools::Long nStartXNextLine = nStartX; if ( nIndex == 0 ) { - auto stMetrics = GetFontUnitMetrics(pNode); tools::Long nFI = scaleXSpacingValue(rLRItem.ResolveTextFirstLineOffset(stMetrics)); nStartX += nFI; @@ -827,7 +830,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY ) nStartX += nStartNextLineAfterMultiLineField; nStartNextLineAfterMultiLineField = 0; - tools::Long nMaxLineWidth = calculateMaxLineWidth(nStartX, rLRItem); + tools::Long nMaxLineWidth = calculateMaxLineWidth(nStartX, rLRItem, stMetrics); // Problem: // Since formatting starts a line _before_ the invalid position, @@ -905,8 +908,9 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY ) } } nXWidth = nMaxRangeWidth; - if ( nXWidth ) - nMaxLineWidth = nXWidth - nStartX - scaleXSpacingValue(rLRItem.GetRight()); + if (nXWidth) + nMaxLineWidth + = nXWidth - nStartX - scaleXSpacingValue(rLRItem.ResolveRight(stMetrics)); else { // Try further down in the polygon. @@ -1002,7 +1006,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY ) if (maStatus.DoStretch() && (fFontScalingX != 1.0)) nCurPos = basegfx::fround<tools::Long>(double(nCurPos) / std::max(fFontScalingX, 0.01)); - short nAllSpaceBeforeText = short(rLRItem.GetTextLeft()); + short nAllSpaceBeforeText = short(rLRItem.ResolveTextLeft({})); aCurrentTab.aTabStop = pNode->GetContentAttribs().FindTabStop( nCurPos - nAllSpaceBeforeText , maEditDoc.GetDefTab() ); aCurrentTab.nTabPos = tools::Long(aCurrentTab.aTabStop.GetTabPos() + nAllSpaceBeforeText); aCurrentTab.bValid = false; @@ -1575,7 +1579,9 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY ) // has to be used for the Alignment. If it does not fit or if it // will change the paper width, it will be formatted again for // Justification! = LEFT anyway. - tools::Long nMaxLineWidthFix = GetColumnWidth(maPaperSize) - scaleXSpacingValue(rLRItem.GetRight()) - nStartX; + tools::Long nMaxLineWidthFix = GetColumnWidth(maPaperSize) + - scaleXSpacingValue(rLRItem.ResolveRight(stMetrics)) + - nStartX; if ( aTextSize.Width() < nMaxLineWidthFix ) nMaxLineWidth = nMaxLineWidthFix; } @@ -1799,13 +1805,14 @@ void ImpEditEngine::CreateAndInsertEmptyLine(ParaPortion& rParaPortion) sal_Int32 nSpaceBeforeAndMinLabelWidth = GetSpaceBeforeAndMinLabelWidth(rParaPortion.GetNode(), &nSpaceBefore); const SvxLRSpaceItem& rLRItem = GetLRSpaceItem(rParaPortion.GetNode()); const SvxLineSpacingItem& rLSItem = rParaPortion.GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL ); - tools::Long nStartX = scaleXSpacingValue( - rLRItem.GetTextLeft() + rLRItem.ResolveTextFirstLineOffset(stMetrics) + nSpaceBefore); + tools::Long nStartX + = scaleXSpacingValue(rLRItem.ResolveTextLeft(stMetrics) + + rLRItem.ResolveTextFirstLineOffset(stMetrics) + nSpaceBefore); tools::Rectangle aBulletArea { Point(), Point() }; if ( bLineBreak ) { - nStartX = scaleXSpacingValue(rLRItem.GetTextLeft() + nStartX = scaleXSpacingValue(rLRItem.ResolveTextLeft(stMetrics) + rLRItem.ResolveTextFirstLineOffset(stMetrics) + nSpaceBeforeAndMinLabelWidth); } @@ -1818,7 +1825,7 @@ void ImpEditEngine::CreateAndInsertEmptyLine(ParaPortion& rParaPortion) rParaPortion.SetBulletX( 0 ); // If Bullet set incorrectly. if (rParaPortion.GetBulletX() > nStartX) { - nStartX = scaleXSpacingValue(rLRItem.GetTextLeft() + nStartX = scaleXSpacingValue(rLRItem.ResolveTextLeft(stMetrics) + rLRItem.ResolveTextFirstLineOffset(stMetrics) + nSpaceBeforeAndMinLabelWidth); if (rParaPortion.GetBulletX() > nStartX) @@ -1848,7 +1855,7 @@ void ImpEditEngine::CreateAndInsertEmptyLine(ParaPortion& rParaPortion) sal_Int32 nPara = GetParaPortions().GetPos(&rParaPortion); SvxAdjust eJustification = GetJustification( nPara ); tools::Long nMaxLineWidth = GetColumnWidth(maPaperSize); - nMaxLineWidth -= scaleXSpacingValue(rLRItem.GetRight()); + nMaxLineWidth -= scaleXSpacingValue(rLRItem.ResolveRight(stMetrics)); if ( nMaxLineWidth < 0 ) nMaxLineWidth = 1; if ( eJustification == SvxAdjust::Center ) diff --git a/editeng/source/editeng/impedit4.cxx b/editeng/source/editeng/impedit4.cxx index 50d7f6fe9669..e6730a64ef86 100644 --- a/editeng/source/editeng/impedit4.cxx +++ b/editeng/source/editeng/impedit4.cxx @@ -780,11 +780,11 @@ void ImpEditEngine::WriteItemAsRTF( const SfxPoolItem& rItem, SvStream& rOutput, nTxtFirst = LogicToTwips( nTxtFirst ); rOutput.WriteNumberAsString( nTxtFirst ); rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_LI ); - sal_uInt32 nTxtLeft = static_cast< sal_uInt32 >(static_cast<const SvxLRSpaceItem&>(rItem).GetTextLeft()); + sal_uInt32 nTxtLeft = static_cast<const SvxLRSpaceItem&>(rItem).ResolveTextLeft({}); nTxtLeft = static_cast<sal_uInt32>(LogicToTwips( nTxtLeft )); rOutput.WriteNumberAsString( nTxtLeft ); rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_RI ); - sal_uInt32 nTxtRight = static_cast<const SvxLRSpaceItem&>(rItem).GetRight(); + sal_uInt32 nTxtRight = static_cast<const SvxLRSpaceItem&>(rItem).ResolveRight({}); nTxtRight = LogicToTwips( nTxtRight); rOutput.WriteNumberAsString( nTxtRight ); } diff --git a/editeng/source/items/frmitems.cxx b/editeng/source/items/frmitems.cxx index 8b4e10e25c83..924ce4b50ece 100644 --- a/editeng/source/items/frmitems.cxx +++ b/editeng/source/items/frmitems.cxx @@ -288,11 +288,124 @@ bool SvxSizeItem::HasMetrics() const return true; } +double SvxIndentValue::ResolveDouble(const SvxFontUnitMetrics& rMetrics) const +{ + if (m_nUnit == css::util::MeasureUnit::TWIP) + return m_dValue; + + SAL_WARN_IF(!rMetrics.m_bInitialized, "editeng", "font-relative indentation lost"); + + switch (m_nUnit) + { + case css::util::MeasureUnit::FONT_EM: + return m_dValue * rMetrics.m_dEmTwips; + + case css::util::MeasureUnit::FONT_CJK_ADVANCE: + return m_dValue * rMetrics.m_dIcTwips; + + default: + SAL_WARN("editeng", "unhandled type conversion"); + return 0.0; + } +} + +sal_Int32 SvxIndentValue::Resolve(const SvxFontUnitMetrics& rMetrics) const +{ + return static_cast<sal_Int32>(std::llround(ResolveDouble(rMetrics))); +} + +sal_Int32 SvxIndentValue::ResolveFixedPart() const +{ + if (m_nUnit == css::util::MeasureUnit::TWIP) + return Resolve({}); + + return 0; +} + +sal_Int32 SvxIndentValue::ResolveVariablePart(const SvxFontUnitMetrics& rMetrics) const +{ + if (m_nUnit == css::util::MeasureUnit::TWIP) + return 0; + + return Resolve(rMetrics); +} + +void SvxIndentValue::ScaleMetrics(tools::Long const nMult, tools::Long const nDiv) +{ + m_dValue = (m_dValue * static_cast<double>(nMult)) / static_cast<double>(nDiv); +} + +size_t SvxIndentValue::hashCode() const +{ + std::size_t seed(0); + o3tl::hash_combine(seed, m_dValue); + o3tl::hash_combine(seed, m_nUnit); + return seed; +} + +namespace +{ + +boost::property_tree::ptree lcl_IndentValueToJson(const char* aName, SvxIndentValue stValue) +{ + boost::property_tree::ptree aState; + + switch (stValue.m_nUnit) + { + case css::util::MeasureUnit::TWIP: + { + OUString sValue + = GetMetricText(stValue.m_dValue, MapUnit::MapTwip, MapUnit::MapInch, nullptr); + aState.put(aName, sValue); + aState.put("unit", "inch"); + } + break; + + case css::util::MeasureUnit::FONT_EM: + aState.put(aName, stValue.m_dValue); + aState.put("unit", "em"); + break; + + case css::util::MeasureUnit::FONT_CJK_ADVANCE: + aState.put(aName, stValue.m_dValue); + aState.put("unit", "ic"); + break; + + default: + SAL_WARN("editeng", "unhandled type conversion"); + break; + } + + return aState; +} + +bool lcl_FillAbsoluteMeasureAny(const SvxIndentValue& rIndent, uno::Any& rVal, bool bConvert) +{ + if (rIndent.m_nUnit == css::util::MeasureUnit::TWIP) + { + auto nConvOffset = (bConvert ? convertTwipToMm100(rIndent.m_dValue) : rIndent.m_dValue); + rVal <<= static_cast<sal_Int32>(std::llround(nConvOffset)); + return true; + } + + return false; +} + +bool lcl_FillRelativeMeasureAny(const SvxIndentValue& rIndent, uno::Any& rVal) +{ + if (rIndent.m_nUnit != css::util::MeasureUnit::TWIP) + { + rVal <<= css::beans::Pair<double, sal_Int16>{ rIndent.m_dValue, rIndent.m_nUnit }; + return true; + } + + return false; +} + +} SvxLRSpaceItem::SvxLRSpaceItem(const sal_uInt16 nId) : SfxPoolItem(nId, SfxItemType::SvxLRSpaceItemType) - , nLeftMargin(0) - , nRightMargin(0) , m_nGutterMargin(0) , m_nRightGutterMargin(0), nPropFirstLineOffset( 100 ), @@ -304,11 +417,9 @@ SvxLRSpaceItem::SvxLRSpaceItem(const sal_uInt16 nId) { } -SvxLRSpaceItem::SvxLRSpaceItem(const tools::Long nLeft, const tools::Long nRight, +SvxLRSpaceItem::SvxLRSpaceItem(SvxIndentValue stLeft, SvxIndentValue stRight, SvxIndentValue stOffset, const sal_uInt16 nId) : SfxPoolItem(nId, SfxItemType::SvxLRSpaceItemType) - , nLeftMargin(nLeft) - , nRightMargin(nRight) , m_nGutterMargin(0) , m_nRightGutterMargin(0) , nPropFirstLineOffset(100) @@ -318,6 +429,8 @@ SvxLRSpaceItem::SvxLRSpaceItem(const tools::Long nLeft, const tools::Long nRight , bExplicitZeroMarginValRight(false) , bExplicitZeroMarginValLeft(false) { + SetLeft(stLeft); + SetRight(stRight); SetTextFirstLineOffset(stOffset); } @@ -333,9 +446,19 @@ bool SvxLRSpaceItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const case 0: { css::frame::status::LeftRightMarginScale aLRSpace; - aLRSpace.Left = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nLeftMargin) : nLeftMargin); - aLRSpace.TextLeft = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(GetTextLeft()) : GetTextLeft()); - aLRSpace.Right = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nRightMargin) : nRightMargin); + + auto nLeftTwips = ResolveLeft({}); + aLRSpace.Left + = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nLeftTwips) : nLeftTwips); + + auto nTextLeftTwips = ResolveTextLeft({}); + aLRSpace.TextLeft = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nTextLeftTwips) + : nTextLeftTwips); + + auto nRightTwips = ResolveRight({}); + aLRSpace.Right + = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nRightTwips) : nRightTwips); + aLRSpace.ScaleLeft = static_cast<sal_Int16>(nPropLeftMargin); aLRSpace.ScaleRight = static_cast<sal_Int16>(nPropRightMargin); @@ -348,15 +471,24 @@ bool SvxLRSpaceItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const break; } case MID_L_MARGIN: - rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nLeftMargin) : nLeftMargin); + bRet = lcl_FillAbsoluteMeasureAny(GetLeft(), rVal, bConvert); + break; + + case MID_TXT_LMARGIN: + bRet = lcl_FillAbsoluteMeasureAny(GetTextLeft(), rVal, bConvert); + break; + + case MID_L_UNIT_MARGIN: + bRet = lcl_FillRelativeMeasureAny(GetTextLeft(), rVal); break; - case MID_TXT_LMARGIN : - rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(GetTextLeft()) : GetTextLeft()); - break; case MID_R_MARGIN: - rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nRightMargin) : nRightMargin); + bRet = lcl_FillAbsoluteMeasureAny(m_stRightMargin, rVal, bConvert); + break; + case MID_R_UNIT_MARGIN: + bRet = lcl_FillRelativeMeasureAny(m_stRightMargin, rVal); break; + case MID_L_REL_MARGIN: rVal <<= static_cast<sal_Int16>(nPropLeftMargin); break; @@ -365,38 +497,16 @@ bool SvxLRSpaceItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const break; case MID_FIRST_LINE_INDENT: - // MID_FIRST_LINE_INDENT only supports statically-convertible measures. - // In practice, these are always stored here in twips. - if (m_nFirstLineUnit == css::util::MeasureUnit::TWIP) - { - auto nConvOffset - = (bConvert ? convertTwipToMm100(m_dFirstLineOffset) : m_dFirstLineOffset); - rVal <<= static_cast<sal_Int32>(std::llround(nConvOffset)); - } - else - { - bRet = false; - } - break; + bRet = lcl_FillAbsoluteMeasureAny(m_stFirstLineOffset, rVal, bConvert); + break; case MID_FIRST_LINE_REL_INDENT: rVal <<= static_cast<sal_Int16>(nPropFirstLineOffset); break; case MID_FIRST_LINE_UNIT_INDENT: - // MID_FIRST_LINE_UNIT_INDENT is used for any values that must be serialized - // as a unit-value pair. In practice, this will be limited to font-relative - // units (e.g. em, ic), and all other units will be pre-converted to twips. - if (m_nFirstLineUnit != css::util::MeasureUnit::TWIP) - { - rVal - <<= css::beans::Pair<double, sal_Int16>{ m_dFirstLineOffset, m_nFirstLineUnit }; - } - else - { - bRet = false; - } - break; + bRet = lcl_FillRelativeMeasureAny(m_stFirstLineOffset, rVal); + break; case MID_FIRST_AUTO: rVal <<= IsAutoFirst(); @@ -422,8 +532,9 @@ bool SvxLRSpaceItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) nMemberId &= ~CONVERT_TWIPS; sal_Int32 nVal = 0; if (nMemberId != 0 && nMemberId != MID_FIRST_AUTO && nMemberId != MID_L_REL_MARGIN - && nMemberId != MID_R_REL_MARGIN && nMemberId != MID_FIRST_LINE_UNIT_INDENT) - if(!(rVal >>= nVal)) + && nMemberId != MID_R_REL_MARGIN && nMemberId != MID_FIRST_LINE_UNIT_INDENT + && nMemberId != MID_L_UNIT_MARGIN && nMemberId != MID_R_UNIT_MARGIN) + if (!(rVal >>= nVal)) return false; switch( nMemberId ) @@ -434,9 +545,13 @@ bool SvxLRSpaceItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) if(!(rVal >>= aLRSpace)) return false; - SetLeft( bConvert ? o3tl::toTwips(aLRSpace.Left, o3tl::Length::mm100) : aLRSpace.Left ); - SetTextLeft( bConvert ? o3tl::toTwips(aLRSpace.TextLeft, o3tl::Length::mm100) : aLRSpace.TextLeft ); - SetRight(bConvert ? o3tl::toTwips(aLRSpace.Right, o3tl::Length::mm100) : aLRSpace.Right); + SetLeft(SvxIndentValue::twips( + bConvert ? o3tl::toTwips(aLRSpace.Left, o3tl::Length::mm100) : aLRSpace.Left)); + SetTextLeft(SvxIndentValue::twips( + bConvert ? o3tl::toTwips(aLRSpace.TextLeft, o3tl::Length::mm100) + : aLRSpace.TextLeft)); + SetRight(SvxIndentValue::twips( + bConvert ? o3tl::toTwips(aLRSpace.Right, o3tl::Length::mm100) : aLRSpace.Right)); nPropLeftMargin = aLRSpace.ScaleLeft; nPropRightMargin = aLRSpace.ScaleRight; SetTextFirstLineOffset(SvxIndentValue::twips( @@ -447,16 +562,44 @@ bool SvxLRSpaceItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) break; } case MID_L_MARGIN: - SetLeft( bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal ); + SetLeft( + SvxIndentValue::twips(bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal)); break; - case MID_TXT_LMARGIN : - SetTextLeft( bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal ); - break; + case MID_TXT_LMARGIN: + SetTextLeft( + SvxIndentValue::twips(bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal)); + break; + + case MID_L_UNIT_MARGIN: + { + css::beans::Pair<double, sal_Int16> stVal; + if (!(rVal >>= stVal)) + { + return false; + } + + SetTextLeft(SvxIndentValue{ stVal.First, stVal.Second }); + break; + } case MID_R_MARGIN: - SetRight(bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal); + SetRight( + SvxIndentValue::twips(bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal)); break; + + case MID_R_UNIT_MARGIN: + { + css::beans::Pair<double, sal_Int16> stVal; + if (!(rVal >>= stVal)) + { + return false; + } + + SetRight(SvxIndentValue{ stVal.First, stVal.Second }); + break; + } + case MID_L_REL_MARGIN: case MID_R_REL_MARGIN: { @@ -472,7 +615,7 @@ bool SvxLRSpaceItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) return false; } break; - case MID_FIRST_LINE_INDENT : + case MID_FIRST_LINE_INDENT: SetTextFirstLineOffset( SvxIndentValue::twips(bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal)); break; @@ -514,147 +657,226 @@ void SvxLeftMarginItem::SetLeft(const tools::Long nL, const sal_uInt16 nProp) m_nPropLeftMargin = nProp; } -void SvxLRSpaceItem::SetLeft(const tools::Long nL, const sal_uInt16 nProp) +void SvxLRSpaceItem::SetLeft(SvxIndentValue stL, const sal_uInt16 nProp) { - nLeftMargin = (nL * nProp) / 100; - SAL_WARN_IF(m_dFirstLineOffset != 0.0, "editeng", + SAL_WARN_IF(m_stFirstLineOffset.m_dValue != 0.0, "editeng", "probably call SetTextLeft instead? looks inconsistent otherwise"); + + m_stLeftMargin = stL; nPropLeftMargin = nProp; + + if (nProp != 100) + { + m_stLeftMargin.m_dValue = (stL.m_dValue * static_cast<double>(nProp)) / 100.0; + } } -void SvxRightMarginItem::SetRight(const tools::Long nR, const sal_uInt16 nProp) +SvxIndentValue SvxLRSpaceItem::GetLeft() const { return m_stLeftMargin; } + +sal_Int32 SvxLRSpaceItem::ResolveLeft(const SvxFontUnitMetrics& rMetrics) const +{ + return m_stLeftMargin.Resolve(rMetrics); +} + +void SvxRightMarginItem::SetRight(SvxIndentValue stR, const sal_uInt16 nProp) { ASSERT_CHANGE_REFCOUNTED_ITEM; - m_nRightMargin = (nR * nProp) / 100; + + m_stRightMargin = stR; m_nPropRightMargin = nProp; + + if (nProp != 100) + { + m_stRightMargin.m_dValue = (stR.m_dValue * static_cast<double>(nProp)) / 100.0; + } } -void SvxLRSpaceItem::SetRight(const tools::Long nR, const sal_uInt16 nProp) +SvxIndentValue SvxRightMarginItem::GetRight() const { return m_stRightMargin; } + +SvxIndentValue SvxLRSpaceItem::GetRight() const { return m_stRightMargin; } + +sal_Int32 SvxRightMarginItem::ResolveRight(const SvxFontUnitMetrics& rMetrics) const { - if (0 == nR) + return m_stRightMargin.Resolve(rMetrics); +} + +sal_Int32 SvxLRSpaceItem::ResolveRight(const SvxFontUnitMetrics& rMetrics) const +{ + return m_stRightMargin.Resolve(rMetrics); +} + +sal_Int32 SvxRightMarginItem::ResolveRightFixedPart() const +{ + return m_stRightMargin.ResolveFixedPart(); +} + +sal_Int32 SvxRightMarginItem::ResolveRightVariablePart(const SvxFontUnitMetrics& rMetrics) const +{ + return m_stRightMargin.ResolveVariablePart(rMetrics); +} + +sal_uInt16 SvxRightMarginItem::GetPropRight() const { return m_nPropRightMargin; } + +void SvxLRSpaceItem::SetRight(SvxIndentValue stR, const sal_uInt16 nProp) +{ + if (0.0 == stR.m_dValue) { SetExplicitZeroMarginValRight(true); } - nRightMargin = (nR * nProp) / 100; + + m_stRightMargin = stR; nPropRightMargin = nProp; + + if (nProp != 100) + { + m_stRightMargin.m_dValue = (stR.m_dValue * static_cast<double>(nProp)) / 100.0; + } } void SvxLRSpaceItem::SetTextFirstLineOffset(SvxIndentValue stValue, sal_uInt16 nProp) { // note: left margin contains any negative first line offset - preserve it! - if (m_dFirstLineOffset < 0.0) + if (m_stFirstLineOffset.m_dValue < 0.0) { - nLeftMargin -= ResolveTextFirstLineOffset({}); + m_stLeftMargin + = SvxIndentValue::twips(m_stLeftMargin.Resolve({}) - ResolveTextFirstLineOffset({})); } - m_dFirstLineOffset = stValue.m_dValue; - m_nFirstLineUnit = stValue.m_nUnit; + m_stFirstLineOffset = stValue; nPropFirstLineOffset = nProp; if (nProp != 100) { - m_dFirstLineOffset = (stValue.m_dValue * static_cast<double>(nProp)) / 100.0; + m_stFirstLineOffset.m_dValue = (stValue.m_dValue * static_cast<double>(nProp)) / 100.0; } - if (m_dFirstLineOffset < 0.0) + if (m_stFirstLineOffset.m_dValue < 0.0) { - nLeftMargin += ResolveTextFirstLineOffset({}); + m_stLeftMargin + = SvxIndentValue::twips(m_stLeftMargin.Resolve({}) + ResolveTextFirstLineOffset({})); } } -#if 0 -void SvxTextLeftMarginItem::SetLeft(SvxFirstLineIndentItem const& rFirstLine, - const tools::Long nL, const sal_uInt16 nProp) +void SvxTextLeftMarginItem::SetTextLeft(SvxIndentValue stL, const sal_uInt16 nProp) { - m_nTextLeftMargin = (nL * nProp) / 100; + ASSERT_CHANGE_REFCOUNTED_ITEM; + + m_stTextLeftMargin = stL; m_nPropLeftMargin = nProp; - // note: text left margin contains any negative first line offset - if (rFirstLine.GetTextFirstLineOffset() < 0) + + if (nProp != 100) { - m_nTextLeftMargin += rFirstLine.GetTextFirstLineOffset(); + m_stTextLeftMargin.m_dValue = (stL.m_dValue * static_cast<double>(nProp)) / 100.0; } } -#endif -void SvxTextLeftMarginItem::SetTextLeft(const tools::Long nL, const sal_uInt16 nProp) +void SvxLRSpaceItem::SetTextLeft(SvxIndentValue stL, const sal_uInt16 nProp) { - ASSERT_CHANGE_REFCOUNTED_ITEM; - m_nTextLeftMargin = (nL * nProp) / 100; - m_nPropLeftMargin = nProp; -} - -void SvxLRSpaceItem::SetTextLeft(const tools::Long nL, const sal_uInt16 nProp) -{ - if (0 == nL) + if (0.0 == stL.m_dValue) { SetExplicitZeroMarginValLeft(true); } - auto const nTxtLeft = (nL * nProp) / 100; + + m_stLeftMargin = stL; nPropLeftMargin = nProp; + + if (nProp != 100) + { + m_stLeftMargin.m_dValue = (stL.m_dValue * static_cast<double>(nProp)) / 100.0; + } + // note: left margin contains any negative first line offset - if (0.0 > m_dFirstLineOffset) - nLeftMargin = nTxtLeft + ResolveTextFirstLineOffset({}); - else - nLeftMargin = nTxtLeft; + if (0.0 > m_stFirstLineOffset.m_dValue) + { + m_stLeftMargin + = SvxIndentValue::twips(m_stLeftMargin.Resolve({}) + ResolveTextFirstLineOffset({})); + } } SvxIndentValue SvxLRSpaceItem::GetTextFirstLineOffset() const { - return { m_dFirstLineOffset, m_nFirstLineUnit }; + return m_stFirstLineOffset; } -double SvxLRSpaceItem::GetTextFirstLineOffsetValue() const { return m_dFirstLineOffset; } +sal_Int32 SvxLRSpaceItem::ResolveTextFirstLineOffset(const SvxFontUnitMetrics& rMetrics) const +{ + return m_stFirstLineOffset.Resolve(rMetrics); +} -sal_Int16 SvxLRSpaceItem::GetTextFirstLineOffsetUnit() const { return m_nFirstLineUnit; } +SvxIndentValue SvxTextLeftMarginItem::GetTextLeft() const { return m_stTextLeftMargin; } -double SvxLRSpaceItem::ResolveTextFirstLineOffsetDouble(const SvxFontUnitMetrics& rMetrics) const +sal_Int32 SvxTextLeftMarginItem::ResolveTextLeft(const SvxFontUnitMetrics& rMetrics) const { - if (m_nFirstLineUnit == css::util::MeasureUnit::TWIP) - return m_dFirstLineOffset; + return m_stTextLeftMargin.Resolve(rMetrics); +} - SAL_WARN_IF(!rMetrics.m_bInitialized, "editeng", "font-relative indentation lost"); +sal_Int32 SvxTextLeftMarginItem::ResolveLeft(const SvxFirstLineIndentItem& rFirstLine, + const SvxFontUnitMetrics& rMetrics) const +{ + auto nLeft = m_stTextLeftMargin.Resolve(rMetrics); - switch (m_nFirstLineUnit) + // add any negative first line offset to text left margin to get left + auto nFirstLine = rFirstLine.GetTextFirstLineOffset().Resolve(rMetrics); + if (nFirstLine < 0) { - case css::util::MeasureUnit::FONT_EM: - return m_dFirstLineOffset * rMetrics.m_dEmTwips; - - case css::util::MeasureUnit::FONT_CJK_ADVANCE: - return m_dFirstLineOffset * rMetrics.m_dIcTwips; - - default: - SAL_WARN("editeng", "unhandled type conversion"); - return 0.0; + nLeft += nFirstLine; } + + return nLeft; } -sal_Int32 SvxLRSpaceItem::ResolveTextFirstLineOffset(const SvxFontUnitMetrics& rMetrics) const +sal_Int32 +SvxTextLeftMarginItem::ResolveLeftFixedPart(const SvxFirstLineIndentItem& rFirstLine) const { - return static_cast<sal_Int32>(std::llround(ResolveTextFirstLineOffsetDouble(rMetrics))); + auto nLeft = m_stTextLeftMargin.ResolveFixedPart(); + + // add any negative first line offset to text left margin to get left + auto nFirstLine = rFirstLine.GetTextFirstLineOffset().ResolveFixedPart(); + if (nFirstLine < 0) + { + nLeft += nFirstLine; + } + + return nLeft; } -tools::Long SvxTextLeftMarginItem::GetTextLeft() const +sal_Int32 SvxTextLeftMarginItem::ResolveLeftVariablePart(const SvxFirstLineIndentItem& rFirstLine, + const SvxFontUnitMetrics& rMetrics) const { - return m_nTextLeftMargin; + auto nLeft = m_stTextLeftMargin.ResolveVariablePart(rMetrics); + + // add any negative first line offset to text left margin to get left + auto nFirstLine = rFirstLine.GetTextFirstLineOffset().ResolveVariablePart(rMetrics); + if (nFirstLine < 0) + { + nLeft += nFirstLine; + } + + return nLeft; } -tools::Long SvxTextLeftMarginItem::GetLeft(const SvxFirstLineIndentItem& rFirstLine, - const SvxFontUnitMetrics& rMetrics) const +sal_uInt16 SvxTextLeftMarginItem::GetPropLeft() const { return m_nPropLeftMargin; } + +SvxIndentValue SvxLRSpaceItem::GetTextLeft() const { - // add any negative first line offset to text left margin to get left - if (rFirstLine.GetTextFirstLineOffsetValue() < 0.0) + // remove any negative first line offset from left margin to get text-left + if (m_stFirstLineOffset.m_dValue < 0.0) { - auto nFirstLineOffset = rFirstLine.ResolveTextFirstLineOffset(rMetrics); - return m_nTextLeftMargin + nFirstLineOffset; + return SvxIndentValue::twips(m_stLeftMargin.Resolve({}) - ResolveTextFirstLineOffset({})); } - return m_nTextLeftMargin; + return m_stLeftMargin; } -tools::Long SvxLRSpaceItem::GetTextLeft() const +sal_Int32 SvxLRSpaceItem::ResolveTextLeft(const SvxFontUnitMetrics& rMetrics) const { // remove any negative first line offset from left margin to get text-left - return (m_dFirstLineOffset < 0) ? nLeftMargin - ResolveTextFirstLineOffset({}) : nLeftMargin; + if (m_stFirstLineOffset.m_dValue < 0.0) + { + return m_stLeftMargin.Resolve(rMetrics) - ResolveTextFirstLineOffset(rMetrics); + } + + return m_stLeftMargin.Resolve(rMetrics); } SvxLeftMarginItem::SvxLeftMarginItem(const sal_uInt16 nId) @@ -830,15 +1052,15 @@ SvxTextLeftMarginItem::SvxTextLeftMarginItem(const sal_uInt16 nId) { } -SvxTextLeftMarginItem::SvxTextLeftMarginItem(const tools::Long nLeft, const sal_uInt16 nId) +SvxTextLeftMarginItem::SvxTextLeftMarginItem(SvxIndentValue stLeft, const sal_uInt16 nId) : SfxPoolItem(nId, SfxItemType::SvxTextLeftMarginItemType) - , m_nTextLeftMargin(nLeft) { + SetTextLeft(stLeft); } bool SvxTextLeftMarginItem::QueryValue(uno::Any& rVal, sal_uInt8 nMemberId) const { - bool bRet = true; + bool bRet = false; bool bConvert = 0 != (nMemberId & CONVERT_TWIPS); nMemberId &= ~CONVERT_TWIPS; switch (nMemberId) @@ -847,17 +1069,25 @@ bool SvxTextLeftMarginItem::QueryValue(uno::Any& rVal, sal_uInt8 nMemberId) cons case 0: { css::frame::status::LeftRightMarginScale aLRSpace; - aLRSpace.TextLeft = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(GetTextLeft()) : GetTextLeft()); + + auto nLeftTwips = m_stTextLeftMargin.Resolve({}); + aLRSpace.TextLeft + = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nLeftTwips) : nLeftTwips); aLRSpace.ScaleLeft = static_cast<sal_Int16>(m_nPropLeftMargin); rVal <<= aLRSpace; + bRet = true; break; } case MID_TXT_LMARGIN : - rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(GetTextLeft()) : GetTextLeft()); - break; + bRet = lcl_FillAbsoluteMeasureAny(m_stTextLeftMargin, rVal, bConvert); + break; case MID_L_REL_MARGIN: rVal <<= static_cast<sal_Int16>(m_nPropLeftMargin); - break; + bRet = true; + break; + case MID_L_UNIT_MARGIN: + bRet = lcl_FillRelativeMeasureAny(m_stTextLeftMargin, rVal); + break; default: assert(false); bRet = false; @@ -882,9 +1112,10 @@ bool SvxTextLeftMarginItem::PutValue(const uno::Any& rVal, sal_uInt8 nMemberId) { return false; } - SetTextLeft(bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal); + SetTextLeft( + SvxIndentValue::twips(bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal)); + break; } - break; case MID_L_REL_MARGIN: { sal_Int32 nRel = 0; @@ -896,8 +1127,19 @@ bool SvxTextLeftMarginItem::PutValue(const uno::Any& rVal, sal_uInt8 nMemberId) { return false; } + break; + } + case MID_L_UNIT_MARGIN: + { + css::beans::Pair<double, sal_Int16> stVal; + if (!(rVal >>= stVal)) + { + return false; + } + + SetTextLeft(SvxIndentValue{ stVal.First, stVal.Second }); + break; } - break; default: assert(false); OSL_FAIL("unknown MemberId"); @@ -912,14 +1154,14 @@ bool SvxTextLeftMarginItem::operator==(const SfxPoolItem& rAttr) const const SvxTextLeftMarginItem& rOther = static_cast<const SvxTextLeftMarginItem&>(rAttr); - return (m_nTextLeftMargin == rOther.GetTextLeft() - && m_nPropLeftMargin == rOther.GetPropLeft()); + return std::tie(m_stTextLeftMargin, m_nPropLeftMargin) + == std::tie(rOther.m_stTextLeftMargin, rOther.m_nPropLeftMargin); } size_t SvxTextLeftMarginItem::hashCode() const { std::size_t seed(0); - o3tl::hash_combine(seed, m_nTextLeftMargin); + o3tl::hash_combine(seed, m_stTextLeftMargin.hashCode()); o3tl::hash_combine(seed, m_nPropLeftMargin); return seed; } @@ -947,10 +1189,16 @@ bool SvxTextLeftMarginItem::GetPresentation rText = unicode::formatPercent(m_nPropLeftMargin, Application::GetSettings().GetUILanguageTag()); } + else if (m_stTextLeftMargin.m_nUnit != css::util::MeasureUnit::TWIP) + { + OUStringBuffer stBuf; + sax::Converter::convertMeasureUnit(stBuf, m_stTextLeftMargin.m_dValue, + m_stTextLeftMargin.m_nUnit); + rText += stBuf.makeStringAndClear(); + } else { - rText = GetMetricText(m_nTextLeftMargin, - eCoreUnit, ePresUnit, &rIntl); + rText = GetMetricText(m_stTextLeftMargin.m_dValue, eCoreUnit, ePresUnit, &rIntl); } return true; } @@ -962,9 +1210,16 @@ bool SvxTextLeftMarginItem::GetPresentation rText += unicode::formatPercent(m_nPropLeftMargin, Application::GetSettings().GetUILanguageTag()); } + else if (m_stTextLeftMargin.m_nUnit != css::util::MeasureUnit::TWIP) + { + OUStringBuffer stBuf; + sax::Converter::convertMeasureUnit(stBuf, m_stTextLeftMargin.m_dValue, + m_stTextLeftMargin.m_nUnit); + rText += stBuf.makeStringAndClear(); + } else { - rText += GetMetricText(m_nTextLeftMargin, eCoreUnit, ePresUnit, &rIntl) + rText += GetMetricText(m_stTextLeftMargin.m_dValue, eCoreUnit, ePresUnit, &rIntl) + " " + EditResId(GetMetricId(ePresUnit)); } return true; @@ -977,7 +1232,7 @@ bool SvxTextLeftMarginItem::GetPresentation void SvxTextLeftMarginItem::ScaleMetrics(tools::Long const nMult, tools::Long const nDiv) { ASSERT_CHANGE_REFCOUNTED_ITEM; - m_nTextLeftMargin = BigInt::Scale(m_nTextLeftMargin, nMult, nDiv); + m_stTextLeftMargin.ScaleMetrics(nMult, nDiv); } bool SvxTextLeftMarginItem::HasMetrics() const @@ -989,7 +1244,12 @@ void SvxTextLeftMarginItem::dumpAsXml(xmlTextWriterPtr pWriter) const { (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxTextLeftMarginItem")); (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr())); - (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nTextLeftMargin"), BAD_CAST(OString::number(m_nTextLeftMargin).getStr())); + (void)xmlTextWriterWriteAttribute( + pWriter, BAD_CAST("m_dTextLeftMargin"), + BAD_CAST(OString::number(m_stTextLeftMargin.m_dValue).getStr())); + (void)xmlTextWriterWriteAttribute( + pWriter, BAD_CAST("m_nUnit"), + BAD_CAST(OString::number(m_stTextLeftMargin.m_nUnit).getStr())); (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nPropLeftMargin"), BAD_CAST(OString::number(m_nPropLeftMargin).getStr())); (void)xmlTextWriterEndElement(pWriter); } @@ -998,16 +1258,7 @@ boost::property_tree::ptree SvxTextLeftMarginItem::dumpAsJSON() const { boost::property_tree::ptree aTree = SfxPoolItem::dumpAsJSON(); - boost::property_tree::ptree aState; - - MapUnit eTargetUnit = MapUnit::MapInch; - - OUString sLeft = GetMetricText(GetTextLeft(), - MapUnit::MapTwip, eTargetUnit, nullptr); - - aState.put("left", sLeft); - aState.put("unit", "inch"); - + auto aState = lcl_IndentValueToJson("left", m_stTextLeftMargin); aTree.push_back(std::make_pair("state", aState)); return aTree; @@ -1046,51 +1297,24 @@ sal_uInt16 SvxFirstLineIndentItem::GetPropTextFirstLineOffset() const void SvxFirstLineIndentItem::SetTextFirstLineOffset(SvxIndentValue stValue, sal_uInt16 nProp) { ASSERT_CHANGE_REFCOUNTED_ITEM; - m_dFirstLineOffset = stValue.m_dValue; - m_nUnit = stValue.m_nUnit; + m_stFirstLineOffset = stValue; m_nPropFirstLineOffset = nProp; if (nProp != 100) { - m_dFirstLineOffset = (stValue.m_dValue * static_cast<double>(nProp)) / 100.0; + m_stFirstLineOffset.m_dValue = (stValue.m_dValue * static_cast<double>(nProp)) / 100.0; } } SvxIndentValue SvxFirstLineIndentItem::GetTextFirstLineOffset() const { - return { m_dFirstLineOffset, m_nUnit }; -} - -double SvxFirstLineIndentItem::GetTextFirstLineOffsetValue() const { return m_dFirstLineOffset; } - -sal_Int16 SvxFirstLineIndentItem::GetTextFirstLineOffsetUnit() const { return m_nUnit; } - -double -SvxFirstLineIndentItem::ResolveTextFirstLineOffsetDouble(const SvxFontUnitMetrics& rMetrics) const -{ - if(m_nUnit == css::util::MeasureUnit::TWIP) - return m_dFirstLineOffset; - - SAL_WARN_IF(!rMetrics.m_bInitialized, "editeng", "font-relative indentation lost"); - - switch (m_nUnit) - { - case css::util::MeasureUnit::FONT_EM: - return m_dFirstLineOffset * rMetrics.m_dEmTwips; - - case css::util::MeasureUnit::FONT_CJK_ADVANCE: - return m_dFirstLineOffset * rMetrics.m_dIcTwips; - - default: - SAL_WARN("editeng", "unhandled type conversion"); - return 0.0; - } + return m_stFirstLineOffset; } sal_Int32 SvxFirstLineIndentItem::ResolveTextFirstLineOffset(const SvxFontUnitMetrics& rMetrics) const { - return static_cast<sal_Int32>(std::llround(ResolveTextFirstLineOffsetDouble(rMetrics))); + return m_stFirstLineOffset.Resolve(rMetrics); } bool SvxFirstLineIndentItem::QueryValue(uno::Any& rVal, sal_uInt8 nMemberId) const @@ -1101,16 +1325,8 @@ bool SvxFirstLineIndentItem::QueryValue(uno::Any& rVal, sal_uInt8 nMemberId) con switch (nMemberId) { case MID_FIRST_LINE_INDENT: - // MID_FIRST_LINE_INDENT only supports statically-convertible measures. - // In practice, these are always stored here in twips. - if (m_nUnit == css::util::MeasureUnit::TWIP) - { - auto nConvOffset - = (bConvert ? convertTwipToMm100(m_dFirstLineOffset) : m_dFirstLineOffset); - rVal <<= static_cast<sal_Int32>(std::llround(nConvOffset)); - bRet = true; - } - break; + bRet = lcl_FillAbsoluteMeasureAny(m_stFirstLineOffset, rVal, bConvert); + break; case MID_FIRST_LINE_REL_INDENT: rVal <<= static_cast<sal_Int16>(m_nPropFirstLineOffset); @@ -1118,15 +1334,8 @@ bool SvxFirstLineIndentItem::QueryValue(uno::Any& rVal, sal_uInt8 nMemberId) con break; case MID_FIRST_LINE_UNIT_INDENT: - // MID_FIRST_LINE_UNIT_INDENT is used for any values that must be serialized - // as a unit-value pair. In practice, this will be limited to font-relative - // units (e.g. em, ic), and all other units will be pre-converted to twips. - if (m_nUnit != css::util::MeasureUnit::TWIP) - { - rVal <<= css::beans::Pair<double, sal_Int16>{ m_dFirstLineOffset, m_nUnit }; - bRet = true; - } - break; + bRet = lcl_FillRelativeMeasureAny(m_stFirstLineOffset, rVal); + break; case MID_FIRST_AUTO: rVal <<= IsAutoFirst(); @@ -1158,8 +1367,8 @@ bool SvxFirstLineIndentItem::PutValue(const uno::Any& rVal, sal_uInt8 nMemberId) return false; } - m_dFirstLineOffset = bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal; - m_nUnit = css::util::MeasureUnit::TWIP; + m_stFirstLineOffset + = SvxIndentValue::twips(bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal); m_nPropFirstLineOffset = 100; break; } @@ -1204,16 +1413,15 @@ bool SvxFirstLineIndentItem::operator==(const SfxPoolItem& rAttr) const const SvxFirstLineIndentItem& rOther = static_cast<const SvxFirstLineIndentItem&>(rAttr); - return std::tie(m_dFirstLineOffset, m_nUnit, m_nPropFirstLineOffset, m_bAutoFirst) - == std::tie(rOther.m_dFirstLineOffset, rOther.m_nUnit, rOther.m_nPropFirstLineOffset, + return std::tie(m_stFirstLineOffset, m_nPropFirstLineOffset, m_bAutoFirst) + == std::tie(rOther.m_stFirstLineOffset, rOther.m_nPropFirstLineOffset, rOther.m_bAutoFirst); } size_t SvxFirstLineIndentItem::hashCode() const { std::size_t seed(0); - o3tl::hash_combine(seed, m_dFirstLineOffset); - o3tl::hash_combine(seed, m_nUnit); + o3tl::hash_combine(seed, m_stFirstLineOffset.hashCode()); o3tl::hash_combine(seed, m_nPropFirstLineOffset); o3tl::hash_combine(seed, m_bAutoFirst); return seed; @@ -1241,15 +1449,16 @@ bool SvxFirstLineIndentItem::GetPresentation rText += unicode::formatPercent(m_nPropFirstLineOffset, Application::GetSettings().GetUILanguageTag()); } - else if (m_nUnit != css::util::MeasureUnit::TWIP) + else if (m_stFirstLineOffset.m_nUnit != css::util::MeasureUnit::TWIP) { OUStringBuffer stBuf; - sax::Converter::convertMeasureUnit(stBuf, m_dFirstLineOffset, m_nUnit); + sax::Converter::convertMeasureUnit(stBuf, m_stFirstLineOffset.m_dValue, + m_stFirstLineOffset.m_nUnit); rText += stBuf.makeStringAndClear(); } else { - rText += GetMetricText(m_dFirstLineOffset, eCoreUnit, ePresUnit, &rIntl); + rText += GetMetricText(m_stFirstLineOffset.m_dValue, eCoreUnit, ePresUnit, &rIntl); } return true; } @@ -1261,16 +1470,17 @@ bool SvxFirstLineIndentItem::GetPresentation rText += unicode::formatPercent(m_nPropFirstLineOffset, Application::GetSettings().GetUILanguageTag()); } - else if (m_nUnit != css::util::MeasureUnit::TWIP) + else if (m_stFirstLineOffset.m_nUnit != css::util::MeasureUnit::TWIP) { OUStringBuffer stBuf; - sax::Converter::convertMeasureUnit(stBuf, m_dFirstLineOffset, m_nUnit); + sax::Converter::convertMeasureUnit(stBuf, m_stFirstLineOffset.m_dValue, + m_stFirstLineOffset.m_nUnit); rText += stBuf.makeStringAndClear(); } else { - rText += GetMetricText(m_dFirstLineOffset, eCoreUnit, ePresUnit, &rIntl) + " " - + EditResId(GetMetricId(ePresUnit)); + rText += GetMetricText(m_stFirstLineOffset.m_dValue, eCoreUnit, ePresUnit, &rIntl) + + " " + EditResId(GetMetricId(ePresUnit)); } return true; } @@ -1282,8 +1492,7 @@ bool SvxFirstLineIndentItem::GetPresentation void SvxFirstLineIndentItem::ScaleMetrics(tools::Long const nMult, tools::Long const nDiv) { ASSERT_CHANGE_REFCOUNTED_ITEM; - m_dFirstLineOffset - = (m_dFirstLineOffset * static_cast<double>(nMult)) / static_cast<double>(nDiv); + m_stFirstLineOffset.ScaleMetrics(nMult, nDiv); } bool SvxFirstLineIndentItem::HasMetrics() const @@ -1295,9 +1504,12 @@ void SvxFirstLineIndentItem::dumpAsXml(xmlTextWriterPtr pWriter) const { (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxFirstLineIndentItem")); (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr())); - (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_dFirstLineOffset"), - BAD_CAST(OString::number(m_dFirstLineOffset).getStr())); - (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nUnit"), BAD_CAST(OString::number(m_nUnit).getStr())); + (void)xmlTextWriterWriteAttribute( + pWriter, BAD_CAST("m_dFirstLineOffset"), + BAD_CAST(OString::number(m_stFirstLineOffset.m_dValue).getStr())); + (void)xmlTextWriterWriteAttribute( + pWriter, BAD_CAST("m_nUnit"), + BAD_CAST(OString::number(m_stFirstLineOffset.m_nUnit).getStr())); (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nPropFirstLineOffset"), BAD_CAST(OString::number(m_nPropFirstLineOffset).getStr())); (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_bAutoFirst"), BAD_CAST(OString::number(int(m_bAutoFirst)).getStr())); (void)xmlTextWriterEndElement(pWriter); @@ -1307,36 +1519,7 @@ boost::property_tree::ptree SvxFirstLineIndentItem::dumpAsJSON() const { boost::property_tree::ptree aTree = SfxPoolItem::dumpAsJSON(); - boost::property_tree::ptree aState; - - switch (m_nUnit) - { - case css::util::MeasureUnit::TWIP: - { - MapUnit eTargetUnit = MapUnit::MapInch; - - OUString sFirstline - = GetMetricText(m_dFirstLineOffset, MapUnit::MapTwip, eTargetUnit, nullptr); - - aState.put("firstline", sFirstline); - aState.put("unit", "inch"); - } - break; - - case css::util::MeasureUnit::FONT_EM: - aState.put("firstline", m_dFirstLineOffset); - aState.put("unit", "em"); - break; - - case css::util::MeasureUnit::FONT_CJK_ADVANCE: - aState.put("firstline", m_dFirstLineOffset); - aState.put("unit", "ic"); - break; - - default: - SAL_WARN("editeng", "unhandled type conversion"); - break; - } + auto aState = lcl_IndentValueToJson("firstline", m_stFirstLineOffset); aTree.push_back(std::make_pair("state", aState)); @@ -1348,15 +1531,15 @@ SvxRightMarginItem::SvxRightMarginItem(const sal_uInt16 nId) { } -SvxRightMarginItem::SvxRightMarginItem(const tools::Long nRight, const sal_uInt16 nId) +SvxRightMarginItem::SvxRightMarginItem(SvxIndentValue stRight, const sal_uInt16 nId) : SfxPoolItem(nId, SfxItemType::SvxRightMarginItemType) - , m_nRightMargin(nRight) { + SetRight(stRight); } bool SvxRightMarginItem::QueryValue(uno::Any& rVal, sal_uInt8 nMemberId) const { - bool bRet = true; + bool bRet = false; bool bConvert = 0 != (nMemberId & CONVERT_TWIPS); nMemberId &= ~CONVERT_TWIPS; switch (nMemberId) @@ -1365,17 +1548,25 @@ bool SvxRightMarginItem::QueryValue(uno::Any& rVal, sal_uInt8 nMemberId) const case 0: { css::frame::status::LeftRightMarginScale aLRSpace; - aLRSpace.Right = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(m_nRightMargin) : m_nRightMargin); + + auto nRightTwips = ResolveRight({}); + aLRSpace.Right + = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nRightTwips) : nRightTwips); aLRSpace.ScaleRight = static_cast<sal_Int16>(m_nPropRightMargin); rVal <<= aLRSpace; + bRet = true; break; } case MID_R_MARGIN: - rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(m_nRightMargin) : m_nRightMargin); + bRet = lcl_FillAbsoluteMeasureAny(m_stRightMargin, rVal, bConvert); break; case MID_R_REL_MARGIN: rVal <<= static_cast<sal_Int16>(m_nPropRightMargin); - break; + bRet = true; + break; + case MID_R_UNIT_MARGIN: + bRet = lcl_FillRelativeMeasureAny(m_stRightMargin, rVal); + break; default: assert(false); bRet = false; @@ -1400,7 +1591,8 @@ bool SvxRightMarginItem::PutValue(const uno::Any& rVal, sal_uInt8 nMemberId) { return false; } - SetRight(bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal); + SetRight( + SvxIndentValue::twips(bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal)); break; } case MID_R_REL_MARGIN: @@ -1414,8 +1606,19 @@ bool SvxRightMarginItem::PutValue(const uno::Any& rVal, sal_uInt8 nMemberId) { return false; } + break; + } + case MID_R_UNIT_MARGIN: + { + css::beans::Pair<double, sal_Int16> stVal; + if (!(rVal >>= stVal)) + { + return false; + } + + SetRight(SvxIndentValue{ stVal.First, stVal.Second }); + break; } - break; default: assert(false); OSL_FAIL("unknown MemberId"); @@ -1430,14 +1633,14 @@ bool SvxRightMarginItem::operator==(const SfxPoolItem& rAttr) const const SvxRightMarginItem& rOther = static_cast<const SvxRightMarginItem&>(rAttr); - return (m_nRightMargin == rOther.GetRight() - && m_nPropRightMargin == rOther.GetPropRight()); + return std::tie(m_stRightMargin, m_nPropRightMargin) + == std::tie(rOther.m_stRightMargin, rOther.m_nPropRightMargin); } size_t SvxRightMarginItem::hashCode() const { std::size_t seed(0); - o3tl::hash_combine(seed, m_nRightMargin); + o3tl::hash_combine(seed, m_stRightMargin.hashCode()); o3tl::hash_combine(seed, m_nPropRightMargin); return seed; } @@ -1459,15 +1662,21 @@ bool SvxRightMarginItem::GetPresentation { case SfxItemPresentation::Nameless: { - if (100 != m_nRightMargin) + if (100 != m_nPropRightMargin) { - rText += unicode::formatPercent(m_nRightMargin, - Application::GetSettings().GetUILanguageTag()); + rText += unicode::formatPercent(m_nPropRightMargin, + Application::GetSettings().GetUILanguageTag()); + } + else if (m_stRightMargin.m_nUnit != css::util::MeasureUnit::TWIP) + { + OUStringBuffer stBuf; + sax::Converter::convertMeasureUnit(stBuf, m_stRightMargin.m_dValue, + m_stRightMargin.m_nUnit); + rText += stBuf.makeStringAndClear(); } else { - rText += GetMetricText(m_nRightMargin, - eCoreUnit, ePresUnit, &rIntl); + rText += GetMetricText(m_stRightMargin.m_dValue, eCoreUnit, ePresUnit, &rIntl); } return true; } @@ -1479,11 +1688,17 @@ bool SvxRightMarginItem::GetPresentation rText += unicode::formatPercent(m_nPropRightMargin, Application::GetSettings().GetUILanguageTag()); } + else if (m_stRightMargin.m_nUnit != css::util::MeasureUnit::TWIP) + { + OUStringBuffer stBuf; + sax::Converter::convertMeasureUnit(stBuf, m_stRightMargin.m_dValue, + m_stRightMargin.m_nUnit); + rText += stBuf.makeStringAndClear(); + } else { - rText += GetMetricText(m_nRightMargin, - eCoreUnit, ePresUnit, &rIntl) - + " " + EditResId(GetMetricId(ePresUnit)); + rText += GetMetricText(m_stRightMargin.m_dValue, eCoreUnit, ePresUnit, &rIntl) + " " + + EditResId(GetMetricId(ePresUnit)); } return true; } @@ -1495,7 +1710,7 @@ bool SvxRightMarginItem::GetPresentation void SvxRightMarginItem::ScaleMetrics(tools::Long const nMult, tools::Long const nDiv) { ASSERT_CHANGE_REFCOUNTED_ITEM; - m_nRightMargin = BigInt::Scale(m_nRightMargin, nMult, nDiv); + m_stRightMargin.ScaleMetrics(nMult, nDiv); } bool SvxRightMarginItem::HasMetrics() const @@ -1507,7 +1722,10 @@ void SvxRightMarginItem::dumpAsXml(xmlTextWriterPtr pWriter) const { (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxRightMarginItem")); (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr())); - (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nRightMargin"), BAD_CAST(OString::number(m_nRightMargin).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_dRightMargin"), + BAD_CAST(OString::number(m_stRightMargin.m_dValue).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nUnit"), + BAD_CAST(OString::number(m_stRightMargin.m_nUnit).getStr())); (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nPropRightMargin"), BAD_CAST(OString::number(m_nPropRightMargin).getStr())); (void)xmlTextWriterEndElement(pWriter); } @@ -1516,16 +1734,7 @@ boost::property_tree::ptree SvxRightMarginItem::dumpAsJSON() const { boost::property_tree::ptree aTree = SfxPoolItem::dumpAsJSON(); - boost::property_tree::ptree aState; - - MapUnit eTargetUnit = MapUnit::MapInch; - - OUString sRight = GetMetricText(GetRight(), - MapUnit::MapTwip, eTargetUnit, nullptr); - - aState.put("right", sRight); - aState.put("unit", "inch"); - + auto aState = lcl_IndentValueToJson("right", m_stRightMargin); aTree.push_back(std::make_pair("state", aState)); return aTree; @@ -1753,12 +1962,11 @@ bool SvxLRSpaceItem::operator==( const SfxPoolItem& rAttr ) const const SvxLRSpaceItem& rOther = static_cast<const SvxLRSpaceItem&>(rAttr); - return std::tie(m_dFirstLineOffset, m_nFirstLineUnit, m_nGutterMargin, m_nRightGutterMargin, - nLeftMargin, nRightMargin, nPropFirstLineOffset, nPropLeftMargin, - nPropRightMargin, bAutoFirst, bExplicitZeroMarginValRight, - bExplicitZeroMarginValLeft) - == std::tie(rOther.m_dFirstLineOffset, rOther.m_nFirstLineUnit, rOther.m_nGutterMargin, - rOther.m_nRightGutterMargin, rOther.nLeftMargin, rOther.nRightMargin, + return std::tie(m_stFirstLineOffset, m_nGutterMargin, m_nRightGutterMargin, m_stLeftMargin, + m_stRightMargin, nPropFirstLineOffset, nPropLeftMargin, nPropRightMargin, + bAutoFirst, bExplicitZeroMarginValRight, bExplicitZeroMarginValLeft) + == std::tie(rOther.m_stFirstLineOffset, rOther.m_nGutterMargin, + rOther.m_nRightGutterMargin, rOther.m_stLeftMargin, rOther.m_stRightMargin, rOther.nPropFirstLineOffset, rOther.nPropLeftMargin, rOther.nPropRightMargin, rOther.bAutoFirst, rOther.bExplicitZeroMarginValRight, rOther.bExplicitZeroMarginValLeft); @@ -1786,33 +1994,48 @@ bool SvxLRSpaceItem::GetPresentation rText = unicode::formatPercent(nPropLeftMargin, Application::GetSettings().GetUILanguageTag()); } + else if (m_stLeftMargin.m_nUnit != css::util::MeasureUnit::TWIP) + { + OUStringBuffer stBuf; + sax::Converter::convertMeasureUnit(stBuf, m_stLeftMargin.m_dValue, + m_stLeftMargin.m_nUnit); + rText += stBuf.makeStringAndClear(); + } else - rText = GetMetricText( nLeftMargin, - eCoreUnit, ePresUnit, &rIntl ); + rText = GetMetricText(static_cast<tools::Long>(m_stLeftMargin.m_dValue), eCoreUnit, + ePresUnit, &rIntl); rText += cpDelim; if ( 100 != nPropFirstLineOffset ) { rText += unicode::formatPercent(nPropFirstLineOffset, Application::GetSettings().GetUILanguageTag()); } - else if (m_nFirstLineUnit != css::util::MeasureUnit::TWIP) + else if (m_stFirstLineOffset.m_nUnit != css::util::MeasureUnit::TWIP) { OUStringBuffer stBuf; - sax::Converter::convertMeasureUnit(stBuf, m_dFirstLineOffset, m_nFirstLineUnit); + sax::Converter::convertMeasureUnit(stBuf, m_stFirstLineOffset.m_dValue, + m_stFirstLineOffset.m_nUnit); rText += stBuf.makeStringAndClear(); } else - rText += GetMetricText(static_cast<tools::Long>(m_dFirstLineOffset), eCoreUnit, - ePresUnit, &rIntl); + rText += GetMetricText(static_cast<tools::Long>(m_stFirstLineOffset.m_dValue), + eCoreUnit, ePresUnit, &rIntl); rText += cpDelim; - if ( 100 != nRightMargin ) + if (100 != nPropRightMargin) { - rText += unicode::formatPercent(nRightMargin, - Application::GetSettings().GetUILanguageTag()); + rText += unicode::formatPercent(nPropRightMargin, + Application::GetSettings().GetUILanguageTag()); + } + else if (m_stRightMargin.m_nUnit != css::util::MeasureUnit::TWIP) + { + OUStringBuffer stBuf; + sax::Converter::convertMeasureUnit(stBuf, m_stRightMargin.m_dValue, + m_stRightMargin.m_nUnit); + rText += stBuf.makeStringAndClear(); } else - rText += GetMetricText( nRightMargin, - eCoreUnit, ePresUnit, &rIntl ); + rText += GetMetricText(static_cast<tools::Long>(m_stRightMargin.m_dValue), + eCoreUnit, ePresUnit, &rIntl); return true; } case SfxItemPresentation::Complete: @@ -1821,41 +2044,59 @@ bool SvxLRSpaceItem::GetPresentation if ( 100 != nPropLeftMargin ) rText += unicode::formatPercent(nPropLeftMargin, Application::GetSettings().GetUILanguageTag()); + else if (m_stLeftMargin.m_nUnit != css::util::MeasureUnit::TWIP) + { + OUStringBuffer stBuf; + sax::Converter::convertMeasureUnit(stBuf, m_stLeftMargin.m_dValue, + m_stLeftMargin.m_nUnit); + rText += stBuf.makeStringAndClear(); + } else { - rText += GetMetricText( nLeftMargin, eCoreUnit, ePresUnit, &rIntl ) + - " " + EditResId(GetMetricId(ePresUnit)); + rText += GetMetricText(static_cast<tools::Long>(m_stLeftMargin.m_dValue), eCoreUnit, + ePresUnit, &rIntl) + + " " + EditResId(GetMetricId(ePresUnit)); } rText += cpDelim; - if (100 != nPropFirstLineOffset || m_dFirstLineOffset != 0.0) + if (100 != nPropFirstLineOffset || m_stFirstLineOffset.m_dValue != 0.0) { rText += EditResId(RID_SVXITEMS_LRSPACE_FLINE); if ( 100 != nPropFirstLineOffset ) rText += unicode::formatPercent(nPropFirstLineOffset, Application::GetSettings().GetUILanguageTag()); - else if (m_nFirstLineUnit != css::util::MeasureUnit::TWIP) + else if (m_stFirstLineOffset.m_nUnit != css::util::MeasureUnit::TWIP) { OUStringBuffer stBuf; - sax::Converter::convertMeasureUnit(stBuf, m_dFirstLineOffset, m_nFirstLineUnit); + sax::Converter::convertMeasureUnit(stBuf, m_stFirstLineOffset.m_dValue, + m_stFirstLineOffset.m_nUnit); rText += stBuf.makeStringAndClear(); } else { - rText += GetMetricText(static_cast<tools::Long>(m_dFirstLineOffset), eCoreUnit, - ePresUnit, &rIntl) + rText += GetMetricText(static_cast<tools::Long>(m_stFirstLineOffset.m_dValue), + eCoreUnit, ePresUnit, &rIntl) + " " + EditResId(GetMetricId(ePresUnit)); } rText += cpDelim; } rText += EditResId(RID_SVXITEMS_LRSPACE_RIGHT); - if ( 100 != nPropRightMargin ) + if (100 != nPropRightMargin) + { rText += unicode::formatPercent(nPropRightMargin, - Application::GetSettings().GetUILanguageTag()); + Application::GetSettings().GetUILanguageTag()); + } + else if (m_stRightMargin.m_nUnit != css::util::MeasureUnit::TWIP) + { + OUStringBuffer stBuf; + sax::Converter::convertMeasureUnit(stBuf, m_stRightMargin.m_dValue, + m_stRightMargin.m_nUnit); + rText += stBuf.makeStringAndClear(); + } else { - rText += GetMetricText( nRightMargin, - eCoreUnit, ePresUnit, &rIntl ) + - " " + EditResId(GetMetricId(ePresUnit)); + rText += GetMetricText(static_cast<tools::Long>(m_stRightMargin.m_dValue), + eCoreUnit, ePresUnit, &rIntl) + + " " + EditResId(GetMetricId(ePresUnit)); } return true; } @@ -1867,10 +2108,9 @@ bool SvxLRSpaceItem::GetPresentation void SvxLRSpaceItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv ) { - m_dFirstLineOffset - = (m_dFirstLineOffset * static_cast<double>(nMult)) / static_cast<double>(nDiv); - nLeftMargin = BigInt::Scale( nLeftMargin, nMult, nDiv ); - nRightMargin = BigInt::Scale( nRightMargin, nMult, nDiv ); + m_stFirstLineOffset.ScaleMetrics(nMult, nDiv); + m_stLeftMargin.ScaleMetrics(nMult, nDiv); + m_stRightMargin.ScaleMetrics(nMult, nDiv); } @@ -1884,12 +2124,20 @@ void SvxLRSpaceItem::dumpAsXml(xmlTextWriterPtr pWriter) const { (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxLRSpaceItem")); (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr())); - (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_dFirstLineOffset"), - BAD_CAST(OString::number(m_dFirstLineOffset).getStr())); - (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nFirstLineUnit"), - BAD_CAST(OString::number(m_nFirstLineUnit).getStr())); - (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLeftMargin"), BAD_CAST(OString::number(nLeftMargin).getStr())); - (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nRightMargin"), BAD_CAST(OString::number(nRightMargin).getStr())); + (void)xmlTextWriterWriteAttribute( + pWriter, BAD_CAST("m_dFirstLineOffset"), + BAD_CAST(OString::number(m_stFirstLineOffset.m_dValue).getStr())); + (void)xmlTextWriterWriteAttribute( + pWriter, BAD_CAST("m_nFirstLineUnit"), + BAD_CAST(OString::number(m_stFirstLineOffset.m_nUnit).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_dLeftMargin"), + BAD_CAST(OString::number(m_stLeftMargin.m_dValue).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nLeftMarginUnit"), + BAD_CAST(OString::number(m_stLeftMargin.m_nUnit).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_dRightMargin"), + BAD_CAST(OString::number(m_stRightMargin.m_dValue).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nRightMarginUnit"), + BAD_CAST(OString::number(m_stRightMargin.m_nUnit).getStr())); (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nGutterMargin"), BAD_CAST(OString::number(m_nGutterMargin).getStr())); (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nRightGutterMargin"), @@ -1912,11 +2160,9 @@ boost::property_tree::ptree SvxLRSpaceItem::dumpAsJSON() const MapUnit eTargetUnit = MapUnit::MapInch; - OUString sLeft = GetMetricText(GetLeft(), - MapUnit::MapTwip, eTargetUnit, nullptr); + OUString sLeft = GetMetricText(ResolveLeft({}), MapUnit::MapTwip, eTargetUnit, nullptr); - OUString sRight = GetMetricText(GetRight(), - MapUnit::MapTwip, eTargetUnit, nullptr); + OUString sRight = GetMetricText(ResolveRight({}), MapUnit::MapTwip, eTargetUnit, nullptr); OUString sFirstline = GetMetricText(ResolveTextFirstLineOffset({}), MapUnit::MapTwip, eTargetUnit, nullptr); diff --git a/editeng/source/outliner/outliner.cxx b/editeng/source/outliner/outliner.cxx index e23ee74ff09f..4ff4c5a46751 100644 --- a/editeng/source/outliner/outliner.cxx +++ b/editeng/source/outliner/outliner.cxx @@ -1492,7 +1492,7 @@ tools::Rectangle Outliner::ImpCalcBulletArea( sal_Int32 nPara, bool bAdjust, boo const auto nSpaceBefore = pFmt->GetAbsLSpace() + pFmt->GetFirstLineOffset(); const SvxLRSpaceItem& rLR = pEditEngine->GetParaAttrib( nPara, bOutlineMode ? EE_PARA_OUTLLRSPACE : EE_PARA_LRSPACE ); - aTopLeft.setX(rLR.GetTextLeft() + rLR.ResolveTextFirstLineOffset({}) + nSpaceBefore); + aTopLeft.setX(rLR.ResolveTextLeft({}) + rLR.ResolveTextFirstLineOffset({}) + nSpaceBefore); tools::Long nBulletWidth = std::max( static_cast<tools::Long>(-rLR.ResolveTextFirstLineOffset({})), diff --git a/editeng/source/rtf/rtfitem.cxx b/editeng/source/rtf/rtfitem.cxx index 129e43ebc33c..17aafa8a558e 100644 --- a/editeng/source/rtf/rtfitem.cxx +++ b/editeng/source/rtf/rtfitem.cxx @@ -342,7 +342,7 @@ void SvxRTFParser::ReadAttr( int nToken, SfxItemSet* pSet ) CalcValue(); nSz = sal_uInt16(nTokenValue); } - aLR.SetTextLeft( nSz ); + aLR.SetTextLeft(SvxIndentValue::twips(nSz)); pSet->Put( aLR ); } break; @@ -359,7 +359,7 @@ void SvxRTFParser::ReadAttr( int nToken, SfxItemSet* pSet ) CalcValue(); nSz = sal_uInt16(nTokenValue); } - aLR.SetRight( nSz ); + aLR.SetRight(SvxIndentValue::twips(nSz)); pSet->Put( aLR ); } break; diff --git a/filter/source/msfilter/svdfppt.cxx b/filter/source/msfilter/svdfppt.cxx index d4bcc197d2e2..8ec7567edb37 100644 --- a/filter/source/msfilter/svdfppt.cxx +++ b/filter/source/msfilter/svdfppt.cxx @@ -6187,7 +6187,7 @@ void PPTParagraphObj::ApplyTo( SfxItemSet& rSet, std::optional< sal_Int16 >& rS auto const nAbsLSpace = convertMasterUnitToMm100(_nTextOfs); auto const nFirstLineOffset = nAbsLSpace - convertMasterUnitToMm100(_nBulletOfs); aLRSpaceItem.SetTextFirstLineOffset(SvxIndentValue::twips(-nFirstLineOffset)); - aLRSpaceItem.SetTextLeft( nAbsLSpace ); + aLRSpaceItem.SetTextLeft(SvxIndentValue::twips(nAbsLSpace)); } rSet.Put( aLRSpaceItem ); diff --git a/include/editeng/lrspitem.hxx b/include/editeng/lrspitem.hxx index c47f9a8f29cf..f5b4d1054056 100644 --- a/include/editeng/lrspitem.hxx +++ b/include/editeng/lrspitem.hxx @@ -79,6 +79,16 @@ struct SvxIndentValue static SvxIndentValue twips(double dValue) { return { dValue, css::util::MeasureUnit::TWIP }; } static SvxIndentValue zero() { return twips(0.0); } + + double ResolveDouble(const SvxFontUnitMetrics& rMetrics) const; + sal_Int32 Resolve(const SvxFontUnitMetrics& rMetrics) const; + sal_Int32 ResolveFixedPart() const; + sal_Int32 ResolveVariablePart(const SvxFontUnitMetrics& rMetrics) const; + + void ScaleMetrics(tools::Long nMult, tools::Long nDiv); + + size_t hashCode() const; + bool operator==(SvxIndentValue const&) const = default; }; /// GetLeft() - for everything that's not applied to a paragraph @@ -127,22 +137,24 @@ class EDITENG_DLLPUBLIC SvxTextLeftMarginItem final : public SfxPoolItem private: friend class SvxFirstLineIndentItem; /// left margin including negative first-line indent - tools::Long m_nTextLeftMargin = 0; + SvxIndentValue m_stTextLeftMargin = SvxIndentValue::zero(); sal_uInt16 m_nPropLeftMargin = 100; public: - //TODO: need this? - //void SetLeft(SvxFirstLineIndentItem const& rFirstLine, const tools::Long nL, const sal_uInt16 nProp = 100); /// get left margin without negative first-line indent - tools::Long GetLeft(const SvxFirstLineIndentItem& rFirstLine, - const SvxFontUnitMetrics& rMetrics) const; - sal_uInt16 GetPropLeft() const { return m_nPropLeftMargin; } + sal_Int32 ResolveLeft(const SvxFirstLineIndentItem& rFirstLine, + const SvxFontUnitMetrics& rMetrics) const; + sal_Int32 ResolveLeftFixedPart(const SvxFirstLineIndentItem& rFirstLine) const; + sal_Int32 ResolveLeftVariablePart(const SvxFirstLineIndentItem& rFirstLine, + const SvxFontUnitMetrics& rMetrics) const; + sal_uInt16 GetPropLeft() const; - void SetTextLeft(const tools::Long nL, const sal_uInt16 nProp = 100); - tools::Long GetTextLeft() const; + void SetTextLeft(SvxIndentValue stL, const sal_uInt16 nProp = 100); + sal_Int32 ResolveTextLeft(const SvxFontUnitMetrics& rMetrics) const; + SvxIndentValue GetTextLeft() const; explicit SvxTextLeftMarginItem(const sal_uInt16 nId); - SvxTextLeftMarginItem(const tools::Long nLeft, const sal_uInt16 nId); + SvxTextLeftMarginItem(SvxIndentValue stLeft, const sal_uInt16 nId); SvxTextLeftMarginItem(SvxTextLeftMarginItem const &) = default; // SfxPoolItem copy function dichotomy // "pure virtual Methods" from SfxPoolItem @@ -171,8 +183,7 @@ class EDITENG_DLLPUBLIC SvxFirstLineIndentItem final : public SfxPoolItem { private: /// First-line indent always relative to GetTextLeft() - double m_dFirstLineOffset = 0.0; - sal_Int16 m_nUnit = css::util::MeasureUnit::TWIP; + SvxIndentValue m_stFirstLineOffset = SvxIndentValue::zero(); sal_uInt16 m_nPropFirstLineOffset = 100; /// Automatic calculation of the first line indent bool m_bAutoFirst = false; @@ -186,9 +197,6 @@ public: void SetTextFirstLineOffset(SvxIndentValue stValue, sal_uInt16 nProp = 100); SvxIndentValue GetTextFirstLineOffset() const; - double GetTextFirstLineOffsetValue() const; - sal_Int16 GetTextFirstLineOffsetUnit() const; - double ResolveTextFirstLineOffsetDouble(const SvxFontUnitMetrics& rMetrics) const; sal_Int32 ResolveTextFirstLineOffset(const SvxFontUnitMetrics& rMetrics) const; explicit SvxFirstLineIndentItem(const sal_uInt16 nId); @@ -220,20 +228,23 @@ class EDITENG_DLLPUBLIC SvxRightMarginItem final : public SfxPoolItem { private: /// right margin: nothing special - tools::Long m_nRightMargin = 0; + SvxIndentValue m_stRightMargin = SvxIndentValue::zero(); sal_uInt16 m_nPropRightMargin = 100; public: // The "layout interface": - void SetRight(const tools::Long nR, const sal_uInt16 nProp = 100); + void SetRight(SvxIndentValue stR, const sal_uInt16 nProp = 100); // Query/direct setting of the absolute values - tools::Long GetRight() const { return m_nRightMargin;} + SvxIndentValue GetRight() const; + sal_Int32 ResolveRight(const SvxFontUnitMetrics& rMetrics) const; + sal_Int32 ResolveRightFixedPart() const; + sal_Int32 ResolveRightVariablePart(const SvxFontUnitMetrics& rMetrics) const; - sal_uInt16 GetPropRight() const { return m_nPropRightMargin; } + sal_uInt16 GetPropRight() const; explicit SvxRightMarginItem(const sal_uInt16 nId); - SvxRightMarginItem(const tools::Long nRight, const sal_uInt16 nId); + SvxRightMarginItem(SvxIndentValue stRight, const sal_uInt16 nId); SvxRightMarginItem(SvxRightMarginItem const &) = default; // SfxPoolItem copy function dichotomy // "pure virtual Methods" from SfxPoolItem @@ -325,10 +336,10 @@ public: class EDITENG_DLLPUBLIC SvxLRSpaceItem final : public SfxPoolItem { /// First-line indent always relative to GetTextLeft() - double m_dFirstLineOffset = 0.0; - sal_Int16 m_nFirstLineUnit = css::util::MeasureUnit::TWIP; - tools::Long nLeftMargin; // nLeft or the negative first-line indent - tools::Long nRightMargin; // The unproblematic right edge + SvxIndentValue m_stFirstLineOffset = SvxIndentValue::zero(); + SvxIndentValue m_stLeftMargin + = SvxIndentValue::zero(); // nLeft or the negative first-line indent + SvxIndentValue m_stRightMargin = SvxIndentValue::zero(); /// The amount of extra space added to the left margin. tools::Long m_nGutterMargin; /// The amount of extra space added to the right margin, on mirrored pages. @@ -344,7 +355,7 @@ public: static SfxPoolItem* CreateDefault(); explicit SvxLRSpaceItem( const sal_uInt16 nId ); - SvxLRSpaceItem(const tools::Long nLeft, const tools::Long nRight, SvxIndentValue stValue, + SvxLRSpaceItem(SvxIndentValue stLeft, SvxIndentValue stRight, SvxIndentValue stValue, const sal_uInt16 nId); SvxLRSpaceItem(SvxLRSpaceItem const &) = default; // SfxPoolItem copy function dichotomy @@ -364,18 +375,14 @@ public: virtual bool HasMetrics() const override; // The "layout interface": - void SetLeft (const tools::Long nL, const sal_uInt16 nProp = 100); - void SetRight(const tools::Long nR, const sal_uInt16 nProp = 100); + void SetLeft(SvxIndentValue stL, const sal_uInt16 nProp = 100); + void SetRight(SvxIndentValue stR, const sal_uInt16 nProp = 100); // Query/direct setting of the absolute values - tools::Long GetLeft() const { return nLeftMargin; } - tools::Long GetRight() const { return nRightMargin;} - void SetLeftValue(const tools::Long nL) - { - assert(m_dFirstLineOffset == 0.0); - nLeftMargin = nL; - } - void SetRightValue( const tools::Long nR ) { nRightMargin = nR; } + SvxIndentValue GetLeft() const; + sal_Int32 ResolveLeft(const SvxFontUnitMetrics& rMetrics) const; + SvxIndentValue GetRight() const; + sal_Int32 ResolveRight(const SvxFontUnitMetrics& rMetrics) const; bool IsAutoFirst() const { return bAutoFirst; } void SetAutoFirst( const bool bNew ) { bAutoFirst = bNew; } @@ -387,14 +394,12 @@ public: sal_uInt16 GetPropRight() const { return nPropRightMargin;} // The UI/text interface: - void SetTextLeft(const tools::Long nL, const sal_uInt16 nProp = 100); - tools::Long GetTextLeft() const; + void SetTextLeft(SvxIndentValue stL, const sal_uInt16 nProp = 100); + SvxIndentValue GetTextLeft() const; + sal_Int32 ResolveTextLeft(const SvxFontUnitMetrics& rMetrics) const; void SetTextFirstLineOffset(SvxIndentValue stValue, sal_uInt16 nProp = 100); SvxIndentValue GetTextFirstLineOffset() const; - double GetTextFirstLineOffsetValue() const; - sal_Int16 GetTextFirstLineOffsetUnit() const; - double ResolveTextFirstLineOffsetDouble(const SvxFontUnitMetrics& rMetrics) const; sal_Int32 ResolveTextFirstLineOffset(const SvxFontUnitMetrics& rMetrics) const; void SetPropTextFirstLineOffset( const sal_uInt16 nProp ) diff --git a/include/editeng/memberids.h b/include/editeng/memberids.h index 195eccce41c8..82a1fe65e9bf 100644 --- a/include/editeng/memberids.h +++ b/include/editeng/memberids.h @@ -139,6 +139,8 @@ #define MID_TXT_LMARGIN 11 #define MID_GUTTER_MARGIN 12 #define MID_FIRST_LINE_UNIT_INDENT 13 +#define MID_R_UNIT_MARGIN 14 +#define MID_L_UNIT_MARGIN 15 //ProtectItem #define MID_PROTECT_CONTENT 0 diff --git a/include/editeng/unoprnms.hxx b/include/editeng/unoprnms.hxx index 0ba35cbee24a..b42c03bca762 100644 --- a/include/editeng/unoprnms.hxx +++ b/include/editeng/unoprnms.hxx @@ -295,8 +295,10 @@ inline constexpr OUString UNO_NAME_EDIT_PARA_ADJUST = u"ParaAdjust"_ustr; inline constexpr OUString UNO_NAME_EDIT_PARA_BMARGIN = u"ParaBottomMargin"_ustr; inline constexpr OUString UNO_NAME_EDIT_PARA_LASTLINEADJ = u"ParaLastLineAdjust"_ustr; inline constexpr OUString UNO_NAME_EDIT_PARA_LMARGIN = u"ParaLeftMargin"_ustr; +inline constexpr OUString UNO_NAME_EDIT_PARA_LMARGIN_UNIT = u"ParaLeftMarginUnit"_ustr; inline constexpr OUString UNO_NAME_EDIT_PARA_LINESPACING = u"ParaLineSpacing"_ustr; inline constexpr OUString UNO_NAME_EDIT_PARA_RMARGIN = u"ParaRightMargin"_ustr; +inline constexpr OUString UNO_NAME_EDIT_PARA_RMARGIN_UNIT = u"ParaRightMarginUnit"_ustr; inline constexpr OUString UNO_NAME_EDIT_PARA_TABSTOPS = u"ParaTabStops"_ustr; inline constexpr OUString UNO_NAME_EDIT_PARA_TABSTOP_DEFAULT_DISTANCE = u"ParaTabStopDefaultDistance"_ustr; inline constexpr OUString UNO_NAME_EDIT_PARA_TMARGIN = u"ParaTopMargin"_ustr; diff --git a/include/editeng/unotext.hxx b/include/editeng/unotext.hxx index 4011fac9d479..168b9ce063ee 100644 --- a/include/editeng/unotext.hxx +++ b/include/editeng/unotext.hxx @@ -148,8 +148,10 @@ struct SfxItemPropertyMapEntry; {u"ParaHyphenationNoLastWord"_ustr, EE_PARA_HYPHENATE_NO_LAST_WORD, ::cppu::UnoType<bool>::get(), 0, 0 }, \ { UNO_NAME_EDIT_PARA_LASTLINEADJ, EE_PARA_JUST, ::cppu::UnoType<sal_Int16>::get(), 0, MID_LAST_LINE_ADJUST }, \ { UNO_NAME_EDIT_PARA_LMARGIN, EE_PARA_LRSPACE, ::cppu::UnoType<sal_Int32>::get(), 0, MID_TXT_LMARGIN, PropertyMoreFlags::METRIC_ITEM }, \ + { UNO_NAME_EDIT_PARA_LMARGIN_UNIT, EE_PARA_LRSPACE, ::cppu::UnoType<css::beans::Pair<double, sal_Int16>>::get(), 0, MID_L_UNIT_MARGIN }, \ { UNO_NAME_EDIT_PARA_LINESPACING, EE_PARA_SBL, cppu::UnoType<css::style::LineSpacing>::get(), 0, CONVERT_TWIPS}, \ { UNO_NAME_EDIT_PARA_RMARGIN, EE_PARA_LRSPACE, ::cppu::UnoType<sal_Int32>::get(), 0, MID_R_MARGIN, PropertyMoreFlags::METRIC_ITEM }, \ + { UNO_NAME_EDIT_PARA_RMARGIN_UNIT, EE_PARA_LRSPACE, ::cppu::UnoType<css::beans::Pair<double, sal_Int16>>::get(), 0, MID_R_UNIT_MARGIN }, \ { UNO_NAME_EDIT_PARA_TABSTOPS, EE_PARA_TABS, cppu::UnoType<css::uno::Sequence< css::style::TabStop >>::get(), 0, 0 }, \ { UNO_NAME_EDIT_PARA_TABSTOP_DEFAULT_DISTANCE, EE_PARA_TABS, ::cppu::UnoType<sal_Int32>::get(), 0, MID_TABSTOP_DEFAULT_DISTANCE }, \ { UNO_NAME_EDIT_PARA_TMARGIN, EE_PARA_ULSPACE, ::cppu::UnoType<sal_Int32>::get(), 0, MID_UP_MARGIN, PropertyMoreFlags::METRIC_ITEM },\ diff --git a/reportdesign/source/ui/report/ReportController.cxx b/reportdesign/source/ui/report/ReportController.cxx index 41914a33ca7a..149b43d5efe2 100644 --- a/reportdesign/source/ui/report/ReportController.cxx +++ b/reportdesign/source/ui/report/ReportController.cxx @@ -2415,10 +2415,11 @@ void OReportController::openPageDialog(const uno::Reference<report::XSection>& _ { aDescriptor.Put(SvxSizeItem(RPTUI_ID_SIZE, VCLUnoHelper::ConvertToVCLSize(getStyleProperty<awt::Size>(m_xReportDefinition,PROPERTY_PAPERSIZE)))); - aDescriptor.Put(SvxLRSpaceItem( - getStyleProperty<sal_Int32>(m_xReportDefinition, PROPERTY_LEFTMARGIN), - getStyleProperty<sal_Int32>(m_xReportDefinition, PROPERTY_RIGHTMARGIN), - SvxIndentValue::zero(), RPTUI_ID_LRSPACE)); + aDescriptor.Put(SvxLRSpaceItem(SvxIndentValue::twips(getStyleProperty<sal_Int32>( + m_xReportDefinition, PROPERTY_LEFTMARGIN)), + SvxIndentValue::twips(getStyleProperty<sal_Int32>( + m_xReportDefinition, PROPERTY_RIGHTMARGIN)), + SvxIndentValue::zero(), RPTUI_ID_LRSPACE)); aDescriptor.Put(SvxULSpaceItem(static_cast<sal_uInt16>(getStyleProperty<sal_Int32>(m_xReportDefinition,PROPERTY_TOPMARGIN)) -e ... etc. - the rest is truncated
