diff options
author | Maxim Monastirsky <momonasmon@gmail.com> | 2022-11-13 14:50:08 +0200 |
---|---|---|
committer | Maxim Monastirsky <momonasmon@gmail.com> | 2022-11-21 14:39:14 +0100 |
commit | f23d3661ab04601650db95f846081317fc06801d (patch) | |
tree | 24d08b3b1ef2e854cc6ad7469ba9a2ce0ea55ced | |
parent | 5d683e8f6c9e677d7b6bc829a4ce9ee384f4fbd8 (diff) |
sd: table design editing
Change-Id: I75559c80da015a13ee078bdda06f6f4975fe5946
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140943
Tested-by: Jenkins
Reviewed-by: Maxim Monastirsky <momonasmon@gmail.com>
-rw-r--r-- | icon-themes/colibre/sd/res/addtablestyle.png | bin | 0 -> 663 bytes | |||
-rw-r--r-- | include/svx/sdr/table/tablecontroller.hxx | 3 | ||||
-rw-r--r-- | sd/inc/bitmaps.hlst | 1 | ||||
-rw-r--r-- | sd/inc/strings.hrc | 2 | ||||
-rw-r--r-- | sd/source/ui/inc/TableDesignPane.hxx | 16 | ||||
-rw-r--r-- | sd/source/ui/table/TableDesignPane.cxx | 317 | ||||
-rw-r--r-- | sd/uiconfig/simpress/ui/tabledesignpanel.ui | 118 | ||||
-rw-r--r-- | svx/source/table/tablecontroller.cxx | 56 | ||||
-rw-r--r-- | svx/source/table/tabledesign.cxx | 41 |
9 files changed, 508 insertions, 46 deletions
diff --git a/icon-themes/colibre/sd/res/addtablestyle.png b/icon-themes/colibre/sd/res/addtablestyle.png Binary files differnew file mode 100644 index 000000000000..8e4422cb733f --- /dev/null +++ b/icon-themes/colibre/sd/res/addtablestyle.png 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 <vcl/weld.hxx> 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<const Point*, void> maContextMenuHandler; public: TableValueSet(std::unique_ptr<weld::ScrolledWindow> 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<const Point*, void>& 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<weld::Menu> m_xMenu; std::unique_ptr<TableValueSet> m_xValueSet; std::unique_ptr<weld::CustomWeld> m_xValueSetWin; std::unique_ptr<weld::CheckButton> 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 <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/drawing/XDrawView.hpp> #include <com/sun/star/frame/XController.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/util/XModifiable.hpp> #include <com/sun/star/view/XSelectionSupplier.hpp> #include <com/sun/star/style/XStyle.hpp> #include <com/sun/star/style/XStyleFamiliesSupplier.hpp> #include <comphelper/sequence.hxx> #include <sfx2/viewfrm.hxx> +#include <vcl/commandevent.hxx> #include <vcl/image.hxx> #include <vcl/settings.hxx> +#include <vcl/svapp.hxx> #include <vcl/virdev.hxx> #include <tools/debug.hxx> @@ -44,15 +48,21 @@ #include <sfx2/dispatch.hxx> #include <svx/svxids.hrc> #include <svx/svdetc.hxx> +#include <svx/svxdlg.hxx> #include <editeng/boxitem.hxx> #include <editeng/borderline.hxx> #include <editeng/colritem.hxx> #include <editeng/eeitem.hxx> #include <svx/sdr/table/tabledesign.hxx> +#include <svx/sdr/table/tablecontroller.hxx> #include <o3tl/enumrange.hxx> #include <TableDesignPane.hxx> +#include <stlsheet.hxx> +#include <strings.hrc> +#include <sdresid.hxx> +#include <bitmaps.hlst> #include <ViewShell.hxx> #include <ViewShellBase.hxx> #include <EventMultiplexer.hxx> @@ -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> xController(mrBase.GetController(), UNO_SET_THROW); + Reference<util::XModifiable> 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> 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<util::XModifiable>(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<XNameContainer>& rTableFamily) + { + OUString aName; + sal_Int32 nIndex = 1; + do + { + aName = "table" + OUString::number(nIndex++); + } + while(rTableFamily->hasByName(aName)); + + return aName; + } +} + +void TableDesignWidget::InsertStyle() +{ + try + { + Reference<XSingleServiceFactory> xFactory(mxTableFamily, UNO_QUERY_THROW); + Reference<XNameContainer> xTableFamily(mxTableFamily, UNO_QUERY_THROW); + Reference<XNameReplace> xTableStyle(xFactory->createInstance(), UNO_QUERY_THROW); + const OUString aName(getNewValidTableStyleName(xTableFamily)); + xTableFamily->insertByName(aName, Any(xTableStyle)); + + Reference<XStyle> 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<XIndexAccess> xSrcTableStyle(mxTableFamily->getByIndex(m_xValueSet->GetSelectedItemId() - 1), UNO_QUERY_THROW); + + Reference<XSingleServiceFactory> xFactory(mxTableFamily, UNO_QUERY_THROW); + Reference<XNameContainer> xTableFamily(mxTableFamily, UNO_QUERY_THROW); + Reference<XIndexReplace> 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<XStyle> xSrcCellStyle(xSrcTableStyle->getByIndex(i), UNO_QUERY); + if (xSrcCellStyle && xSrcCellStyle->isUserDefined()) + { + Reference<XSingleServiceFactory> xCellFactory(mxCellFamily, UNO_QUERY_THROW); + Reference<XStyle> xDestCellStyle(xCellFactory->createInstance(), UNO_QUERY_THROW); + xDestCellStyle->setParentStyle(xSrcCellStyle->getParentStyle()); + mxCellFamily->insertByName(xDestCellStyle->getName(), Any(xDestCellStyle)); + + rtl::Reference xSrcStyleSheet = static_cast<SdStyleSheet*>(xSrcCellStyle.get()); + rtl::Reference xDestStyleSheet = static_cast<SdStyleSheet*>(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<XIndexReplace> xTableStyle(mxTableFamily->getByIndex(m_xValueSet->GetSelectedItemId() - 1), UNO_QUERY_THROW); + + for (sal_Int32 i = 0; i < xTableStyle->getCount(); ++i) + { + Reference<XStyle> xCellStyle(xTableStyle->getByIndex(i), UNO_QUERY); + if (xCellStyle && xCellStyle->isUserDefined()) + xTableStyle->replaceByIndex(i, mxCellFamily->getByName(xCellStyle->getParentStyle())); + } + + Reference<util::XModifiable>(xTableStyle, UNO_QUERY_THROW)->setModified(false); + + updateControls(); + setDocumentModified(); + } + catch (Exception&) + { + TOOLS_WARN_EXCEPTION( "sd", "TableDesignWidget::ResetStyle()"); + } +} + +void TableDesignWidget::DeleteStyle() +{ + try + { + Reference<XStyle> xTableStyle(mxTableFamily->getByIndex(m_xValueSet->GetSelectedItemId() - 1), UNO_QUERY_THROW); + + if (xTableStyle->isInUse()) + { + std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog( + m_xValueSet->GetDrawingArea(), VclMessageType::Question, VclButtonsType::YesNo, SdResId(STR_REMOVE_TABLESTYLE))); + + if (xBox->run() != RET_YES) + return; + } + + Reference<XNameContainer>(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<XNameReplace> xTableStyle(mxTableFamily->getByIndex(m_xValueSet->GetSelectedItemId() - 1), UNO_QUERY_THROW); + Reference<XStyle> xCellStyle(xTableStyle->getByName(OUString::fromUtf8(rCommand)), UNO_QUERY_THROW); + + bool bUserDefined = xCellStyle->isUserDefined(); + if (!bUserDefined) + { + Reference<XSingleServiceFactory> xFactory(mxCellFamily, UNO_QUERY_THROW); + Reference<XStyle> xNewStyle(xFactory->createInstance(), UNO_QUERY_THROW); + xNewStyle->setParentStyle(xCellStyle->getName()); + xCellStyle = xNewStyle; + } + + rtl::Reference xStyleSheet = static_cast<SdStyleSheet*>(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<SfxAbstractTabDialog> 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<sal_uInt16>(nColumnCount)); - SetLineCount (static_cast<sal_uInt16>(nRowCount)); + SetLineCount (static_cast<sal_uInt16>(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<sal_uInt16>(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<sal_uInt16>(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<sal_Int32>((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 @@ </packing> </child> </object> + <object class="GtkMenu" id="menu"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <child> + <object class="GtkMenuItem" id="new"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="tabledesignpanel|menunew">New</property> + <property name="use-underline">True</property> + </object> + </child> + <child> + <object class="GtkMenuItem" id="clone"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="tabledesignpanel|menuclone">Clone</property> + <property name="use-underline">True</property> + </object> + </child> + <child> + <object class="GtkMenuItem" id="delete"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="tabledesignpanel|menudelete">Delete</property> + <property name="use-underline">True</property> + </object> + </child> + <child> + <object class="GtkMenuItem" id="reset"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="tabledesignpanel|menureset">Reset</property> + <property name="use-underline">True</property> + </object> + </child> + <child> + <object class="GtkMenuItem" id="format"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="tabledesignpanel|menuformat">Format</property> + <property name="use-underline">True</property> + <child type="submenu"> + <object class="GtkMenu"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <child> + <object class="GtkMenuItem" id="first-row"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="tabledesignpanel|menufirstrow">Header row...</property> + <property name="use-underline">True</property> + </object> + </child> + <child> + <object class="GtkMenuItem" id="last-row"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="tabledesignpanel|menulastrow">Total row...</property> + <property name="use-underline">True</property> + </object> + </child> + <child> + <object class="GtkMenuItem" id="odd-rows"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="tabledesignpanel|menuoddrows">Banded rows...</property> + <property name="use-underline">True</property> + </object> + </child> + <child> + <object class="GtkSeparatorMenuItem"> + <property name="visible">True</property> + <property name="can-focus">False</property> + </object> + </child> + <child> + <object class="GtkMenuItem" id="first-column"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="tabledesignpanel|menufirstcolumn">First column...</property> + <property name="use-underline">True</property> + </object> + </child> + <child> + <object class="GtkMenuItem" id="last-column"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="tabledesignpanel|menulastcolumn">Last column...</property> + <property name="use-underline">True</property> + </object> + </child> + <child> + <object class="GtkMenuItem" id="odd-columns"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="tabledesignpanel|menuoddcolumns">Banded columns...</property> + <property name="use-underline">True</property> + </object> + </child> + <child> + <object class="GtkSeparatorMenuItem"> + <property name="visible">True</property> + <property name="can-focus">False</property> + </object> + </child> + <child> + <object class="GtkMenuItem" id="body"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="tabledesignpanel|menubody">Other cells...</property> + <property name="use-underline">True</property> + </object> + </child> + </object> + </child> + </object> + </child> + </object> </interface> 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 <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/lang/XComponent.hpp> #include <com/sun/star/lang/XSingleServiceFactory.hpp> -#include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/container/XIndexReplace.hpp> #include <com/sun/star/container/XNameContainer.hpp> #include <com/sun/star/beans/XPropertySet.hpp> -#include <com/sun/star/util/XModifyBroadcaster.hpp> +#include <com/sun/star/util/XModifiable.hpp> #include <com/sun/star/util/XModifyListener.hpp> #include <com/sun/star/form/XReset.hpp> @@ -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<XVetoableChangeListener>& aListener ) override; virtual void SAL_CALL removeVetoableChangeListener(const OUString& PropertyName,const Reference<XVetoableChangeListener>&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 |