summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxim Monastirsky <momonasmon@gmail.com>2022-11-13 14:50:08 +0200
committerMaxim Monastirsky <momonasmon@gmail.com>2022-11-21 14:39:14 +0100
commitf23d3661ab04601650db95f846081317fc06801d (patch)
tree24d08b3b1ef2e854cc6ad7469ba9a2ce0ea55ced
parent5d683e8f6c9e677d7b6bc829a4ce9ee384f4fbd8 (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.pngbin0 -> 663 bytes
-rw-r--r--include/svx/sdr/table/tablecontroller.hxx3
-rw-r--r--sd/inc/bitmaps.hlst1
-rw-r--r--sd/inc/strings.hrc2
-rw-r--r--sd/source/ui/inc/TableDesignPane.hxx16
-rw-r--r--sd/source/ui/table/TableDesignPane.cxx317
-rw-r--r--sd/uiconfig/simpress/ui/tabledesignpanel.ui118
-rw-r--r--svx/source/table/tablecontroller.cxx56
-rw-r--r--svx/source/table/tabledesign.cxx41
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
new file mode 100644
index 000000000000..8e4422cb733f
--- /dev/null
+++ b/icon-themes/colibre/sd/res/addtablestyle.png
Binary files 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 <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