diff options
33 files changed, 486 insertions, 6 deletions
diff --git a/cui/Library_cui.mk b/cui/Library_cui.mk index d6fa68e0d194..6fdf446f97e9 100644 --- a/cui/Library_cui.mk +++ b/cui/Library_cui.mk @@ -215,6 +215,7 @@ $(eval $(call gb_Library_add_exception_objects,cui,\ cui/source/tabpages/tabstpge \ cui/source/tabpages/textanim \ cui/source/tabpages/textattr \ + cui/source/tabpages/TextColumnsPage \ cui/source/tabpages/tparea \ cui/source/tabpages/tpbitmap \ cui/source/tabpages/tpcolor \ diff --git a/cui/UIConfig_cui.mk b/cui/UIConfig_cui.mk index ff3c718b21d6..c6d9d1584a66 100644 --- a/cui/UIConfig_cui.mk +++ b/cui/UIConfig_cui.mk @@ -206,6 +206,7 @@ $(eval $(call gb_UIConfig_add_uifiles,cui,\ cui/uiconfig/ui/swpossizepage \ cui/uiconfig/ui/textattrtabpage \ cui/uiconfig/ui/textanimtabpage \ + cui/uiconfig/ui/textcolumnstabpage \ cui/uiconfig/ui/textdialog \ cui/uiconfig/ui/textflowpage \ cui/uiconfig/ui/thesaurus \ diff --git a/cui/source/factory/dlgfact.cxx b/cui/source/factory/dlgfact.cxx index ebfd9bfb0ea5..19b30518e426 100644 --- a/cui/source/factory/dlgfact.cxx +++ b/cui/source/factory/dlgfact.cxx @@ -91,6 +91,7 @@ #include <toolbarmodedlg.hxx> #include <DiagramDialog.hxx> #include <fileextcheckdlg.hxx> +#include <TextColumnsPage.hxx> using namespace ::com::sun::star; using namespace ::com::sun::star::frame; @@ -1499,6 +1500,8 @@ CreateTabPage AbstractDialogFactory_Impl::GetTabPageCreatorFunc( sal_uInt16 nId return SvxGrfCropPage::Create; case RID_SVXPAGE_MACROASSIGN : return SfxMacroTabPage::Create; + case RID_SVXPAGE_TEXTCOLUMNS: + return SvxTextColumnsPage::Create; default: break; } @@ -1562,6 +1565,8 @@ GetTabPageRanges AbstractDialogFactory_Impl::GetTabPageRangesFunc( sal_uInt16 nI return SvxPageDescPage::GetRanges; case RID_SVXPAGE_ASIAN_LAYOUT: return SvxAsianLayoutPage::GetRanges; + case RID_SVXPAGE_TEXTCOLUMNS: + return SvxTextColumnsPage::GetRanges; default: break; } diff --git a/cui/source/inc/TextColumnsPage.hxx b/cui/source/inc/TextColumnsPage.hxx new file mode 100644 index 000000000000..6153cd27a520 --- /dev/null +++ b/cui/source/inc/TextColumnsPage.hxx @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <sal/config.h> + +#include <sfx2/tabdlg.hxx> + +#include <memory> + +/// Tab page for EditEngine columns properties +class SvxTextColumnsPage : public SfxTabPage +{ +private: + static const sal_uInt16 pRanges[]; + + std::unique_ptr<weld::SpinButton> m_xColumnsNumber; + std::unique_ptr<weld::MetricSpinButton> m_xColumnsSpacing; + +public: + SvxTextColumnsPage(weld::Container* pPage, weld::DialogController* pController, + const SfxItemSet& rInAttrs); + virtual ~SvxTextColumnsPage() override; + + static std::unique_ptr<SfxTabPage> + Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet*); + static const sal_uInt16* GetRanges() { return pRanges; } + + virtual bool FillItemSet(SfxItemSet*) override; + virtual void Reset(const SfxItemSet*) override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/cui/source/tabpages/TextColumnsPage.cxx b/cui/source/tabpages/TextColumnsPage.cxx new file mode 100644 index 000000000000..db83722e6be1 --- /dev/null +++ b/cui/source/tabpages/TextColumnsPage.cxx @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <sal/config.h> + +#include <svtools/unitconv.hxx> +#include <svx/dlgutil.hxx> +#include <svx/sdmetitm.hxx> +#include <svx/svddef.hxx> + +#include <TextColumnsPage.hxx> + +const sal_uInt16 SvxTextColumnsPage::pRanges[] + = { SDRATTR_TEXTCOLUMNS_FIRST, SDRATTR_TEXTCOLUMNS_LAST, 0 }; + +SvxTextColumnsPage::SvxTextColumnsPage(weld::Container* pPage, weld::DialogController* pController, + const SfxItemSet& rInAttrs) + : SfxTabPage(pPage, pController, "cui/ui/textcolumnstabpage.ui", "TextColumnsPage", &rInAttrs) + , m_xColumnsNumber(m_xBuilder->weld_spin_button("FLD_COL_NUMBER")) + , m_xColumnsSpacing( + m_xBuilder->weld_metric_spin_button("MTR_FLD_COL_SPACING", GetModuleFieldUnit(rInAttrs))) +{ +} + +SvxTextColumnsPage::~SvxTextColumnsPage() = default; + +// read the passed item set +void SvxTextColumnsPage::Reset(const SfxItemSet* rAttrs) +{ + SfxItemPool* pPool = rAttrs->GetPool(); + assert(pPool); + + { + auto pItem = GetItem(*rAttrs, SDRATTR_TEXTCOLUMNS_NUMBER); + if (!pItem) + pItem = &pPool->GetDefaultItem(SDRATTR_TEXTCOLUMNS_NUMBER); + m_xColumnsNumber->set_value(pItem->GetValue()); + m_xColumnsNumber->save_value(); + } + + { + MapUnit eUnit = pPool->GetMetric(SDRATTR_TEXTCOLUMNS_SPACING); + auto pItem = GetItem(*rAttrs, SDRATTR_TEXTCOLUMNS_SPACING); + if (!pItem) + pItem = &pPool->GetDefaultItem(SDRATTR_TEXTCOLUMNS_SPACING); + SetMetricValue(*m_xColumnsSpacing, pItem->GetValue(), eUnit); + m_xColumnsSpacing->save_value(); + } +} + +// fill the passed item set with dialog box attributes +bool SvxTextColumnsPage::FillItemSet(SfxItemSet* rAttrs) +{ + if (m_xColumnsNumber->get_value_changed_from_saved()) + rAttrs->Put(SfxInt16Item(SDRATTR_TEXTCOLUMNS_NUMBER, m_xColumnsNumber->get_value())); + + if (m_xColumnsSpacing->get_value_changed_from_saved()) + { + SfxItemPool* pPool = rAttrs->GetPool(); + assert(pPool); + MapUnit eUnit = pPool->GetMetric(SDRATTR_TEXTCOLUMNS_SPACING); + sal_Int32 nValue = GetCoreValue(*m_xColumnsSpacing, eUnit); + rAttrs->Put(SdrMetricItem(SDRATTR_TEXTCOLUMNS_SPACING, nValue)); + } + + return true; +} + +std::unique_ptr<SfxTabPage> SvxTextColumnsPage::Create(weld::Container* pPage, + weld::DialogController* pController, + const SfxItemSet* rAttrs) +{ + return std::make_unique<SvxTextColumnsPage>(pPage, pController, *rAttrs); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/cui/source/tabpages/textanim.cxx b/cui/source/tabpages/textanim.cxx index 71a5d185a3dc..43b69d77afd6 100644 --- a/cui/source/tabpages/textanim.cxx +++ b/cui/source/tabpages/textanim.cxx @@ -19,6 +19,7 @@ #include <textanim.hxx> #include <textattr.hxx> +#include <TextColumnsPage.hxx> #include <svx/dlgutil.hxx> #include <svx/svdmark.hxx> #include <svx/svdview.hxx> @@ -47,6 +48,7 @@ SvxTextTabDialog::SvxTextTabDialog(weld::Window* pParent, const SfxItemSet* pAtt { AddTabPage("RID_SVXPAGE_TEXTATTR", SvxTextAttrPage::Create, nullptr); AddTabPage("RID_SVXPAGE_TEXTANIMATION", SvxTextAnimationPage::Create, nullptr); + AddTabPage("RID_SVXPAGE_TEXTCOLUMNS", SvxTextColumnsPage::Create, nullptr); } /************************************************************************* diff --git a/cui/uiconfig/ui/textcolumnstabpage.ui b/cui/uiconfig/ui/textcolumnstabpage.ui new file mode 100644 index 000000000000..596b155dbe1b --- /dev/null +++ b/cui/uiconfig/ui/textcolumnstabpage.ui @@ -0,0 +1,111 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.38.2 --> +<interface domain="cui"> + <requires lib="gtk+" version="3.20"/> + <object class="GtkAdjustment" id="adjustmentColNumber"> + <property name="lower">1</property> + <property name="upper">16</property><!-- MSO has an upper limit of 16 in UI --> + <property name="step-increment">1</property> + <property name="page-increment">10</property> + </object> + <object class="GtkAdjustment" id="adjustmentColSpacing"> + <property name="lower">0</property> + <property name="upper">2147483647</property> + <property name="step-increment">1</property> + <property name="page-increment">10</property> + </object> + <object class="GtkBox" id="TextColumnsPage"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="border-width">6</property> + <property name="orientation">vertical</property> + <property name="spacing">12</property> + <child> + <!-- n-columns=2 n-rows=2 --> + <object class="GtkGrid" id="grid1"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="margin-start">12</property> + <property name="margin-top">6</property> + <property name="row-spacing">6</property> + <property name="column-spacing">12</property> + <child> + <object class="GtkLabel" id="labelColNumber"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="textcolumnstabpage|labelColNumber">_Number of columns:</property> + <property name="use-underline">True</property> + <property name="mnemonic-widget">FLD_COL_NUMBER</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="labelColSpacing"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="textcolumnstabpage|labelColSpacing">_Spacing:</property> + <property name="use-underline">True</property> + <property name="mnemonic-widget">MTR_FLD_COL_SPACING</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">1</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="FLD_COL_NUMBER"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="activates-default">True</property> + <property name="truncate-multiline">True</property> + <property name="adjustment">adjustmentColNumber</property> + <property name="value">1</property> + <child internal-child="accessible"> + <object class="AtkObject" id="FLD_COL_NUMBER-atkobject"> + <property name="AtkObject::accessible-description" translatable="yes" context="textcolumnstabpage|extended_tip|FLD_COL_NUMBER">Enter the number of columns to use for the text.</property> + </object> + </child> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">0</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="MTR_FLD_COL_SPACING"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="activates-default">True</property> + <property name="truncate-multiline">True</property> + <property name="adjustment">adjustmentColSpacing</property> + <property name="digits">2</property> + <child internal-child="accessible"> + <object class="AtkObject" id="MTR_FLD_COL_SPACING-atkobject"> + <property name="AtkObject::accessible-description" translatable="yes" context="textcolumnstabpage|extended_tip|MTR_FLD_COL_SPACING">Enter the amount of space to leave between the columns.</property> + </object> + </child> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child internal-child="accessible"> + <object class="AtkObject" id="TextColumnsPage-atkobject"> + <property name="AtkObject::accessible-description" translatable="yes" context="textcolumnstabpage|extended_tip|TextColumnsPage">Sets the columns layout properties for text in the selected drawing or text object.</property> + </object> + </child> + </object> +</interface> diff --git a/cui/uiconfig/ui/textdialog.ui b/cui/uiconfig/ui/textdialog.ui index c3981d1cc46d..6cde38354a2a 100644 --- a/cui/uiconfig/ui/textdialog.ui +++ b/cui/uiconfig/ui/textdialog.ui @@ -187,6 +187,54 @@ <property name="tab_fill">False</property> </packing> </child> + <child> + <!-- n-columns=1 n-rows=1 --> + <object class="GtkGrid"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + </object> + <packing> + <property name="position">2</property> + </packing> + </child> + <child type="tab"> + <object class="GtkLabel" id="RID_SVXPAGE_TEXTCOLUMNS"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes" context="textdialog|RID_SVXPAGE_TEXTCOLUMNS">Text Columns</property> + </object> + <packing> + <property name="position">2</property> + <property name="tab_fill">False</property> + </packing> + </child> </object> <packing> <property name="expand">False</property> diff --git a/editeng/source/editeng/editeng.cxx b/editeng/source/editeng/editeng.cxx index 7000403ff2b4..cb1244f2e30f 100644 --- a/editeng/source/editeng/editeng.cxx +++ b/editeng/source/editeng/editeng.cxx @@ -452,6 +452,11 @@ bool EditEngine::GetDirectVertical() const return pImpEditEngine->GetDirectVertical(); } +void EditEngine::SetTextColumns(sal_Int16 nColumns, sal_Int32 nSpacing) +{ + pImpEditEngine->SetTextColumns(nColumns, nSpacing); +} + void EditEngine::SetFixedCellHeight( bool bUseFixedCellHeight ) { pImpEditEngine->SetFixedCellHeight( bUseFixedCellHeight ); diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx index a105716f8791..394165930379 100644 --- a/editeng/source/editeng/impedit.hxx +++ b/editeng/source/editeng/impedit.hxx @@ -561,6 +561,9 @@ private: sal_Int32 mnOverflowingLine = -1; bool mbNeedsChainingHandling = false; + sal_Int16 mnColumns = 1; + sal_Int32 mnColumnSpacing = 0; + // If it is detected at one point that the StatusHdl has to be called, but // this should not happen immediately (critical section): Timer aStatusTimer; @@ -817,6 +820,8 @@ public: void SetRotation( TextRotation nRotation); TextRotation GetRotation() const { return GetEditDoc().GetRotation(); } + void SetTextColumns(sal_Int16 nColumns, sal_Int32 nSpacing); + bool IsPageOverflow( ) const; void SetFixedCellHeight( bool bUseFixedCellHeight ); diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx index fff957f46f14..6a14cda16f92 100644 --- a/editeng/source/editeng/impedit3.cxx +++ b/editeng/source/editeng/impedit3.cxx @@ -2635,6 +2635,20 @@ void ImpEditEngine::SetRotation(TextRotation nRotation) } } +void ImpEditEngine::SetTextColumns(sal_Int16 nColumns, sal_Int32 nSpacing) +{ + if (mnColumns != nColumns || mnColumnSpacing != nSpacing) + { + mnColumns = nColumns; + mnColumnSpacing = nSpacing; + if (IsFormatted()) + { + FormatFullDoc(); + UpdateViews(GetActiveView()); + } + } +} + void ImpEditEngine::SetFixedCellHeight( bool bUseFixedCellHeight ) { if ( IsFixedCellHeight() != bUseFixedCellHeight ) diff --git a/editeng/source/outliner/outlin2.cxx b/editeng/source/outliner/outlin2.cxx index 1acab5ba4d48..a0ea00d555f6 100644 --- a/editeng/source/outliner/outlin2.cxx +++ b/editeng/source/outliner/outlin2.cxx @@ -532,6 +532,11 @@ bool Outliner::IsTopToBottom() const return pEditEngine->IsTopToBottom(); } +void Outliner::SetTextColumns(sal_Int16 nColumns, sal_Int32 nSpacing) +{ + pEditEngine->SetTextColumns(nColumns, nSpacing); +} + void Outliner::SetFixedCellHeight( bool bUseFixedCellHeight ) { pEditEngine->SetFixedCellHeight( bUseFixedCellHeight ); diff --git a/include/editeng/editeng.hxx b/include/editeng/editeng.hxx index be5262a41d23..73a89992f62b 100644 --- a/include/editeng/editeng.hxx +++ b/include/editeng/editeng.hxx @@ -242,6 +242,8 @@ public: void SetRotation(TextRotation nRotation); TextRotation GetRotation() const; + void SetTextColumns(sal_Int16 nColumns, sal_Int32 nSpacing); + void SetFixedCellHeight( bool bUseFixedCellHeight ); void SetDefaultHorizontalTextDirection( EEHorizontalTextDirection eHTextDir ); diff --git a/include/editeng/outliner.hxx b/include/editeng/outliner.hxx index 98dd7dc14b00..34de51fc904c 100644 --- a/include/editeng/outliner.hxx +++ b/include/editeng/outliner.hxx @@ -658,6 +658,8 @@ public: bool IsVertical() const; bool IsTopToBottom() const; + void SetTextColumns(sal_Int16 nColumns, sal_Int32 nSpacing); + void SetFixedCellHeight( bool bUseFixedCellHeight ); void SetDefaultHorizontalTextDirection( EEHorizontalTextDirection eHTextDir ); diff --git a/include/svx/dialogs.hrc b/include/svx/dialogs.hrc index 5dc3fc6faa58..f03600a74fe0 100644 --- a/include/svx/dialogs.hrc +++ b/include/svx/dialogs.hrc @@ -45,6 +45,7 @@ #define RID_SVXPAGE_TRANSPARENCE (RID_SVX_START + 54) #define RID_SVXPAGE_TEXTATTR (RID_SVX_START + 153) #define RID_SVXPAGE_TEXTANIMATION (RID_SVX_START + 184) +#define RID_SVXPAGE_TEXTCOLUMNS (RID_SVX_START + 154) #define RID_SVXPAGE_MEASURE (RID_SVX_START + 161) #define RID_SVXPAGE_CONNECTION (RID_SVX_START + 191) #define RID_SVXPAGE_LINE_DEF (RID_SVX_START + 52) diff --git a/include/svx/strings.hrc b/include/svx/strings.hrc index 35fa94d665cb..4ac04ffb2fea 100644 --- a/include/svx/strings.hrc +++ b/include/svx/strings.hrc @@ -402,6 +402,8 @@ #define SIP_SA_TEXT_ANIDELAY NC_("SIP_SA_TEXT_ANIDELAY", "Speed of ticker") #define SIP_SA_TEXT_ANIAMOUNT NC_("SIP_SA_TEXT_ANIAMOUNT", "Ticker step size") #define SIP_SA_TEXT_CONTOURFRAME NC_("SIP_SA_TEXT_CONTOURFRAME", "Outline text flow") +#define SIP_SA_TEXTCOLUMNS_NUMBER NC_("SIP_SA_TEXTCOLUMNS_NUMBER", "Columns number") +#define SIP_SA_TEXTCOLUMNS_SPACING NC_("SIP_SA_TEXTCOLUMNS_SPACING", "Columns spacing") #define SIP_SA_XMLATTRIBUTES NC_("SIP_SA_XMLATTRIBUTES", "User-defined attributes") #define SIP_SA_TEXT_USEFIXEDCELLHEIGHT NC_("SIP_SA_TEXT_USEFIXEDCELLHEIGHT", "Use font-independent line spacing") #define SIP_SA_WORDWRAP NC_("SIP_SA_WORDWRAP", "Word wrap text in shape") diff --git a/include/svx/svddef.hxx b/include/svx/svddef.hxx index 6061293f9421..9332dc65a59f 100644 --- a/include/svx/svddef.hxx +++ b/include/svx/svddef.hxx @@ -138,6 +138,7 @@ class SdrVertShearAllItem; class SdrVertShearOneItem; class SdrYesNoItem; class SfxBoolItem; +class SfxInt16Item; class SfxUInt16Item; class SfxUInt32Item; class SfxStringItem; @@ -426,7 +427,12 @@ constexpr sal_uInt16 SDRATTR_SOFTEDGE_FIRST(SDRATTR_GLOW_LAST + constexpr TypedWhichId<SdrMetricItem> SDRATTR_SOFTEDGE_RADIUS(SDRATTR_SOFTEDGE_FIRST + 0); constexpr sal_uInt16 SDRATTR_SOFTEDGE_LAST(SDRATTR_SOFTEDGE_RADIUS); -constexpr sal_uInt16 SDRATTR_END (SDRATTR_SOFTEDGE_LAST); /* 1357 */ /* 1333 V4+++*/ /* 1243 V4+++*/ /*1213*/ /*1085*/ /*1040*/ /*Pool V2: 1123,V1: 1065 */ +constexpr sal_uInt16 SDRATTR_TEXTCOLUMNS_FIRST(SDRATTR_SOFTEDGE_LAST + 1); +constexpr TypedWhichId<SfxInt16Item> SDRATTR_TEXTCOLUMNS_NUMBER(SDRATTR_TEXTCOLUMNS_FIRST + 0); +constexpr TypedWhichId<SdrMetricItem> SDRATTR_TEXTCOLUMNS_SPACING(SDRATTR_TEXTCOLUMNS_FIRST + 1); +constexpr sal_uInt16 SDRATTR_TEXTCOLUMNS_LAST(SDRATTR_TEXTCOLUMNS_SPACING); + +constexpr sal_uInt16 SDRATTR_END (SDRATTR_TEXTCOLUMNS_LAST); /* 1357 */ /* 1333 V4+++*/ /* 1243 V4+++*/ /*1213*/ /*1085*/ /*1040*/ /*Pool V2: 1123,V1: 1065 */ #endif // INCLUDED_SVX_SVDDEF_HXX diff --git a/include/svx/svdotext.hxx b/include/svx/svdotext.hxx index a3ff2e1fda50..746d1d2de93e 100644 --- a/include/svx/svdotext.hxx +++ b/include/svx/svdotext.hxx @@ -439,6 +439,9 @@ public: SdrTextAniKind GetTextAniKind() const; SdrTextAniDirection GetTextAniDirection() const; + sal_Int16 GetTextColumnsNumber() const; + sal_Int32 GetTextColumnsSpacing() const; + // react on model/page change virtual void handlePageChange(SdrPage* pOldPage, SdrPage* pNewPage) override; diff --git a/sd/qa/uitest/impress_tests/textColumnsDialog.py b/sd/qa/uitest/impress_tests/textColumnsDialog.py new file mode 100644 index 000000000000..d6ae7d248000 --- /dev/null +++ b/sd/qa/uitest/impress_tests/textColumnsDialog.py @@ -0,0 +1,53 @@ +# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +from uitest.uihelper.common import get_state_as_dict +from libreoffice.uno.propertyvalue import mkPropertyValues +from uitest.uihelper.common import change_measurement_unit, select_pos +from uitest.framework import UITestCase +from uitest.uihelper import guarded + +class textColumnsDialog(UITestCase): + + def test_textColumnsDialog(self): + with guarded.create_doc_in_start_center(self, "impress") as document: + + xTemplateDlg = self.xUITest.getTopFocusWindow() + xCancelBtn = xTemplateDlg.getChild("close") + self.ui_test.close_dialog_through_button(xCancelBtn) + + change_measurement_unit(self, 'Centimeter') + + xImpressDoc = self.xUITest.getTopFocusWindow() + + xEditWin = xImpressDoc.getChild("impress_win") + xEditWin.executeAction("SELECT", mkPropertyValues({"OBJECT":"Unnamed Drawinglayer object 1"})) + self.assertEqual("com.sun.star.drawing.SvxShapeCollection", document.CurrentSelection.getImplementationName()) + + # Test defaults and set some values + with guarded.execute_dialog_through_command(self, ".uno:TextAttributes") as xDialog: + xTabs = xDialog.getChild("tabcontrol") + select_pos(xTabs, "2") + colNumber = xDialog.getChild('FLD_COL_NUMBER') + colSpacing = xDialog.getChild('MTR_FLD_COL_SPACING') + self.assertEqual('1', get_state_as_dict(colNumber)['Text']) + self.assertEqual('0.00 cm', get_state_as_dict(colSpacing)['Text']) + colNumber.executeAction("SET", mkPropertyValues({"TEXT": "3"})) + colSpacing.executeAction("SET", mkPropertyValues({"TEXT": "1.5"})) + + # Test that settings persist + with guarded.execute_dialog_through_command(self, ".uno:TextAttributes") as xDialog: + xTabs = xDialog.getChild("tabcontrol") + select_pos(xTabs, "2") + colNumber = xDialog.getChild('FLD_COL_NUMBER') + colSpacing = xDialog.getChild('MTR_FLD_COL_SPACING') + self.assertEqual('3', get_state_as_dict(colNumber)['Text']) + self.assertEqual('1.50 cm', get_state_as_dict(colSpacing)['Text']) + +# vim: set shiftwidth=4 softtabstop=4 expandtab: diff --git a/sd/qa/unit/misc-tests.cxx b/sd/qa/unit/misc-tests.cxx index 031aeca1f817..254fc46f69bb 100644 --- a/sd/qa/unit/misc-tests.cxx +++ b/sd/qa/unit/misc-tests.cxx @@ -58,6 +58,8 @@ #include <tools/gen.hxx> #include <svx/view3d.hxx> #include <svx/scene3d.hxx> +#include <svx/sdmetitm.hxx> +#include <svx/unoapi.hxx> using namespace ::com::sun::star; @@ -80,6 +82,7 @@ public: void testTdf67248(); void testTdf119956(); void testTdf120527(); + void testTextColumns(); void testTdf98839_ShearVFlipH(); void testTdf130988(); void testTdf131033(); @@ -102,6 +105,7 @@ public: CPPUNIT_TEST(testTdf67248); CPPUNIT_TEST(testTdf119956); CPPUNIT_TEST(testTdf120527); + CPPUNIT_TEST(testTextColumns); CPPUNIT_TEST(testTdf98839_ShearVFlipH); CPPUNIT_TEST(testTdf130988); CPPUNIT_TEST(testTdf131033); @@ -472,6 +476,51 @@ void SdMiscTest::testTdf120527() xDocShRef->DoClose(); } +// Testing document model part of editengine-columns +void SdMiscTest::testTextColumns() +{ + ::sd::DrawDocShellRef xDocShRef + = new ::sd::DrawDocShell(SfxObjectCreateMode::EMBEDDED, false, DocumentType::Impress); + uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier = getDoc(xDocShRef); + uno::Reference<drawing::XDrawPages> xDrawPages = xDrawPagesSupplier->getDrawPages(); + // Insert a new page. + uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPages->insertNewByIndex(0), + uno::UNO_SET_THROW); + uno::Reference<drawing::XShapes> xShapes(xDrawPage, uno::UNO_QUERY_THROW); + uno::Reference<lang::XMultiServiceFactory> const xDoc(xDocShRef->GetDoc()->getUnoModel(), + uno::UNO_QUERY); + + { + // Create a text shape + uno::Reference<drawing::XShape> xShape( + xDoc->createInstance("com.sun.star.drawing.TextShape"), uno::UNO_QUERY_THROW); + uno::Reference<beans::XPropertySet> xPropSet(xShape, uno::UNO_QUERY_THROW); + + // Add the shape to the page. + xShapes->add(xShape); + + // Set up columns + auto pTextObj = dynamic_cast<SdrTextObj*>(GetSdrObjectFromXShape(xShape)); + CPPUNIT_ASSERT(pTextObj); + pTextObj->SetMergedItem(SfxInt16Item(SDRATTR_TEXTCOLUMNS_NUMBER, 2)); + pTextObj->SetMergedItem(SdrMetricItem(SDRATTR_TEXTCOLUMNS_SPACING, 1000)); + } + + { + // Retrieve the shape and check columns + uno::Reference<container::XIndexAccess> xIndexAccess(xDrawPage, uno::UNO_QUERY_THROW); + uno::Reference<drawing::XShape> xShape(xIndexAccess->getByIndex(0), uno::UNO_QUERY_THROW); + + auto pTextObj = dynamic_cast<SdrTextObj*>(GetSdrObjectFromXShape(xShape)); + CPPUNIT_ASSERT(pTextObj); + + CPPUNIT_ASSERT_EQUAL(sal_Int16(2), pTextObj->GetTextColumnsNumber()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1000), pTextObj->GetTextColumnsSpacing()); + } + + xDocShRef->DoClose(); +} + /// Draw miscellaneous tests. // Since LO 6.2 the visible/printable/locked information for layers is always diff --git a/svx/source/sdr/properties/attributeproperties.cxx b/svx/source/sdr/properties/attributeproperties.cxx index c61f95354020..2dfd9e819981 100644 --- a/svx/source/sdr/properties/attributeproperties.cxx +++ b/svx/source/sdr/properties/attributeproperties.cxx @@ -129,7 +129,8 @@ namespace sdr::properties // ranges from SdrAttrObj svl::Items<SDRATTR_START, SDRATTR_SHADOW_LAST, SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST, - SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION>{}); + SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION, + SDRATTR_TEXTCOLUMNS_FIRST, SDRATTR_TEXTCOLUMNS_LAST>{}); } AttributeProperties::AttributeProperties(SdrObject& rObj) diff --git a/svx/source/sdr/properties/captionproperties.cxx b/svx/source/sdr/properties/captionproperties.cxx index 6f98fdb2a407..d073aa91b91e 100644 --- a/svx/source/sdr/properties/captionproperties.cxx +++ b/svx/source/sdr/properties/captionproperties.cxx @@ -38,6 +38,7 @@ namespace sdr::properties // Ranges from SdrAttrObj, SdrCaptionObj: SDRATTR_START, SDRATTR_MISC_LAST, SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION, + SDRATTR_TEXTCOLUMNS_FIRST, SDRATTR_TEXTCOLUMNS_LAST, // Range from SdrTextObj: EE_ITEMS_START, EE_ITEMS_END>{}); } diff --git a/svx/source/sdr/properties/circleproperties.cxx b/svx/source/sdr/properties/circleproperties.cxx index 08139805228c..dab008ff6957 100644 --- a/svx/source/sdr/properties/circleproperties.cxx +++ b/svx/source/sdr/properties/circleproperties.cxx @@ -42,6 +42,7 @@ namespace sdr::properties SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST, SDRATTR_CIRC_FIRST, SDRATTR_CIRC_LAST, SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION, + SDRATTR_TEXTCOLUMNS_FIRST, SDRATTR_TEXTCOLUMNS_LAST, // Range from SdrTextObj: EE_ITEMS_START, EE_ITEMS_END>{}); } diff --git a/svx/source/sdr/properties/connectorproperties.cxx b/svx/source/sdr/properties/connectorproperties.cxx index 58e773e91327..97063011f79c 100644 --- a/svx/source/sdr/properties/connectorproperties.cxx +++ b/svx/source/sdr/properties/connectorproperties.cxx @@ -39,6 +39,7 @@ namespace sdr::properties SDRATTR_START, SDRATTR_SHADOW_LAST, SDRATTR_MISC_FIRST, SDRATTR_EDGE_LAST, SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION, + SDRATTR_TEXTCOLUMNS_FIRST, SDRATTR_TEXTCOLUMNS_LAST, // Range from SdrTextObj: EE_ITEMS_START, EE_ITEMS_END>{}); } diff --git a/svx/source/sdr/properties/customshapeproperties.cxx b/svx/source/sdr/properties/customshapeproperties.cxx index 4b372605576d..07c893d1cf51 100644 --- a/svx/source/sdr/properties/customshapeproperties.cxx +++ b/svx/source/sdr/properties/customshapeproperties.cxx @@ -71,7 +71,7 @@ namespace sdr::properties // Graphic attributes, 3D properties, CustomShape // properties: SDRATTR_GRAF_FIRST, SDRATTR_CUSTOMSHAPE_LAST, - SDRATTR_GLOW_FIRST, SDRATTR_SOFTEDGE_LAST, + SDRATTR_GLOW_FIRST, SDRATTR_TEXTCOLUMNS_LAST, // Range from SdrTextObj: EE_ITEMS_START, EE_ITEMS_END>{}); } diff --git a/svx/source/sdr/properties/graphicproperties.cxx b/svx/source/sdr/properties/graphicproperties.cxx index d50e58f3d883..c7a9b6913ad0 100644 --- a/svx/source/sdr/properties/graphicproperties.cxx +++ b/svx/source/sdr/properties/graphicproperties.cxx @@ -67,7 +67,7 @@ namespace sdr::properties // range from SdrGrafObj SDRATTR_GRAF_FIRST, SDRATTR_GRAF_LAST, - SDRATTR_GLOW_FIRST, SDRATTR_SOFTEDGE_LAST, + SDRATTR_GLOW_FIRST, SDRATTR_TEXTCOLUMNS_LAST, // range from SdrTextObj EE_ITEMS_START, EE_ITEMS_END>{}); diff --git a/svx/source/sdr/properties/measureproperties.cxx b/svx/source/sdr/properties/measureproperties.cxx index 0675a6c1ddc4..e503c5710810 100644 --- a/svx/source/sdr/properties/measureproperties.cxx +++ b/svx/source/sdr/properties/measureproperties.cxx @@ -48,6 +48,7 @@ namespace sdr::properties SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST, SDRATTR_MEASURE_FIRST, SDRATTR_MEASURE_LAST, SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION, + SDRATTR_TEXTCOLUMNS_FIRST, SDRATTR_TEXTCOLUMNS_LAST, // Range from SdrTextObj: EE_ITEMS_START, EE_ITEMS_END>{}); } diff --git a/svx/source/sdr/properties/textproperties.cxx b/svx/source/sdr/properties/textproperties.cxx index a5ebc79efddc..de5c6765de75 100644 --- a/svx/source/sdr/properties/textproperties.cxx +++ b/svx/source/sdr/properties/textproperties.cxx @@ -54,6 +54,7 @@ namespace sdr::properties svl::Items<SDRATTR_START, SDRATTR_SHADOW_LAST, SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST, SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION, + SDRATTR_TEXTCOLUMNS_FIRST, SDRATTR_TEXTCOLUMNS_LAST, // range from SdrTextObj EE_ITEMS_START, EE_ITEMS_END>{}); @@ -87,6 +88,12 @@ namespace sdr::properties // #i101556# ItemSet has changed -> new version maVersion++; + if (auto pOutliner = rObj.GetTextEditOutliner()) + { + pOutliner->SetTextColumns(rObj.GetTextColumnsNumber(), + rObj.GetTextColumnsSpacing()); + } + const svx::ITextProvider& rTextProvider(getTextProvider()); sal_Int32 nText = rTextProvider.getTextCount(); while (nText--) diff --git a/svx/source/svdraw/svdattr.cxx b/svx/source/svdraw/svdattr.cxx index 0d32ce6e0baf..411294962d45 100644 --- a/svx/source/svdraw/svdattr.cxx +++ b/svx/source/svdraw/svdattr.cxx @@ -332,6 +332,9 @@ SdrItemPool::SdrItemPool( rPoolDefaults[SDRATTR_SOFTEDGE_RADIUS - SDRATTR_START] = new SdrMetricItem(SDRATTR_SOFTEDGE_RADIUS, 0); + rPoolDefaults[SDRATTR_TEXTCOLUMNS_NUMBER - SDRATTR_START] = new SfxInt16Item(SDRATTR_TEXTCOLUMNS_NUMBER, 1); + rPoolDefaults[SDRATTR_TEXTCOLUMNS_SPACING - SDRATTR_START] = new SdrMetricItem(SDRATTR_TEXTCOLUMNS_SPACING, 0); + // set own ItemInfos mpLocalItemInfos[SDRATTR_SHADOW-SDRATTR_START]._nSID=SID_ATTR_FILL_SHADOW; mpLocalItemInfos[SDRATTR_SHADOWCOLOR-SDRATTR_START]._nSID=SID_ATTR_SHADOW_COLOR; @@ -353,6 +356,9 @@ SdrItemPool::SdrItemPool( mpLocalItemInfos[SDRATTR_SOFTEDGE_RADIUS - SDRATTR_START]._nSID = SID_ATTR_SOFTEDGE_RADIUS; + mpLocalItemInfos[SDRATTR_TEXTCOLUMNS_NUMBER - SDRATTR_START]._nSID = 0 /*TODO*/; + mpLocalItemInfos[SDRATTR_TEXTCOLUMNS_SPACING - SDRATTR_START]._nSID = 0 /*TODO*/; + // it's my own creation level, set Defaults and ItemInfos SetDefaults(mpLocalPoolDefaults); SetItemInfos(mpLocalItemInfos.get()); @@ -619,6 +625,9 @@ OUString SdrItemPool::GetItemName(sal_uInt16 nWhich) case EE_FEATURE_LINEBR : pResId = SIP_EE_FEATURE_LINEBR;break; case EE_FEATURE_NOTCONV : pResId = SIP_EE_FEATURE_NOTCONV;break; case EE_FEATURE_FIELD : pResId = SIP_EE_FEATURE_FIELD;break; + + case SDRATTR_TEXTCOLUMNS_NUMBER: pResId = SIP_SA_TEXTCOLUMNS_NUMBER; break; + case SDRATTR_TEXTCOLUMNS_SPACING: pResId = SIP_SA_TEXTCOLUMNS_SPACING; break; } // switch return SvxResId(pResId); diff --git a/svx/source/svdraw/svdotext.cxx b/svx/source/svdraw/svdotext.cxx index 090ffc901dfe..a5d9939a6103 100644 --- a/svx/source/svdraw/svdotext.cxx +++ b/svx/source/svdraw/svdotext.cxx @@ -1724,6 +1724,16 @@ SdrTextAniDirection SdrTextObj::GetTextAniDirection() const return GetObjectItemSet().Get(SDRATTR_TEXT_ANIDIRECTION).GetValue(); } +sal_Int16 SdrTextObj::GetTextColumnsNumber() const +{ + return GetObjectItemSet().Get(SDRATTR_TEXTCOLUMNS_NUMBER).GetValue(); +} + +sal_Int32 SdrTextObj::GetTextColumnsSpacing() const +{ + return GetObjectItemSet().Get(SDRATTR_TEXTCOLUMNS_SPACING).GetValue(); +} + // Get necessary data for text scroll animation. ATM base it on a Text-Metafile and a // painting rectangle. Rotation is excluded from the returned values. GDIMetaFile* SdrTextObj::GetTextScrollMetaFileAndRectangle( diff --git a/svx/source/svdraw/svdotxed.cxx b/svx/source/svdraw/svdotxed.cxx index f332bf524db3..950a5cff85be 100644 --- a/svx/source/svdraw/svdotxed.cxx +++ b/svx/source/svdraw/svdotxed.cxx @@ -349,6 +349,7 @@ void SdrTextObj::ImpSetTextEditParams() const pEdtOutl->SetMinAutoPaperSize(aPaperMin); pEdtOutl->SetMaxAutoPaperSize(aPaperMax); pEdtOutl->SetPaperSize(Size()); + pEdtOutl->SetTextColumns(GetTextColumnsNumber(), GetTextColumnsSpacing()); if (bContourFrame) { tools::Rectangle aAnchorRect; TakeTextAnchorRect(aAnchorRect); diff --git a/svx/source/svdraw/svdoutl.cxx b/svx/source/svdraw/svdoutl.cxx index fed5e1c82f25..738309182fd7 100644 --- a/svx/source/svdraw/svdoutl.cxx +++ b/svx/source/svdraw/svdoutl.cxx @@ -57,6 +57,7 @@ void SdrOutliner::SetTextObj( const SdrTextObj* pObj ) SetMinAutoPaperSize( Size() ); SetMaxAutoPaperSize( aMaxSize ); SetPaperSize( aMaxSize ); + SetTextColumns(pObj->GetTextColumnsNumber(), pObj->GetTextColumnsSpacing()); ClearPolygon(); } diff --git a/uitest/uitest/uihelper/guarded.py b/uitest/uitest/uihelper/guarded.py index 871fa697d584..b75aea332ff3 100644 --- a/uitest/uitest/uihelper/guarded.py +++ b/uitest/uitest/uihelper/guarded.py @@ -18,6 +18,16 @@ def load_file(testCase, url): finally: testCase.ui_test.close_doc() +# Calls UITest.close_doc at exit +@contextmanager +def create_doc_in_start_center(testCase, app): + testCase.ui_test.create_doc_in_start_center(app) + component = testCase.ui_test.get_component() + try: + yield component + finally: + testCase.ui_test.close_doc() + # Calls UITest.close_dialog_through_button at exit @contextmanager def execute_dialog_through_action(testCase, ui_object, action, parameters = None, event_name = "DialogExecute", close_button = "ok"): @@ -30,8 +40,8 @@ def execute_dialog_through_action(testCase, ui_object, action, parameters = None # Calls UITest.close_dialog_through_button at exit @contextmanager -def execute_dialog_through_command(testCase, unoCommand, close_button = "ok"): - testCase.ui_test.execute_dialog_through_command(unoCommand) +def execute_dialog_through_command(testCase, command, printNames=False, close_button = "ok"): + testCase.ui_test.execute_dialog_through_command(command, printNames) xDialog = testCase.xUITest.getTopFocusWindow() try: yield xDialog |