summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Le Grand <Armin.Le.Grand@cib.de>2018-05-08 14:07:17 +0200
committerArmin Le Grand <Armin.Le.Grand@cib.de>2018-05-09 17:41:12 +0200
commit015dd48ce60e64de517cb56a5ced89dd4feb4198 (patch)
tree09b9e60e2e2172e632774c47ca44b029c89cfe2d
parent1887806c401e3f2d522f500c9b83bdd452030c49 (diff)
tdf#116977 Correctly handle copy-construct of SdrTableObj
The new central CloneSdrObject in the case of SdrTableObj has to do some more stuff due to the UNO API TableModel in- volved and stuff. This is done in ::operator= now and thus will work uniformly now (multi-select and copy). At the same time there is functionality to clone/copy only a partial Table in Draw/Impress when e.g some Cells are selected. To reflect this code is needed to 'crop' the just cloned SdrTableObj to the current selection. This again was pretty hard due to side-effects in the implementation using a mix of UNO API and SdrModel-stuff. Change-Id: I9816e1caf34e29021d46d6dd9bb935c634f5ba2e Reviewed-on: https://gerrit.libreoffice.org/53975 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
-rw-r--r--include/svx/sdr/table/tablecontroller.hxx2
-rw-r--r--include/svx/selectioncontroller.hxx3
-rw-r--r--include/svx/svdotable.hxx7
-rw-r--r--svx/source/svdraw/selectioncontroller.cxx4
-rw-r--r--svx/source/svdraw/svdotext.cxx13
-rw-r--r--svx/source/svdraw/svdxcgv.cxx70
-rw-r--r--svx/source/table/svdotable.cxx263
-rw-r--r--svx/source/table/tablecontroller.cxx45
8 files changed, 245 insertions, 162 deletions
diff --git a/include/svx/sdr/table/tablecontroller.hxx b/include/svx/sdr/table/tablecontroller.hxx
index b16b5f30f0b2..3a8ec322aaeb 100644
--- a/include/svx/sdr/table/tablecontroller.hxx
+++ b/include/svx/sdr/table/tablecontroller.hxx
@@ -96,7 +96,7 @@ public:
SVX_DLLPRIVATE virtual bool GetAttributes(SfxItemSet& rTargetSet, bool bOnlyHardAttr) const override;
SVX_DLLPRIVATE virtual bool SetAttributes(const SfxItemSet& rSet, bool bReplaceAll) override;
- SVX_DLLPRIVATE virtual bool GetMarkedObjModel( SdrPage* pNewPage ) override;
+ SVX_DLLPRIVATE virtual SdrObject* GetMarkedSdrObjClone( SdrModel& rTargetModel ) override;
SVX_DLLPRIVATE virtual bool PasteObjModel( const SdrModel& rModel ) override;
SVX_DLLPRIVATE virtual bool hasSelectedCells() const override { return mbCellSelectionMode || mrView.IsTextEdit(); }
diff --git a/include/svx/selectioncontroller.hxx b/include/svx/selectioncontroller.hxx
index 9df053e9f5bc..11acdac3cd59 100644
--- a/include/svx/selectioncontroller.hxx
+++ b/include/svx/selectioncontroller.hxx
@@ -34,6 +34,7 @@ class SdrPage;
class SdrModel;
class Point;
class FontList;
+class SdrObject;
namespace sdr
{
@@ -61,7 +62,7 @@ public:
virtual bool GetStyleSheet( SfxStyleSheet* &rpStyleSheet ) const;
virtual bool SetStyleSheet( SfxStyleSheet* pStyleSheet, bool bDontRemoveHardAttr );
- virtual bool GetMarkedObjModel( SdrPage* pNewPage );
+ virtual SdrObject* GetMarkedSdrObjClone( SdrModel& rTargetModel );
virtual bool PasteObjModel( const SdrModel& rModel );
/** returns a format paint brush set from the current selection */
diff --git a/include/svx/svdotable.hxx b/include/svx/svdotable.hxx
index 12e27379f5ff..1119c8c9fc59 100644
--- a/include/svx/svdotable.hxx
+++ b/include/svx/svdotable.hxx
@@ -109,11 +109,10 @@ public:
sal_Int32 nColumns,
sal_Int32 nRows);
+ // helper to limit existing TableModel to a given selection
+ void CropTableModelToSelection(const CellPos& rStart, const CellPos& rEnd);
+
// Table stuff
- SdrTableObj* CloneRange(
- const CellPos& rStartPos,
- const CellPos& rEndPos,
- SdrModel& rTargetModel);
void DistributeColumns( sal_Int32 nFirstColumn, sal_Int32 nLastColumn );
void DistributeRows( sal_Int32 nFirstRow, sal_Int32 nLastRow );
diff --git a/svx/source/svdraw/selectioncontroller.cxx b/svx/source/svdraw/selectioncontroller.cxx
index 883836d69610..8cb678d66467 100644
--- a/svx/source/svdraw/selectioncontroller.cxx
+++ b/svx/source/svdraw/selectioncontroller.cxx
@@ -80,9 +80,9 @@ bool SelectionController::SetStyleSheet( SfxStyleSheet* /*pStyleSheet*/, bool /*
return false;
}
-bool SelectionController::GetMarkedObjModel( SdrPage* /*pNewPage*/ )
+SdrObject* SelectionController::GetMarkedSdrObjClone( SdrModel& /*rTargetModel*/ )
{
- return false;
+ return nullptr;
}
bool SelectionController::PasteObjModel( const SdrModel& /*rModel*/ )
diff --git a/svx/source/svdraw/svdotext.cxx b/svx/source/svdraw/svdotext.cxx
index e89dfff7eeb3..18673a5f0914 100644
--- a/svx/source/svdraw/svdotext.cxx
+++ b/svx/source/svdraw/svdotext.cxx
@@ -1033,14 +1033,18 @@ SdrTextObj& SdrTextObj::operator=(const SdrTextObj& rObj)
bNoShear = rObj.bNoShear;
bNoMirror = rObj.bNoMirror;
bDisableAutoWidthOnDragging = rObj.bDisableAutoWidthOnDragging;
-
- OutlinerParaObject* pNewOutlinerParaObject = nullptr;
-
SdrText* pText = getActiveText();
if( pText && rObj.HasText() )
{
+ // before pNewOutlinerParaObject was created the same, but
+ // set at mpText (outside this scope), but mpText might be
+ // empty (this operator== seems not prepared for MultiText
+ // objects). In the current form it makes only sense to
+ // create locally and use locally on a known existing SdrText
const Outliner* pEO=rObj.pEdtOutl;
+ OutlinerParaObject* pNewOutlinerParaObject = nullptr;
+
if (pEO!=nullptr)
{
pNewOutlinerParaObject = pEO->CreateParaObject();
@@ -1049,9 +1053,10 @@ SdrTextObj& SdrTextObj::operator=(const SdrTextObj& rObj)
{
pNewOutlinerParaObject = new OutlinerParaObject(*rObj.getActiveText()->GetOutlinerParaObject());
}
+
+ pText->SetOutlinerParaObject( pNewOutlinerParaObject );
}
- mpText->SetOutlinerParaObject( pNewOutlinerParaObject );
ImpSetTextStyleSheetListeners();
return *this;
}
diff --git a/svx/source/svdraw/svdxcgv.cxx b/svx/source/svdraw/svdxcgv.cxx
index a92305d8ba8a..67ec4033ae96 100644
--- a/svx/source/svdraw/svdxcgv.cxx
+++ b/svx/source/svdraw/svdxcgv.cxx
@@ -54,6 +54,7 @@
#include <svx/sdr/contact/viewcontact.hxx>
#include <svx/sdr/contact/objectcontactofobjlistpainter.hxx>
#include <svx/sdr/contact/displayinfo.hxx>
+#include <svx/svdotable.hxx>
using namespace com::sun::star;
@@ -714,49 +715,58 @@ SdrModel* SdrExchangeView::GetMarkedObjModel() const
// Sorting the MarkList here might be problematic in the future, so
// use a copy.
SortMarkedObjects();
- SdrModel* pNewModel=mpModel->AllocModel();
- SdrPage* pnewPage=pNewModel->AllocPage(false);
- pNewModel->InsertPage(pnewPage);
+ SdrModel* pNewModel(mpModel->AllocModel());
+ SdrPage* pNewPage(pNewModel->AllocPage(false));
+ pNewModel->InsertPage(pNewPage);
+ ::std::vector< SdrObject* > aSdrObjects(GetMarkedObjects());
- if( !mxSelectionController.is() || !mxSelectionController->GetMarkedObjModel( pnewPage ) )
- {
- ::std::vector< SdrObject* > aSdrObjects(GetMarkedObjects());
+ // #i13033#
+ // New mechanism to re-create the connections of cloned connectors
+ CloneList aCloneList;
- // #i13033#
- // New mechanism to re-create the connections of cloned connectors
- CloneList aCloneList;
+ for(SdrObject* pObj : aSdrObjects)
+ {
+ SdrObject* pNewObj(nullptr);
- for(SdrObject* pObj : aSdrObjects)
+ if(nullptr != dynamic_cast< const SdrPageObj* >(pObj))
{
- SdrObject* pNewObj;
-
- if( dynamic_cast<const SdrPageObj*>( pObj) != nullptr )
- {
- // convert SdrPageObj's to a graphic representation, because
- // virtual connection to referenced page gets lost in new model
- pNewObj = new SdrGrafObj(
- *pNewModel,
- GetObjGraphic(*pObj),
- pObj->GetLogicRect());
- pNewObj->SetPage( pnewPage );
- }
- else
+ // convert SdrPageObj's to a graphic representation, because
+ // virtual connection to referenced page gets lost in new model
+ pNewObj = new SdrGrafObj(
+ *pNewModel,
+ GetObjGraphic(*pObj),
+ pObj->GetLogicRect());
+ }
+ else if(nullptr != dynamic_cast< const sdr::table::SdrTableObj* >(pObj))
+ {
+ // check if we have a valid selection *different* from whole table
+ // being selected
+ if(mxSelectionController.is())
{
- pNewObj = pObj->CloneSdrObject(*pNewModel);
- pNewObj->SetPage( pnewPage );
+ pNewObj = mxSelectionController->GetMarkedSdrObjClone(*pNewModel);
}
+ }
+
+ if(nullptr == pNewObj)
+ {
+ // not cloned yet, use default way
+ pNewObj = pObj->CloneSdrObject(*pNewModel);
+ }
- pnewPage->InsertObject(pNewObj, SAL_MAX_SIZE);
+ if(pNewObj)
+ {
+ pNewObj->SetPage(pNewPage);
+ pNewPage->InsertObject(pNewObj, SAL_MAX_SIZE);
// #i13033#
aCloneList.AddPair(pObj, pNewObj);
}
-
- // #i13033#
- // New mechanism to re-create the connections of cloned connectors
- aCloneList.CopyConnections();
}
+ // #i13033#
+ // New mechanism to re-create the connections of cloned connectors
+ aCloneList.CopyConnections();
+
return pNewModel;
}
diff --git a/svx/source/table/svdotable.cxx b/svx/source/table/svdotable.cxx
index 7e64ec8956a2..c1ea8b2f9daf 100644
--- a/svx/source/table/svdotable.cxx
+++ b/svx/source/table/svdotable.cxx
@@ -198,7 +198,7 @@ public:
std::vector<std::unique_ptr<SdrUndoAction>> maUndos;
bool mbSkipChangeLayout;
- void SetModel(SdrModel* pNewModelel);
+ void CropTableModelToSelection(const CellPos& rStart, const CellPos& rEnd);
CellRef getCell( const CellPos& rPos ) const;
void LayoutTable( tools::Rectangle& rArea, bool bFitWidth, bool bFitHeight );
@@ -270,6 +270,96 @@ SdrTableObjImpl::~SdrTableObjImpl()
}
+void SdrTableObjImpl::CropTableModelToSelection(const CellPos& rStart, const CellPos& rEnd)
+{
+ if(!mxTable.is())
+ {
+ return;
+ }
+
+ const sal_Int32 nColumns(rEnd.mnCol - rStart.mnCol + 1);
+ const sal_Int32 nRows(rEnd.mnRow - rStart.mnRow + 1);
+
+ if(nColumns < 1 || nRows < 1 || nColumns > getColumnCount() || nRows > getRowCount())
+ {
+ return;
+ }
+
+ // tdf#116977 First thought was to create the new TableModel, copy data to it and then exchange
+ // mxTable and dispose old one. This does *not* work, even when all stuff looks nicely referenced
+ // and safe *because* Cell::create gets handed over the current SdrTableObj, hands it to
+ // ::Cell and there the local mxTable is initialized using rTableObj.getTable() (!). Due to This,
+ // the new created Cells in a new created TableModel based on given mpTableObj *will be disposed*
+ // when the old mxTable gets disposed - ARGH!
+ // To avoid, change strategy: Remember old TableModel, reset mxTable immediately - this is the
+ // SdrTableObjImpl of the current SdrTableObj anyways. Luckily, this works as intended...
+
+ // remember old TableModel
+ TableModelRef xOldTable(mxTable);
+
+ // immediately create new one and initialize. This creates ::Cell's which then will use
+ // the correct TableModel (accessed through SdrTableObj, but using local mxTable)
+ mxTable = new TableModel(mpTableObj);
+ mxTable->init(nColumns, nRows);
+
+ // copy cells
+ for( sal_Int32 nRow = 0; nRow < nRows; ++nRow )
+ {
+ for( sal_Int32 nCol = 0; nCol < nColumns; ++nCol ) try
+ {
+ CellRef xTargetCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
+ if( xTargetCell.is() )
+ xTargetCell->cloneFrom( dynamic_cast< Cell* >( xOldTable->getCellByPosition( rStart.mnCol + nCol, rStart.mnRow + nRow ).get() ) );
+ }
+ catch( Exception& )
+ {
+ OSL_FAIL( "SdrTableObj::CropTableModelToSelection(), exception caught!" );
+ }
+ }
+
+ // copy row heights
+ Reference< XTableRows > xNewRows(mxTable->getRows(), UNO_QUERY_THROW );
+ const OUString sHeight( "Height" );
+ for( sal_Int32 nRow = 0; nRow < nRows; ++nRow )
+ {
+ Reference< XPropertySet > xNewSet( xNewRows->getByIndex( nRow ), UNO_QUERY_THROW );
+ xNewSet->setPropertyValue( sHeight, Any( mpLayouter->getRowHeight( rStart.mnRow + nRow ) ) );
+ }
+
+ // copy column widths
+ Reference< XTableColumns > xNewColumns( mxTable->getColumns(), UNO_QUERY_THROW );
+ const OUString sWidth( "Width" );
+ for( sal_Int32 nCol = 0; nCol < nColumns; ++nCol )
+ {
+ Reference< XPropertySet > xNewSet( xNewColumns->getByIndex( nCol ), UNO_QUERY_THROW );
+ xNewSet->setPropertyValue( sWidth, Any( mpLayouter->getColumnWidth( rStart.mnCol + nCol ) ) );
+ }
+
+ // reset layouter which still holds a copy to old TableModel
+ mpLayouter.reset();
+
+ // cleanup old TableModel
+ {
+ Reference< XModifyListener > xListener( static_cast< css::util::XModifyListener* >(this) );
+ xOldTable->removeModifyListener( xListener );
+ xOldTable->dispose();
+ xOldTable.clear();
+ }
+
+ // create and hand over to new TableLayouter
+ mpLayouter.reset(new TableLayouter( mxTable ));
+
+ // add needed listener to react on changes
+ Reference< XModifyListener > xListener( static_cast< css::util::XModifyListener* >(this) );
+ mxTable->addModifyListener( xListener );
+
+ // Apply Style to Cells
+ ApplyCellStyles();
+
+ // layout cropped table
+ LayoutTable( mpTableObj->maRect, false, false );
+}
+
void SdrTableObjImpl::init( SdrTableObj* pTable, sal_Int32 nColumns, sal_Int32 nRows )
{
mpTableObj = pTable;
@@ -285,48 +375,61 @@ void SdrTableObjImpl::init( SdrTableObj* pTable, sal_Int32 nColumns, sal_Int32 n
SdrTableObjImpl& SdrTableObjImpl::operator=( const SdrTableObjImpl& rSource )
{
- if (this != &rSource)
+ if(this == &rSource)
{
- disconnectTableStyle();
+ return *this;
+ }
- mpLayouter.reset();
+ if(nullptr == mpTableObj || nullptr == rSource.mpTableObj)
+ {
+ // error: need both SdrObjects to successfully copy data
+ return *this;
+ }
- if( mxTable.is() )
- {
- Reference< XModifyListener > xListener( static_cast< css::util::XModifyListener* >(this) );
- mxTable->removeModifyListener( xListener );
- mxTable->dispose();
- mxTable.clear();
- }
+ // remove evtl. listeners from local
+ disconnectTableStyle();
- maTableStyle = rSource.maTableStyle;
+ // reset layouter which holds a copy
+ mpLayouter.reset();
- mxTable = new TableModel( mpTableObj, rSource.mxTable );
- mpLayouter.reset(new TableLayouter( mxTable ));
+ // cleanup local mxTable if used
+ if( mxTable.is() )
+ {
Reference< XModifyListener > xListener( static_cast< css::util::XModifyListener* >(this) );
- mxTable->addModifyListener( xListener );
- mxTableStyle = rSource.mxTableStyle;
- ApplyCellStyles();
- mpTableObj->maRect = mpTableObj->maLogicRect;
- LayoutTable( mpTableObj->maRect, false, false );
-
- connectTableStyle();
+ mxTable->removeModifyListener( xListener );
+ mxTable->dispose();
+ mxTable.clear();
}
- return *this;
-}
+ // copy TableStyle (short internal data)
+ maTableStyle = rSource.maTableStyle;
-void SdrTableObjImpl::SetModel(SdrModel* pNewModelel)
-{
- // try to find new table style
- disconnectTableStyle();
+ // create/copy new mxTable. This will copy all needed cells, too
+ mxTable = new TableModel( mpTableObj, rSource.mxTable );
+
+ // create and hand over to new TableLayouter
+ mpLayouter.reset(new TableLayouter( mxTable ));
+
+ // add needed listener to react on changes
+ Reference< XModifyListener > xListener( static_cast< css::util::XModifyListener* >(this) );
+ mxTable->addModifyListener( xListener );
+ // handle TableStyle
Reference< XIndexAccess > xNewTableStyle;
- if( mxTableStyle.is() ) try
+ SdrModel& rSourceSdrModel(rSource.mpTableObj->getSdrModelFromSdrObject());
+ SdrModel& rTargetSdrModel(mpTableObj->getSdrModelFromSdrObject());
+
+ if(rSource.mxTableStyle.is() && &rSourceSdrModel == &rTargetSdrModel)
{
- const OUString sStyleName( Reference< XNamed >( mxTableStyle, UNO_QUERY_THROW )->getName() );
+ // source and target model the same -> keep current TableStyle
+ xNewTableStyle = rSource.mxTableStyle;
+ }
- Reference< XStyleFamiliesSupplier > xSFS( pNewModelel->getUnoModel(), UNO_QUERY_THROW );
+ if(!xNewTableStyle.is() && rSource.mxTableStyle.is()) try
+ {
+ // search in traget SdrModel for that TableStyle
+ const OUString sStyleName( Reference< XNamed >( rSource.mxTableStyle, UNO_QUERY_THROW )->getName() );
+ Reference< XStyleFamiliesSupplier > xSFS(rTargetSdrModel.getUnoModel(), UNO_QUERY_THROW );
Reference< XNameAccess > xFamilyNameAccess( xSFS->getStyleFamilies(), UNO_QUERY_THROW );
const OUString sFamilyName( "table" );
Reference< XNameAccess > xTableFamilyAccess( xFamilyNameAccess->getByName( sFamilyName ), UNO_QUERY_THROW );
@@ -338,22 +441,33 @@ void SdrTableObjImpl::SetModel(SdrModel* pNewModelel)
}
else
{
- // copy or?
+ // copy or? Not found, use 1st existing TableStyle (or none)
Reference< XIndexAccess > xIndexAccess( xTableFamilyAccess, UNO_QUERY_THROW );
xIndexAccess->getByIndex( 0 ) >>= xNewTableStyle;
}
}
catch( Exception& )
{
- OSL_FAIL("svx::SdrTableObjImpl::SetModel(), exception caught!");
+ OSL_FAIL("svx::SdrTableObjImpl::operator=(), exception caught!");
}
+ // set that TableStyle
mxTableStyle = xNewTableStyle;
+ // Apply Style to Cells
+ ApplyCellStyles();
+
+ // copy geometry
+ mpTableObj->maRect = mpTableObj->maLogicRect;
+
+ // layout cloned table
+ LayoutTable( mpTableObj->maRect, false, false );
+
+ // re-connect to styles (evtl. in new SdrModel)
connectTableStyle();
- update();
-}
+ return *this;
+}
void SdrTableObjImpl::ApplyCellStyles()
{
@@ -774,9 +888,6 @@ void SdrTableObj::init( sal_Int32 nColumns, sal_Int32 nRows )
maRect = maLogicRect;
mpImpl->LayoutTable( maRect, false, false );
}
-
- // Also init from old SetModel:
- mpImpl->SetModel(&getSdrModelFromSdrObject());
}
@@ -1642,9 +1753,16 @@ SdrTableObj* SdrTableObj::CloneSdrObject(SdrModel& rTargetModel) const
SdrTableObj& SdrTableObj::operator=(const SdrTableObj& rObj)
{
if( this == &rObj )
+ {
return *this;
+ }
+
// call parent
- SdrObject::operator=(rObj);
+ // before SdrObject::operator= was called which is wrong from
+ // the derivation hierarchy and may leave quite some entries
+ // unititialized. Changed to SdrTextObj::operator=, but had to adapt
+ // usage of pNewOutlinerParaObject/mpText there due to nullptr access
+ SdrTextObj::operator=(rObj);
TableModelNotifyGuard aGuard( mpImpl.is() ? mpImpl->mxTable.get() : nullptr );
@@ -1659,7 +1777,10 @@ SdrTableObj& SdrTableObj::operator=(const SdrTableObj& rObj)
bNoMirror = rObj.bNoMirror;
bDisableAutoWidthOnDragging = rObj.bDisableAutoWidthOnDragging;
+ // use SdrTableObjImpl::operator= now to
+ // copy model data and other stuff (see there)
*mpImpl = *rObj.mpImpl;
+
return *this;
}
@@ -2312,74 +2433,16 @@ void SdrTableObj::RestGeoData(const SdrObjGeoData& rGeo)
ActionChanged();
}
-
-SdrTableObj* SdrTableObj::CloneRange(
- const CellPos& rStart,
- const CellPos& rEnd,
- SdrModel& rTargetModel)
+void SdrTableObj::CropTableModelToSelection(const CellPos& rStart, const CellPos& rEnd)
{
- const sal_Int32 nColumns = rEnd.mnCol - rStart.mnCol + 1;
- const sal_Int32 nRows = rEnd.mnRow - rStart.mnRow + 1;
-
- SdrTableObj* pNewTableObj(
- new SdrTableObj(
- rTargetModel,
- GetCurrentBoundRect(),
- nColumns,
- nRows));
-
- pNewTableObj->setTableStyleSettings( getTableStyleSettings() );
- pNewTableObj->setTableStyle( getTableStyle() );
-
- Reference< XTable > xTable( getTable() );
- Reference< XTable > xNewTable( pNewTableObj->getTable() );
-
- if( !xTable.is() || !xNewTable.is() )
- {
- delete pNewTableObj;
- return nullptr;
- }
-
- // copy cells
- for( sal_Int32 nRow = 0; nRow < nRows; ++nRow )
- {
- for( sal_Int32 nCol = 0; nCol < nColumns; ++nCol ) try
- {
- CellRef xTargetCell( dynamic_cast< Cell* >( xNewTable->getCellByPosition( nCol, nRow ).get() ) );
- if( xTargetCell.is() )
- xTargetCell->cloneFrom( dynamic_cast< Cell* >( xTable->getCellByPosition( rStart.mnCol + nCol, rStart.mnRow + nRow ).get() ) );
- }
- catch( Exception& )
- {
- OSL_FAIL( "svx::SvxTableController::GetMarkedObjModel(), exception caught!" );
- }
- }
-
- // copy row heights
- Reference< XTableRows > xNewRows( xNewTable->getRows(), UNO_QUERY_THROW );
- const OUString sHeight( "Height" );
- for( sal_Int32 nRow = 0; nRow < nRows; ++nRow )
- {
- Reference< XPropertySet > xNewSet( xNewRows->getByIndex( nRow ), UNO_QUERY_THROW );
- xNewSet->setPropertyValue( sHeight, Any( mpImpl->mpLayouter->getRowHeight( rStart.mnRow + nRow ) ) );
- }
-
- // copy column widths
- Reference< XTableColumns > xNewColumns( xNewTable->getColumns(), UNO_QUERY_THROW );
- const OUString sWidth( "Width" );
- for( sal_Int32 nCol = 0; nCol < nColumns; ++nCol )
+ if(!mpImpl.is())
{
- Reference< XPropertySet > xNewSet( xNewColumns->getByIndex( nCol ), UNO_QUERY_THROW );
- xNewSet->setPropertyValue( sWidth, Any( mpImpl->mpLayouter->getColumnWidth( rStart.mnCol + nCol ) ) );
+ return;
}
- pNewTableObj->NbcReformatText();
- pNewTableObj->SetLogicRect( pNewTableObj->GetCurrentBoundRect() );
-
- return pNewTableObj;
+ mpImpl->CropTableModelToSelection(rStart, rEnd);
}
-
void SdrTableObj::DistributeColumns( sal_Int32 nFirstColumn, sal_Int32 nLastColumn )
{
if( mpImpl.is() && mpImpl->mpLayouter )
diff --git a/svx/source/table/tablecontroller.cxx b/svx/source/table/tablecontroller.cxx
index 9e70356369e3..3568fa743fd7 100644
--- a/svx/source/table/tablecontroller.cxx
+++ b/svx/source/table/tablecontroller.cxx
@@ -2615,35 +2615,40 @@ bool SvxTableController::SetAttributes(const SfxItemSet& rSet, bool bReplaceAll)
return false;
}
-
-bool SvxTableController::GetMarkedObjModel( SdrPage* pNewPage )
+SdrObject* SvxTableController::GetMarkedSdrObjClone(SdrModel& rTargetModel)
{
- if( mxTableObj.is() && mbCellSelectionMode && pNewPage ) try
- {
- sdr::table::SdrTableObj& rTableObj(*mxTableObj.get());
- CellPos aStart, aEnd;
- getSelectedCells(aStart, aEnd);
+ SdrTableObj* pRetval(nullptr);
+ sdr::table::SdrTableObj* pCurrentSdrTableObj(GetTableObj());
- // Clone to new SdrModel
- SdrTableObj* pNewTableObj(
- rTableObj.CloneRange(
- aStart,
- aEnd,
- pNewPage->getSdrModelFromSdrPage()));
- pNewTableObj->SetPage(pNewPage);
- pNewPage->InsertObject(pNewTableObj, SAL_MAX_SIZE);
+ if(nullptr == pCurrentSdrTableObj)
+ {
+ return pRetval;
+ }
- return true;
+ if(!mxTableObj.is())
+ {
+ return pRetval;
}
- catch( Exception& )
+
+ // get selection and create full selection
+ CellPos aStart, aEnd;
+ const CellPos aFullStart, aFullEnd(mxTable->getColumnCount()-1, mxTable->getRowCount()-1);
+
+ getSelectedCells(aStart, aEnd);
+
+ // compare to see if we have a partial selection
+ if(aStart != aFullStart || aEnd != aFullEnd)
{
- OSL_FAIL( "svx::SvxTableController::GetMarkedObjModel(), exception caught!" );
+ // create full clone
+ pRetval = pCurrentSdrTableObj->CloneSdrObject(rTargetModel);
+
+ // limit SdrObject's TableModel to partial selection
+ pRetval->CropTableModelToSelection(aStart, aEnd);
}
- return false;
+ return pRetval;
}
-
bool SvxTableController::PasteObjModel( const SdrModel& rModel )
{
if( mxTableObj.is() && (rModel.GetPageCount() >= 1) )