/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <sdr/properties/textproperties.hxx>
#include <editeng/outlobj.hxx>
#include <o3tl/make_unique.hxx>
#include <cell.hxx>
#include "tableundo.hxx"
#include <svx/svdotable.hxx>
#include "tablerow.hxx"
#include "tablecolumn.hxx"
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::table;
namespace sdr { namespace table {
CellUndo::CellUndo( const tools::WeakReference<SdrObject>& xObjRef, const CellRef& xCell )
: SdrUndoAction(xCell->GetObject().getSdrModelFromSdrObject())
,mxObjRef( xObjRef )
,mxCell( xCell )
,mbUndo( true )
{
if( mxCell.is() && mxObjRef.is() )
{
getDataFromCell( maUndoData );
mxObjRef->AddObjectUser( *this );
}
}
CellUndo::~CellUndo()
{
if( mxObjRef.is() )
mxObjRef->RemoveObjectUser( *this );
dispose();
}
void CellUndo::dispose()
{
mxCell.clear();
delete maUndoData.mpProperties;
maUndoData.mpProperties = nullptr;
delete maRedoData.mpProperties;
maRedoData.mpProperties = nullptr;
delete maUndoData.mpOutlinerParaObject;
maUndoData.mpOutlinerParaObject = nullptr;
delete maRedoData.mpOutlinerParaObject;
maRedoData.mpOutlinerParaObject = nullptr;
}
void CellUndo::ObjectInDestruction(const SdrObject& )
{
dispose();
}
void CellUndo::Undo()
{
if( mxCell.is() && mbUndo )
{
if( maRedoData.mpProperties == nullptr )
getDataFromCell( maRedoData );
setDataToCell( maUndoData );
mbUndo = false;
}
}
void CellUndo::Redo()
{
if( mxCell.is() && !mbUndo )
{
setDataToCell( maRedoData );
mbUndo = true;
}
}
bool CellUndo::Merge( SfxUndoAction *pNextAction )
{
CellUndo* pNext = dynamic_cast< CellUndo* >( pNextAction );
return pNext && pNext->mxCell.get() == mxCell.get();
}
void CellUndo::setDataToCell( const Data& rData )
{
if( rData.mpProperties )
mxCell->mpProperties.reset(Cell::CloneProperties( rData.mpProperties, *mxObjRef.get(), *mxCell.get() ));
else
mxCell->mpProperties.reset();
if( rData.mpOutlinerParaObject )
mxCell->SetOutlinerParaObject( o3tl::make_unique<OutlinerParaObject>(*rData.mpOutlinerParaObject) );
else
mxCell->RemoveOutlinerParaObject();
mxCell->msFormula = rData.msFormula;
mxCell->mfValue = rData.mfValue;
mxCell->mnError = rData.mnError;
mxCell->mbMerged = rData.mbMerged;
mxCell->mnRowSpan = rData.mnRowSpan;
mxCell->mnColSpan = rData.mnColSpan;
if(mxObjRef.is())
{
// #i120201# ActionChanged is not enough, we need to trigger TableLayouter::UpdateBorderLayout()
// and this is done best using ReformatText() for table objects
mxObjRef->ActionChanged();
mxObjRef->NbcReformatText();
}
}
void CellUndo::getDataFromCell( Data& rData )
{
if( mxObjRef.is() && mxCell.is() )
{
if( mxCell->mpProperties )
rData.mpProperties = mxCell->CloneProperties( *mxObjRef.get(), *mxCell.get());
if( mxCell->GetOutlinerParaObject() )
rData.mpOutlinerParaObject = new OutlinerParaObject(*mxCell->GetOutlinerParaObject());
else
rData.mpOutlinerParaObject = nullptr;
rData.msFormula = mxCell->msFormula;
rData.mfValue = mxCell->mfValue;
rData.mnError = mxCell->mnError;
rData.mbMerged = mxCell->mbMerged;
rData.mnRowSpan = mxCell->mnRowSpan;
rData.mnColSpan = mxCell->mnColSpan;
}
}
// class InsertRowUndo : public SdrUndoAction
static void Dispose( RowVector& rRows )
{
RowVector::iterator aIter( rRows.begin() );
while( aIter != rRows.end() )
(*aIter++)->dispose();
}
InsertRowUndo::InsertRowUndo( const TableModelRef& xTable, sal_Int32 nIndex, RowVector& aNewRows )
: SdrUndoAction(xTable->getSdrTableObj()->getSdrModelFromSdrObject())
,mxTable( xTable )
,mnIndex( nIndex )
,mbUndo( true )
{
maRows.swap( aNewRows );
}
InsertRowUndo::~InsertRowUndo()
{
if( !mbUndo )
Dispose( maRows );
}
void InsertRowUndo::Undo()
{
if( mxTable.is() )
{
mxTable->UndoInsertRows( mnIndex, sal::static_int_cast< sal_Int32 >( maRows.size() ) );
mbUndo = false;
}
}
void InsertRowUndo::Redo()
{
if( mxTable.is() )
{
mxTable->UndoRemoveRows( mnIndex, maRows );
mbUndo = true;
}
}
// class RemoveRowUndo : public SdrUndoAction
RemoveRowUndo::RemoveRowUndo( const TableModelRef& xTable, sal_Int32 nIndex, RowVector& aRemovedRows )
: SdrUndoAction(xTable->getSdrTableObj()->getSdrModelFromSdrObject())
,mxTable( xTable )
,mnIndex( nIndex )
,mbUndo( true )
{
maRows.swap( aRemovedRows );
}
RemoveRowUndo::~RemoveRowUndo()
{
if( mbUndo )
Dispose( maRows );
}
void RemoveRowUndo::Undo()
{
if( mxTable.is() )
{
mxTable->UndoRemoveRows( mnIndex, maRows );
mbUndo = false;
}
}
void RemoveRowUndo::Redo()
{
if( mxTable.is() )
{
mxTable->UndoInsertRows( mnIndex, sal::static_int_cast< sal_Int32 >( maRows.size() ) );
mbUndo = true;
}
}
// class InsertColUndo : public SdrUndoAction
static void Dispose( ColumnVector& rCols )
{
ColumnVector::iterator aIter( rCols.begin() );
while( aIter != rCols.end() )
(*aIter++)->dispose();
}
static void Dispose( CellVector& rCells )
{
CellVector::iterator aIter( rCells.begin() );
while( aIter != rCells.end() )
(*aIter++)->dispose();
}
InsertColUndo::InsertColUndo( const TableModelRef& xTable, sal_Int32 nIndex, ColumnVector& aNewCols, CellVector& aCells )
: SdrUndoAction(xTable->getSdrTableObj()->getSdrModelFromSdrObject())
,mxTable( xTable )
,mnIndex( nIndex )
,mbUndo( true )
{
maColumns.swap( aNewCols );
maCells.swap( aCells );
}
InsertColUndo::~InsertColUndo()
{
if( !mbUndo )
{
Dispose( maColumns );
Dispose( maCells );
}
}
void InsertColUndo::Undo()
{
if( mxTable.is() )
{
mxTable->UndoInsertColumns( mnIndex, sal::static_int_cast< sal_Int32 >( maColumns.size() ) );
mbUndo = false;
}
}
void InsertColUndo::Redo()
{
if( mxTable.is() )
{
mxTable->UndoRemoveColumns( mnIndex, maColumns, maCells );
mbUndo = true;
}
}
// class RemoveColUndo : public SdrUndoAction
RemoveColUndo::RemoveColUndo( const TableModelRef& xTable, sal_Int32 nIndex, ColumnVector& aNewCols, CellVector& aCells )
: SdrUndoAction(xTable->getSdrTableObj()->getSdrModelFromSdrObject())
,mxTable( xTable )
,mnIndex( nIndex )
,mbUndo( true )
{
maColumns.swap( aNewCols );
maCells.swap( aCells );
}
RemoveColUndo::~RemoveColUndo()
{
if( mbUndo )
{
Dispose( maColumns );
Dispose( maCells );
}
}
void RemoveColUndo::Undo()
{
if( mxTable.is() )
{
mxTable->UndoRemoveColumns( mnIndex, maColumns, maCells );
mbUndo = false;
}
}
void RemoveColUndo::Redo()
{
if( mxTable.is() )
{
mxTable->UndoInsertColumns( mnIndex, sal::static_int_cast< sal_Int32 >( maColumns.size() ) );
mbUndo = true;
}
}
// class TableColumnUndo : public SdrUndoAction
TableColumnUndo::TableColumnUndo( const TableColumnRef& xCol )
: SdrUndoAction(xCol->mxTableModel->getSdrTableObj()->getSdrModelFromSdrObject())
,mxCol( xCol )
,mbHasRedoData( false )
{
getData( maUndoData );
}
TableColumnUndo::~TableColumnUndo()
{
}
void TableColumnUndo::Undo()
{
if( !mbHasRedoData )
{
getData( maRedoData );
mbHasRedoData = true;
}
setData( maUndoData );
}
void TableColumnUndo::Redo()
{
setData( maRedoData );
}
bool TableColumnUndo::Merge( SfxUndoAction *pNextAction )
{
TableColumnUndo* pNext = dynamic_cast< TableColumnUndo* >( pNextAction );
return pNext && pNext->mxCol == mxCol;
}
void TableColumnUndo::setData( const Data& rData )
{
mxCol->mnColumn = rData.mnColumn;
mxCol->mnWidth = rData.mnWidth;
mxCol->mbOptimalWidth = rData.mbOptimalWidth;
mxCol->mbIsVisible = rData.mbIsVisible;
mxCol->mbIsStartOfNewPage = rData.mbIsStartOfNewPage;
mxCol->maName = rData.maName;
// Trigger re-layout of the table.
mxCol->getModel()->setModified(true);
}
void TableColumnUndo::getData( Data& rData )
{
rData.mnColumn = mxCol->mnColumn;
rData.mnWidth = mxCol->mnWidth;
rData.mbOptimalWidth = mxCol->mbOptimalWidth;
rData.mbIsVisible = mxCol->mbIsVisible;
rData.mbIsStartOfNewPage = mxCol->mbIsStartOfNewPage;
rData.maName = mxCol->maName;
}
// class TableRowUndo : public SdrUndoAction
TableRowUndo::TableRowUndo( const TableRowRef& xRow )
: SdrUndoAction(xRow->mxTableModel->getSdrTableObj()->getSdrModelFromSdrObject())
, mxRow( xRow )
, mbHasRedoData( false )
{
getData( maUndoData );
}
TableRowUndo::~TableRowUndo()
{
}
void TableRowUndo::Undo()
{
if( !mbHasRedoData )
{
getData( maRedoData );
mbHasRedoData = true;
}
setData( maUndoData );
}
void TableRowUndo::Redo()
{
setData( maRedoData );
}
bool TableRowUndo::Merge( SfxUndoAction *pNextAction )
{
TableRowUndo* pNext = dynamic_cast< TableRowUndo* >( pNextAction );
return pNext && pNext->mxRow == mxRow;
}
void TableRowUndo::setData( const Data& rData )
{
mxRow->mnRow = rData.mnRow;
mxRow->mnHeight = rData.mnHeight;
mxRow->mbOptimalHeight = rData.mbOptimalHeight;
mxRow->mbIsVisible = rData.mbIsVisible;
mxRow->mbIsStartOfNewPage = rData.mbIsStartOfNewPage;
mxRow->maName = rData.maName;
// Trigger re-layout of the table.
mxRow->getModel()->setModified(true);
}
void TableRowUndo::getData( Data& rData )
{
rData.mnRow = mxRow->mnRow;
rData.mnHeight = mxRow->mnHeight;
rData.mbOptimalHeight = mxRow->mbOptimalHeight;
rData.mbIsVisible = mxRow->mbIsVisible;
rData.mbIsStartOfNewPage = mxRow->mbIsStartOfNewPage;
rData.maName = mxRow->maName;
}
TableStyleUndo::TableStyleUndo( const SdrTableObj& rTableObj )
: SdrUndoAction(rTableObj.getSdrModelFromSdrObject())
,mxObjRef( const_cast< sdr::table::SdrTableObj*>( &rTableObj ) )
,mbHasRedoData(false)
{
getData( maUndoData );
}
void TableStyleUndo::Undo()
{
if( !mbHasRedoData )
{
getData( maRedoData );
mbHasRedoData = true;
}
setData( maUndoData );
}
void TableStyleUndo::Redo()
{
setData( maRedoData );
}
void TableStyleUndo::setData( const Data& rData )
{
SdrTableObj* pTableObj = mxObjRef.get();
if( pTableObj )
{
pTableObj->setTableStyle( rData.mxTableStyle );
pTableObj->setTableStyleSettings( rData.maSettings );
}
}
void TableStyleUndo::getData( Data& rData )
{
SdrTableObj* pTableObj = mxObjRef.get();
if( pTableObj )
{
rData.maSettings = pTableObj->getTableStyleSettings();
rData.mxTableStyle = pTableObj->getTableStyle();
}
}
} }
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
↑ V730 It is possible that not all members of a class are initialized inside the constructor. Consider inspecting: maRedoData.