From f23d3661ab04601650db95f846081317fc06801d Mon Sep 17 00:00:00 2001 From: Maxim Monastirsky Date: Sun, 13 Nov 2022 14:50:08 +0200 Subject: sd: table design editing Change-Id: I75559c80da015a13ee078bdda06f6f4975fe5946 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140943 Tested-by: Jenkins Reviewed-by: Maxim Monastirsky --- icon-themes/colibre/sd/res/addtablestyle.png | Bin 0 -> 663 bytes include/svx/sdr/table/tablecontroller.hxx | 3 + sd/inc/bitmaps.hlst | 1 + sd/inc/strings.hrc | 2 + sd/source/ui/inc/TableDesignPane.hxx | 16 +- sd/source/ui/table/TableDesignPane.cxx | 317 +++++++++++++++++++++++++-- sd/uiconfig/simpress/ui/tabledesignpanel.ui | 118 ++++++++++ svx/source/table/tablecontroller.cxx | 56 ++--- svx/source/table/tabledesign.cxx | 41 +++- 9 files changed, 508 insertions(+), 46 deletions(-) create mode 100644 icon-themes/colibre/sd/res/addtablestyle.png diff --git a/icon-themes/colibre/sd/res/addtablestyle.png b/icon-themes/colibre/sd/res/addtablestyle.png new file mode 100644 index 000000000000..8e4422cb733f Binary files /dev/null and b/icon-themes/colibre/sd/res/addtablestyle.png differ diff --git a/include/svx/sdr/table/tablecontroller.hxx b/include/svx/sdr/table/tablecontroller.hxx index e71eba7cf608..bb02fc271f52 100644 --- a/include/svx/sdr/table/tablecontroller.hxx +++ b/include/svx/sdr/table/tablecontroller.hxx @@ -87,6 +87,9 @@ public: const SdrTableObj& rObj, const rtl::Reference< sdr::SelectionController >& xRefController); + static SvxBoxItem TextDistancesToSvxBoxItem(const SfxItemSet& rAttrSet); + static void SvxBoxItemToTextDistances(const SvxBoxItem& pOriginalItem, SfxItemSet& rAttrSet); + SVX_DLLPRIVATE void MergeAttrFromSelectedCells(SfxItemSet& rAttr, bool bOnlyHardAttr) const; SVX_DLLPRIVATE void SetAttrToSelectedCells(const SfxItemSet& rAttr, bool bReplaceAll); void SetAttrToSelectedShape(const SfxItemSet& rAttr); diff --git a/sd/inc/bitmaps.hlst b/sd/inc/bitmaps.hlst index e1c798cfae4e..32e81ced59fa 100644 --- a/sd/inc/bitmaps.hlst +++ b/sd/inc/bitmaps.hlst @@ -78,6 +78,7 @@ inline constexpr OUStringLiteral BMP_POINTER_ICON = u"sd/res/pointericon.png"; inline constexpr OUStringLiteral BMP_WAIT_ICON = u"sd/res/waiticon.png"; inline constexpr OUStringLiteral BMP_FADE_EFFECT_INDICATOR = u"sd/res/fade_effect_indicator.png"; inline constexpr OUStringLiteral BMP_CUSTOM_ANIMATION_INDICATOR = u"sd/res/click_16.png"; +inline constexpr OUStringLiteral BMP_INSERT_TABLESTYLE = u"sd/res/addtablestyle.png"; // Presenter Screen bitmaps: inline constexpr OUStringLiteral BMP_PRESENTERSCREEN_BORDER_LEFT = u"sd/res/presenterscreen-BorderLeft.png"; inline constexpr OUStringLiteral BMP_PRESENTERSCREEN_BUTTON_SLIDE_NEXT_DISABLED = u"sd/res/presenterscreen-ButtonSlideNextDisabled.png"; diff --git a/sd/inc/strings.hrc b/sd/inc/strings.hrc index 05326f9e461a..662acd59db12 100644 --- a/sd/inc/strings.hrc +++ b/sd/inc/strings.hrc @@ -484,5 +484,7 @@ #define RID_SVXSTR_MENU_LAST NC_("RID_SVXSTR_MENU_LAST", "~Last Slide") #define STR_CLOSE_PANE NC_("STR_CLOSE_PANE", "Close Pane") +#define STR_INSERT_TABLESTYLE NC_("STR_INSERT_TABLESTYLE", "Add a new design") +#define STR_REMOVE_TABLESTYLE NC_("STR_REMOVE_TABLESTYLE", "The selected style is in use in this document.\nIf you will delete this style, tables using it will revert to the default style.\nDo you still wish to delete this style?\n") /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/inc/TableDesignPane.hxx b/sd/source/ui/inc/TableDesignPane.hxx index 042eb6137662..a3658bb30bf2 100644 --- a/sd/source/ui/inc/TableDesignPane.hxx +++ b/sd/source/ui/inc/TableDesignPane.hxx @@ -25,7 +25,7 @@ #include namespace com::sun::star::beans { class XPropertySet; } -namespace com::sun::star::container { class XIndexAccess; } +namespace com::sun::star::container { class XIndexAccess; class XNameContainer; } namespace com::sun::star::drawing { class XDrawView; } namespace sd @@ -52,12 +52,16 @@ class TableValueSet final : public ValueSet { private: bool m_bModal; + Link maContextMenuHandler; public: TableValueSet(std::unique_ptr pScrolledWindow); + virtual bool Command(const CommandEvent& rEvent) override; virtual void Resize() override; virtual void StyleUpdated() override; void updateSettings(); void setModal(bool bModal) { m_bModal = bModal; } + void SetContextMenuHandler(const Link& rLink) { maContextMenuHandler = rLink; } + static constexpr int getMaxRowCount() { return 3; } }; class TableDesignWidget final @@ -71,20 +75,29 @@ public: void ApplyOptions(); void ApplyStyle(); + void InsertStyle(); + void CloneStyle(); + void ResetStyle(); + void DeleteStyle(); + void EditStyle(std::string_view rCommand); private: void addListener(); void removeListener(); void updateControls(); + void selectStyle(std::u16string_view rStyle); + void setDocumentModified(); void FillDesignPreviewControl(); DECL_LINK(EventMultiplexerListener, tools::EventMultiplexerEvent&, void); + DECL_LINK(implContextMenuHandler, const Point*, void); DECL_LINK(implValueSetHdl, ValueSet*, void); DECL_LINK(implCheckBoxHdl, weld::Toggleable&, void); ViewShellBase& mrBase; + std::unique_ptr m_xMenu; std::unique_ptr m_xValueSet; std::unique_ptr m_xValueSetWin; std::unique_ptr m_aCheckBoxes[CB_COUNT]; @@ -92,6 +105,7 @@ private: css::uno::Reference< css::beans::XPropertySet > mxSelectedTable; css::uno::Reference< css::drawing::XDrawView > mxView; css::uno::Reference< css::container::XIndexAccess > mxTableFamily; + css::uno::Reference< css::container::XNameContainer > mxCellFamily; }; class TableDesignPane final : public PanelLayout diff --git a/sd/source/ui/table/TableDesignPane.cxx b/sd/source/ui/table/TableDesignPane.cxx index fbed413d3160..07371e6e9980 100644 --- a/sd/source/ui/table/TableDesignPane.cxx +++ b/sd/source/ui/table/TableDesignPane.cxx @@ -24,14 +24,18 @@ #include #include #include +#include +#include #include #include #include #include #include +#include #include #include +#include #include #include @@ -44,15 +48,21 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include +#include +#include +#include +#include #include #include #include @@ -89,6 +99,7 @@ const std::string_view gPropNames[CB_COUNT] = TableDesignWidget::TableDesignWidget(weld::Builder& rBuilder, ViewShellBase& rBase) : mrBase(rBase) + , m_xMenu(rBuilder.weld_menu("menu")) , m_xValueSet(new TableValueSet(rBuilder.weld_scrolled_window("previewswin", true))) , m_xValueSetWin(new weld::CustomWeld(rBuilder, "previews", *m_xValueSet)) { @@ -97,6 +108,7 @@ TableDesignWidget::TableDesignWidget(weld::Builder& rBuilder, ViewShellBase& rBa m_xValueSet->setModal(false); m_xValueSet->SetColor(); m_xValueSet->SetSelectHdl(LINK(this, TableDesignWidget, implValueSetHdl)); + m_xValueSet->SetContextMenuHandler(LINK(this, TableDesignWidget, implContextMenuHandler)); for (sal_uInt16 i = CB_HEADER_ROW; i <= CB_BANDED_COLUMNS; ++i) { @@ -114,6 +126,7 @@ TableDesignWidget::TableDesignWidget(weld::Builder& rBuilder, ViewShellBase& rBa Reference< XStyleFamiliesSupplier > xFamiliesSupp( xController->getModel(), UNO_QUERY_THROW ); Reference< XNameAccess > xFamilies( xFamiliesSupp->getStyleFamilies() ); mxTableFamily.set( xFamilies->getByName( "table" ), UNO_QUERY_THROW ); + mxCellFamily.set( xFamilies->getByName( "cell" ), UNO_QUERY_THROW ); } catch (const Exception&) { @@ -129,6 +142,263 @@ TableDesignWidget::~TableDesignWidget() removeListener(); } +void TableDesignWidget::setDocumentModified() +{ + try + { + Reference xController(mrBase.GetController(), UNO_SET_THROW); + Reference xModifiable(xController->getModel(), UNO_QUERY_THROW); + xModifiable->setModified(true); + } + catch (Exception&) + { + TOOLS_WARN_EXCEPTION( "sd", "TableDesignWidget::setDocumentModified()"); + } +} + +IMPL_LINK(TableDesignWidget, implContextMenuHandler, const Point*, pPoint, void) +{ + auto nClickedItemId = pPoint ? m_xValueSet->GetItemId(*pPoint) : m_xValueSet->GetSelectedItemId(); + + try + { + if (nClickedItemId > mxTableFamily->getCount()) + return; + + if (nClickedItemId) + { + Reference xStyle(mxTableFamily->getByIndex(nClickedItemId - 1), UNO_QUERY_THROW); + + m_xMenu->set_visible("clone", true); + m_xMenu->set_visible("format", true); + m_xMenu->set_visible("delete", xStyle->isUserDefined()); + m_xMenu->set_visible("reset", !xStyle->isUserDefined()); + m_xMenu->set_sensitive("reset", Reference(xStyle, UNO_QUERY_THROW)->isModified()); + } + else + { + m_xMenu->set_visible("clone", false); + m_xMenu->set_visible("format", false); + m_xMenu->set_visible("delete", false); + m_xMenu->set_visible("reset", false); + } + } + catch (Exception&) + { + TOOLS_WARN_EXCEPTION( "sd", "TableDesignWidget::implContextMenuHandler()"); + } + + m_xValueSet->SelectItem(nClickedItemId); + + Point aPosition = pPoint ? *pPoint : m_xValueSet->GetItemRect(nClickedItemId).Center(); + OString aCommand = m_xMenu->popup_at_rect(m_xValueSet->GetDrawingArea(), ::tools::Rectangle(aPosition, Size(1,1))); + + if (aCommand == "new") + InsertStyle(); + else if (aCommand == "clone") + CloneStyle(); + else if (aCommand == "delete") + DeleteStyle(); + else if (aCommand == "reset") + ResetStyle(); + else if (!aCommand.isEmpty()) + EditStyle(aCommand); +} + +namespace +{ + OUString getNewValidTableStyleName(const Reference& rTableFamily) + { + OUString aName; + sal_Int32 nIndex = 1; + do + { + aName = "table" + OUString::number(nIndex++); + } + while(rTableFamily->hasByName(aName)); + + return aName; + } +} + +void TableDesignWidget::InsertStyle() +{ + try + { + Reference xFactory(mxTableFamily, UNO_QUERY_THROW); + Reference xTableFamily(mxTableFamily, UNO_QUERY_THROW); + Reference xTableStyle(xFactory->createInstance(), UNO_QUERY_THROW); + const OUString aName(getNewValidTableStyleName(xTableFamily)); + xTableFamily->insertByName(aName, Any(xTableStyle)); + + Reference xCellStyle(mxCellFamily->getByName("default"), UNO_QUERY_THROW); + + xTableStyle->replaceByName("body", Any(xCellStyle)); + xTableStyle->replaceByName("odd-rows" , Any(xCellStyle)); + xTableStyle->replaceByName("odd-columns" , Any(xCellStyle)); + xTableStyle->replaceByName("first-row" , Any(xCellStyle)); + xTableStyle->replaceByName("first-column" , Any(xCellStyle)); + xTableStyle->replaceByName("last-row" , Any(xCellStyle)); + xTableStyle->replaceByName("last-column" , Any(xCellStyle)); + + updateControls(); + selectStyle(aName); + setDocumentModified(); + } + catch (Exception&) + { + TOOLS_WARN_EXCEPTION( "sd", "TableDesignWidget::InsertStyle()"); + } +} + +void TableDesignWidget::CloneStyle() +{ + try + { + Reference xSrcTableStyle(mxTableFamily->getByIndex(m_xValueSet->GetSelectedItemId() - 1), UNO_QUERY_THROW); + + Reference xFactory(mxTableFamily, UNO_QUERY_THROW); + Reference xTableFamily(mxTableFamily, UNO_QUERY_THROW); + Reference xDestTableStyle(xFactory->createInstance(), UNO_QUERY_THROW); + const OUString aName(getNewValidTableStyleName(xTableFamily)); + xTableFamily->insertByName(aName, Any(xDestTableStyle)); + + for (sal_Int32 i = 0; i < xDestTableStyle->getCount(); ++i) + { + Reference xSrcCellStyle(xSrcTableStyle->getByIndex(i), UNO_QUERY); + if (xSrcCellStyle && xSrcCellStyle->isUserDefined()) + { + Reference xCellFactory(mxCellFamily, UNO_QUERY_THROW); + Reference xDestCellStyle(xCellFactory->createInstance(), UNO_QUERY_THROW); + xDestCellStyle->setParentStyle(xSrcCellStyle->getParentStyle()); + mxCellFamily->insertByName(xDestCellStyle->getName(), Any(xDestCellStyle)); + + rtl::Reference xSrcStyleSheet = static_cast(xSrcCellStyle.get()); + rtl::Reference xDestStyleSheet = static_cast(xDestCellStyle.get()); + + xDestStyleSheet->GetItemSet().Put(xSrcStyleSheet->GetItemSet()); + + xDestTableStyle->replaceByIndex(i, Any(xDestCellStyle)); + } + else + xDestTableStyle->replaceByIndex(i, Any(xSrcCellStyle)); + } + + updateControls(); + selectStyle(aName); + setDocumentModified(); + } + catch (Exception&) + { + TOOLS_WARN_EXCEPTION( "sd", "TableDesignWidget::CloneStyle()"); + } +} + +void TableDesignWidget::ResetStyle() +{ + try + { + Reference xTableStyle(mxTableFamily->getByIndex(m_xValueSet->GetSelectedItemId() - 1), UNO_QUERY_THROW); + + for (sal_Int32 i = 0; i < xTableStyle->getCount(); ++i) + { + Reference xCellStyle(xTableStyle->getByIndex(i), UNO_QUERY); + if (xCellStyle && xCellStyle->isUserDefined()) + xTableStyle->replaceByIndex(i, mxCellFamily->getByName(xCellStyle->getParentStyle())); + } + + Reference(xTableStyle, UNO_QUERY_THROW)->setModified(false); + + updateControls(); + setDocumentModified(); + } + catch (Exception&) + { + TOOLS_WARN_EXCEPTION( "sd", "TableDesignWidget::ResetStyle()"); + } +} + +void TableDesignWidget::DeleteStyle() +{ + try + { + Reference xTableStyle(mxTableFamily->getByIndex(m_xValueSet->GetSelectedItemId() - 1), UNO_QUERY_THROW); + + if (xTableStyle->isInUse()) + { + std::unique_ptr xBox(Application::CreateMessageDialog( + m_xValueSet->GetDrawingArea(), VclMessageType::Question, VclButtonsType::YesNo, SdResId(STR_REMOVE_TABLESTYLE))); + + if (xBox->run() != RET_YES) + return; + } + + Reference(mxTableFamily, UNO_QUERY_THROW)->removeByName(xTableStyle->getName()); + + updateControls(); + setDocumentModified(); + } + catch (Exception&) + { + TOOLS_WARN_EXCEPTION( "sd", "TableDesignWidget::DeleteStyle()"); + } +} + +void TableDesignWidget::EditStyle(std::string_view rCommand) +{ + try + { + Reference xTableStyle(mxTableFamily->getByIndex(m_xValueSet->GetSelectedItemId() - 1), UNO_QUERY_THROW); + Reference xCellStyle(xTableStyle->getByName(OUString::fromUtf8(rCommand)), UNO_QUERY_THROW); + + bool bUserDefined = xCellStyle->isUserDefined(); + if (!bUserDefined) + { + Reference xFactory(mxCellFamily, UNO_QUERY_THROW); + Reference xNewStyle(xFactory->createInstance(), UNO_QUERY_THROW); + xNewStyle->setParentStyle(xCellStyle->getName()); + xCellStyle = xNewStyle; + } + + rtl::Reference xStyleSheet = static_cast(xCellStyle.get()); + SfxItemSet aNewAttr(xStyleSheet->GetItemSet()); + + // merge drawing layer text distance items into SvxBoxItem used by the dialog + SvxBoxItem aBoxItem(sdr::table::SvxTableController::TextDistancesToSvxBoxItem(aNewAttr)); + aNewAttr.Put(aBoxItem); + + // inner borders do not apply to a cell style + SvxBoxInfoItem aBoxInfoItem(aNewAttr.Get(SDRATTR_TABLE_BORDER_INNER)); + aBoxInfoItem.SetTable(false); + aNewAttr.Put(aBoxInfoItem); + + SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); + ScopedVclPtr pDlg(pFact ? pFact->CreateSvxFormatCellsDialog( + mrBase.GetFrameWeld(), &aNewAttr, *mrBase.GetDrawView()->GetModel(), true) : nullptr); + if (pDlg && pDlg->Execute() == RET_OK) + { + if (!bUserDefined) + { + mxCellFamily->insertByName(xCellStyle->getName(), Any(xCellStyle)); + xTableStyle->replaceByName(OUString::fromUtf8(rCommand), Any(xCellStyle)); + } + + SfxItemSet aNewSet(*pDlg->GetOutputItemSet()); + sdr::table::SvxTableController::SvxBoxItemToTextDistances(aBoxItem, aNewSet); + sdr::properties::CleanupFillProperties(aNewSet); + xStyleSheet->GetItemSet().Put(aNewSet); + xStyleSheet->Broadcast(SfxHint(SfxHintId::DataChanged)); + + updateControls(); + setDocumentModified(); + } + } + catch (Exception&) + { + TOOLS_WARN_EXCEPTION( "sd", "TableDesignWidget::EditStyle()"); + } +} + static SfxBindings* getBindings( ViewShellBase const & rBase ) { if( rBase.GetMainViewShell() && rBase.GetMainViewShell()->GetViewFrame() ) @@ -162,6 +432,11 @@ void TableDesignWidget::ApplyStyle() Reference< XNameAccess > xNames( mxTableFamily, UNO_QUERY_THROW ); sStyleName = xNames->getElementNames()[nIndex]; } + else if (nIndex == mxTableFamily->getCount()) + { + InsertStyle(); + return; + } if( sStyleName.isEmpty() ) return; @@ -281,6 +556,15 @@ void TableDesignWidget::onSelectionChanged() } } +bool TableValueSet::Command(const CommandEvent& rEvent) +{ + if (rEvent.GetCommand() != CommandEventId::ContextMenu) + return ValueSet::Command(rEvent); + + maContextMenuHandler.Call(rEvent.IsMouseEvent() ? &rEvent.GetMousePosPixel() : nullptr); + return true; +} + void TableValueSet::Resize() { ValueSet::Resize(); @@ -302,10 +586,10 @@ void TableValueSet::Resize() if (nRowCount < 1) nRowCount = 1; - int nVisibleRowCount = (aValueSetSize.Height()+2) / aItemSize.Height(); + int nVisibleRowCount = std::min(nRowCount, getMaxRowCount()); SetColCount (static_cast(nColumnCount)); - SetLineCount (static_cast(nRowCount)); + SetLineCount (static_cast(nVisibleRowCount)); if( !m_bModal ) { @@ -364,25 +648,24 @@ void TableDesignWidget::updateControls() m_xValueSet->updateSettings(); m_xValueSet->Resize(); - sal_uInt16 nSelection = 0; if( mxSelectedTable.is() ) { Reference< XNamed > xNamed( mxSelectedTable->getPropertyValue( "TableTemplate" ), UNO_QUERY ); if( xNamed.is() ) - { - const OUString sStyleName( xNamed->getName() ); + selectStyle(xNamed->getName()); + } +} - Reference< XNameAccess > xNames( mxTableFamily, UNO_QUERY ); - if( xNames.is() ) - { - Sequence< OUString > aNames( xNames->getElementNames() ); - sal_Int32 nIndex = comphelper::findValue(aNames, sStyleName); - if (nIndex != -1) - nSelection = static_cast(nIndex) + 1; - } - } +void TableDesignWidget::selectStyle(std::u16string_view rStyle) +{ + Reference< XNameAccess > xNames( mxTableFamily, UNO_QUERY ); + if( xNames.is() ) + { + Sequence< OUString > aNames( xNames->getElementNames() ); + sal_Int32 nIndex = comphelper::findValue(aNames, rStyle); + if (nIndex != -1) + m_xValueSet->SelectItem(static_cast(nIndex) + 1); } - m_xValueSet->SelectItem( nSelection ); } void TableDesignWidget::addListener() @@ -735,8 +1018,10 @@ void TableDesignWidget::FillDesignPreviewControl() { TOOLS_WARN_EXCEPTION( "sd", "sd::TableDesignWidget::FillDesignPreviewControl()"); } + m_xValueSet->InsertItem(++nCount, Image(StockImage::Yes, BMP_INSERT_TABLESTYLE), SdResId(STR_INSERT_TABLESTYLE)); + sal_Int32 nCols = 3; - sal_Int32 nRows = (nCount+2)/3; + sal_Int32 nRows = std::min((nCount+2)/3, TableValueSet::getMaxRowCount()); m_xValueSet->SetColCount(nCols); m_xValueSet->SetLineCount(nRows); WinBits nStyle = m_xValueSet->GetStyle() & ~WB_VSCROLL; diff --git a/sd/uiconfig/simpress/ui/tabledesignpanel.ui b/sd/uiconfig/simpress/ui/tabledesignpanel.ui index 0c3ec5e403e0..c820774d1bec 100644 --- a/sd/uiconfig/simpress/ui/tabledesignpanel.ui +++ b/sd/uiconfig/simpress/ui/tabledesignpanel.ui @@ -142,4 +142,122 @@ + + True + False + + + True + False + New + True + + + + + True + False + Clone + True + + + + + True + False + Delete + True + + + + + True + False + Reset + True + + + + + True + False + Format + True + + + True + False + + + True + False + Header row... + True + + + + + True + False + Total row... + True + + + + + True + False + Banded rows... + True + + + + + True + False + + + + + True + False + First column... + True + + + + + True + False + Last column... + True + + + + + True + False + Banded columns... + True + + + + + True + False + + + + + True + False + Other cells... + True + + + + + + + diff --git a/svx/source/table/tablecontroller.cxx b/svx/source/table/tablecontroller.cxx index 9b3d8687a855..84b6bd93f674 100644 --- a/svx/source/table/tablecontroller.cxx +++ b/svx/source/table/tablecontroller.cxx @@ -890,18 +890,34 @@ void SvxTableController::onSelect( sal_uInt16 nSId ) gotoCell( aStart, true, nullptr ); } -namespace +SvxBoxItem SvxTableController::TextDistancesToSvxBoxItem(const SfxItemSet& rAttrSet) { - SvxBoxItem mergeDrawinglayerTextDistancesAndSvxBoxItem(const SfxItemSet& rAttrSet) - { - // merge drawing layer text distance items into SvxBoxItem used by the dialog - SvxBoxItem aBoxItem( rAttrSet.Get( SDRATTR_TABLE_BORDER ) ); - aBoxItem.SetDistance( sal::static_int_cast< sal_uInt16 >( rAttrSet.Get(SDRATTR_TEXT_LEFTDIST).GetValue()), SvxBoxItemLine::LEFT ); - aBoxItem.SetDistance( sal::static_int_cast< sal_uInt16 >( rAttrSet.Get(SDRATTR_TEXT_RIGHTDIST).GetValue()), SvxBoxItemLine::RIGHT ); - aBoxItem.SetDistance( sal::static_int_cast< sal_uInt16 >( rAttrSet.Get(SDRATTR_TEXT_UPPERDIST).GetValue()), SvxBoxItemLine::TOP ); - aBoxItem.SetDistance( sal::static_int_cast< sal_uInt16 >( rAttrSet.Get(SDRATTR_TEXT_LOWERDIST).GetValue()), SvxBoxItemLine::BOTTOM ); - return aBoxItem; - } + // merge drawing layer text distance items into SvxBoxItem used by the dialog + SvxBoxItem aBoxItem( rAttrSet.Get( SDRATTR_TABLE_BORDER ) ); + aBoxItem.SetDistance( sal::static_int_cast< sal_uInt16 >( rAttrSet.Get(SDRATTR_TEXT_LEFTDIST).GetValue()), SvxBoxItemLine::LEFT ); + aBoxItem.SetDistance( sal::static_int_cast< sal_uInt16 >( rAttrSet.Get(SDRATTR_TEXT_RIGHTDIST).GetValue()), SvxBoxItemLine::RIGHT ); + aBoxItem.SetDistance( sal::static_int_cast< sal_uInt16 >( rAttrSet.Get(SDRATTR_TEXT_UPPERDIST).GetValue()), SvxBoxItemLine::TOP ); + aBoxItem.SetDistance( sal::static_int_cast< sal_uInt16 >( rAttrSet.Get(SDRATTR_TEXT_LOWERDIST).GetValue()), SvxBoxItemLine::BOTTOM ); + return aBoxItem; +} + +void SvxTableController::SvxBoxItemToTextDistances(const SvxBoxItem& pOriginalItem, SfxItemSet& rAttrSet) +{ + const SvxBoxItem* pNewItem( rAttrSet.GetItemIfSet( SDRATTR_TABLE_BORDER ) ); + if ( !pNewItem ) + return; + + if( pNewItem->GetDistance( SvxBoxItemLine::LEFT ) != pOriginalItem.GetDistance( SvxBoxItemLine::LEFT ) ) + rAttrSet.Put(makeSdrTextLeftDistItem( pNewItem->GetDistance( SvxBoxItemLine::LEFT ) ) ); + + if( pNewItem->GetDistance( SvxBoxItemLine::RIGHT ) != pOriginalItem.GetDistance( SvxBoxItemLine::RIGHT ) ) + rAttrSet.Put(makeSdrTextRightDistItem( pNewItem->GetDistance( SvxBoxItemLine::RIGHT ) ) ); + + if( pNewItem->GetDistance( SvxBoxItemLine::TOP ) != pOriginalItem.GetDistance( SvxBoxItemLine::TOP ) ) + rAttrSet.Put(makeSdrTextUpperDistItem( pNewItem->GetDistance( SvxBoxItemLine::TOP ) ) ); + + if( pNewItem->GetDistance( SvxBoxItemLine::BOTTOM ) != pOriginalItem.GetDistance( SvxBoxItemLine::BOTTOM ) ) + rAttrSet.Put(makeSdrTextLowerDistItem( pNewItem->GetDistance( SvxBoxItemLine::BOTTOM ) ) ); } void SvxTableController::onFormatTable(const SfxRequest& rReq) @@ -919,7 +935,7 @@ void SvxTableController::onFormatTable(const SfxRequest& rReq) SfxItemSet aNewAttr(rModel.GetItemPool()); // merge drawing layer text distance items into SvxBoxItem used by the dialog - SvxBoxItem aBoxItem(mergeDrawinglayerTextDistancesAndSvxBoxItem(aNewAttr)); + SvxBoxItem aBoxItem(TextDistancesToSvxBoxItem(aNewAttr)); SvxBoxInfoItem aBoxInfoItem( aNewAttr.Get( SDRATTR_TABLE_BORDER_INNER ) ); @@ -966,19 +982,7 @@ void SvxTableController::onFormatTable(const SfxRequest& rReq) aNewSet.Put(aBoxInfoItem); } - SvxBoxItem aNewBoxItem( aNewSet.Get( SDRATTR_TABLE_BORDER ) ); - - if( aNewBoxItem.GetDistance( SvxBoxItemLine::LEFT ) != aBoxItem.GetDistance( SvxBoxItemLine::LEFT ) ) - aNewSet.Put(makeSdrTextLeftDistItem( aNewBoxItem.GetDistance( SvxBoxItemLine::LEFT ) ) ); - - if( aNewBoxItem.GetDistance( SvxBoxItemLine::RIGHT ) != aBoxItem.GetDistance( SvxBoxItemLine::RIGHT ) ) - aNewSet.Put(makeSdrTextRightDistItem( aNewBoxItem.GetDistance( SvxBoxItemLine::RIGHT ) ) ); - - if( aNewBoxItem.GetDistance( SvxBoxItemLine::TOP ) != aBoxItem.GetDistance( SvxBoxItemLine::TOP ) ) - aNewSet.Put(makeSdrTextUpperDistItem( aNewBoxItem.GetDistance( SvxBoxItemLine::TOP ) ) ); - - if( aNewBoxItem.GetDistance( SvxBoxItemLine::BOTTOM ) != aBoxItem.GetDistance( SvxBoxItemLine::BOTTOM ) ) - aNewSet.Put(makeSdrTextLowerDistItem( aNewBoxItem.GetDistance( SvxBoxItemLine::BOTTOM ) ) ); + SvxBoxItemToTextDistances(aBoxItem, aNewSet); if (checkTableObject() && mxTable.is()) { @@ -3210,7 +3214,7 @@ void SvxTableController::FillCommonBorderAttrFromSelectedCells( SvxBoxItem& rBox nCellPosFlags |= (nCol > aEnd.mnCol) ? CellPosFlag::After : CellPosFlag::NONE; const SfxItemSet& rSet = xCell->GetItemSet(); - SvxBoxItem aCellBoxItem(mergeDrawinglayerTextDistancesAndSvxBoxItem(rSet)); + SvxBoxItem aCellBoxItem(TextDistancesToSvxBoxItem(rSet)); lcl_MergeCommonBorderAttr( aLinesState, aCellBoxItem, nCellPosFlags ); } } diff --git a/svx/source/table/tabledesign.cxx b/svx/source/table/tabledesign.cxx index d4fe8cda4460..7c097199f9e9 100644 --- a/svx/source/table/tabledesign.cxx +++ b/svx/source/table/tabledesign.cxx @@ -23,10 +23,10 @@ #include #include #include -#include +#include #include #include -#include +#include #include #include @@ -60,7 +60,7 @@ namespace sdr::table { typedef std::map< OUString, sal_Int32 > CellStyleNameMap; -typedef ::comphelper::WeakComponentImplHelper< XStyle, XNameReplace, XServiceInfo, XIndexAccess, XModifyBroadcaster, XModifyListener, XPropertySet > TableDesignStyleBase; +typedef ::comphelper::WeakComponentImplHelper< XStyle, XNameReplace, XServiceInfo, XIndexReplace, XModifiable, XModifyListener, XPropertySet > TableDesignStyleBase; namespace { @@ -97,6 +97,9 @@ public: virtual sal_Int32 SAL_CALL getCount() override ; virtual Any SAL_CALL getByIndex( sal_Int32 Index ) override; + // XIndexReplace + virtual void SAL_CALL replaceByIndex( sal_Int32 Index, const Any& Element ) override; + // XNameReplace virtual void SAL_CALL replaceByName( const OUString& aName, const Any& aElement ) override; @@ -109,6 +112,10 @@ public: virtual void SAL_CALL addVetoableChangeListener(const OUString& PropertyName, const Reference& aListener ) override; virtual void SAL_CALL removeVetoableChangeListener(const OUString& PropertyName,const Reference&aListener ) override; + // XModifiable + virtual sal_Bool SAL_CALL isModified() override; + virtual void SAL_CALL setModified( sal_Bool bModified ) override; + // XModifyBroadcaster virtual void SAL_CALL addModifyListener( const Reference< XModifyListener >& aListener ) override; virtual void SAL_CALL removeModifyListener( const Reference< XModifyListener >& aListener ) override; @@ -356,6 +363,21 @@ Any SAL_CALL TableDesignStyle::getByIndex( sal_Int32 Index ) } +// XIndexReplace + +void SAL_CALL TableDesignStyle::replaceByIndex( sal_Int32 Index, const Any& aElement ) +{ + if( (Index < 0) || (Index >= style_count) ) + throw IndexOutOfBoundsException(); + + const CellStyleNameMap& rMap = getCellStyleNameMap(); + auto iter = std::find_if(rMap.begin(), rMap.end(), + [&Index](const auto& item) { return Index == item.second; }); + if (iter != rMap.end()) + replaceByName(iter->first, aElement); +} + + // XNameReplace @@ -450,6 +472,19 @@ void TableDesignStyle::removeVetoableChangeListener( const OUString&,const Refer { } +// XModifiable + +sal_Bool TableDesignStyle::isModified() +{ + return mbModified; +} + +void TableDesignStyle::setModified( sal_Bool bModified ) +{ + mbModified = bModified; + notifyModifyListener(); +} + // XModifyBroadcaster -- cgit v1.2.3