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>
This commit is contained in:
Maxim Monastirsky 2022-11-13 14:50:08 +02:00
parent 5d683e8f6c
commit f23d3661ab
9 changed files with 509 additions and 47 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 663 B

View file

@ -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);

View file

@ -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";

View file

@ -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: */

View file

@ -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

View file

@ -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() );
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;
}
}
selectStyle(xNamed->getName());
}
}
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;

View file

@ -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>

View file

@ -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 );
}
}

View file

@ -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