Skip to content

Commit

Permalink
Nicer API for adding/removing items
Browse files Browse the repository at this point in the history
Automatically create the corresponding undo commands, so that
plugins and scripts which add/delete items will be added to
the undo stack without any work required.
  • Loading branch information
nyalldawson committed Oct 6, 2017
1 parent 4167724 commit a66f2cb
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 19 deletions.
1 change: 1 addition & 0 deletions python/core/layout/qgslayout.sip
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ class QgsLayout : QGraphicsScene, QgsExpressionContextGenerator, QgsLayoutUndoOb
%Docstring
Removes an ``item`` from the layout. This should be called instead of the base class removeItem()
method.
The item will also be deleted.
%End

QDomElement writeXml( QDomDocument &document, const QgsReadWriteContext &context ) const;
Expand Down
41 changes: 32 additions & 9 deletions src/core/layout/qgslayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "qgslayoutguidecollection.h"
#include "qgsreadwritecontext.h"
#include "qgsproject.h"
#include "qgslayoutitemundocommand.h"

QgsLayout::QgsLayout( QgsProject *project )
: mProject( project )
Expand Down Expand Up @@ -360,19 +361,24 @@ QRectF QgsLayout::layoutBounds( bool ignorePages, double margin ) const

void QgsLayout::addLayoutItem( QgsLayoutItem *item )
{
addItem( item );
updateBounds();
mItemsModel->rebuildZList();
addLayoutItemPrivate( item );
QString undoText;
if ( QgsLayoutItemAbstractMetadata *metadata = QgsApplication::layoutItemRegistry()->itemMetadata( item->type() ) )
{
undoText = tr( "Created %1" ).arg( metadata->visibleName() );
}
else
{
undoText = tr( "Created item" );
}
mUndoStack->stack()->push( new QgsLayoutItemAddItemCommand( item, undoText ) );
}

void QgsLayout::removeLayoutItem( QgsLayoutItem *item )
{
mItemsModel->setItemRemoved( item );
removeItem( item );
#if 0 //TODO
emit itemRemoved( item );
#endif
item->deleteLater();
QgsLayoutItemDeleteUndoCommand *deleteCommand = new QgsLayoutItemDeleteUndoCommand( item, tr( "Deleted item" ) );
removeLayoutItemPrivate( item );
mUndoStack->stack()->push( deleteCommand );
}

QgsLayoutUndoStack *QgsLayout::undoStack()
Expand Down Expand Up @@ -457,6 +463,23 @@ bool QgsLayout::readXmlLayoutSettings( const QDomElement &layoutElement, const Q
return true;
}

void QgsLayout::addLayoutItemPrivate( QgsLayoutItem *item )
{
addItem( item );
updateBounds();
mItemsModel->rebuildZList();
}

void QgsLayout::removeLayoutItemPrivate( QgsLayoutItem *item )
{
mItemsModel->setItemRemoved( item );
removeItem( item );
#if 0 //TODO
emit itemRemoved( item );
#endif
item->deleteLater();
}

void QgsLayout::updateZValues( const bool addUndoCommands )
{
int counter = mItemsModel->zOrderListSize();
Expand Down
13 changes: 13 additions & 0 deletions src/core/layout/qgslayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,7 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext
/**
* Removes an \a item from the layout. This should be called instead of the base class removeItem()
* method.
* The item will also be deleted.
*/
void removeLayoutItem( QgsLayoutItem *item );

Expand Down Expand Up @@ -489,7 +490,19 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext
//! Reads only the layout settings (not member settings like grid settings, etc) from XML
bool readXmlLayoutSettings( const QDomElement &layoutElement, const QDomDocument &document, const QgsReadWriteContext &context );

/**
* Adds a layout item to the layout, without adding the corresponding undo commands.
*/
void addLayoutItemPrivate( QgsLayoutItem *item );

/**
* Removes an item from the layout, without adding the corresponding undo commands.
*/
void removeLayoutItemPrivate( QgsLayoutItem *item );

friend class QgsLayoutItemAddItemCommand;
friend class QgsLayoutItemDeleteUndoCommand;
friend class QgsLayoutItemUndoCommand;
friend class QgsLayoutUndoCommand;
friend class QgsLayoutModel;
};
Expand Down
6 changes: 3 additions & 3 deletions src/core/layout/qgslayoutitemundocommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ void QgsLayoutItemUndoCommand::restoreState( QDomDocument &stateDoc )
QgsLayoutItem *QgsLayoutItemUndoCommand::recreateItem( int itemType, QgsLayout *layout )
{
QgsLayoutItem *item = QgsApplication::layoutItemRegistry()->createItem( itemType, layout );
mLayout->addLayoutItem( item );
mLayout->addLayoutItemPrivate( item );
return item;
}

Expand Down Expand Up @@ -116,7 +116,7 @@ void QgsLayoutItemDeleteUndoCommand::redo()
QgsLayoutItem *item = layout()->itemByUuid( itemUuid() );
Q_ASSERT_X( item, "QgsLayoutItemDeleteUndoCommand::redo", "could not find item to re-delete!" );

layout()->removeLayoutItem( item );
layout()->removeLayoutItemPrivate( item );
}

QgsLayoutItemAddItemCommand::QgsLayoutItemAddItemCommand( QgsLayoutItem *item, const QString &text, int id, QUndoCommand *parent )
Expand Down Expand Up @@ -146,7 +146,7 @@ void QgsLayoutItemAddItemCommand::undo()
QgsLayoutItem *item = layout()->itemByUuid( itemUuid() );
if ( item )
{
layout()->removeLayoutItem( item );
layout()->removeLayoutItemPrivate( item );
}
}

Expand Down
2 changes: 0 additions & 2 deletions src/gui/layout/qgslayoutview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -585,9 +585,7 @@ void QgsLayoutView::deleteSelectedItems()
//delete selected items
for ( QgsLayoutItem *item : selectedItems )
{
QgsLayoutItemDeleteUndoCommand *deleteCommand = new QgsLayoutItemDeleteUndoCommand( item, QString() );
currentLayout()->removeLayoutItem( item );
currentLayout()->undoStack()->stack()->push( deleteCommand );
}
currentLayout()->undoStack()->endMacro();
currentLayout()->project()->setDirty( true );
Expand Down
2 changes: 0 additions & 2 deletions src/gui/layout/qgslayoutviewtooladditem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
#include "qgslayoutitemguiregistry.h"
#include "qgslayoutnewitempropertiesdialog.h"
#include "qgssettings.h"
#include "qgslayoutitemundocommand.h"
#include <QGraphicsRectItem>
#include <QPen>
#include <QBrush>
Expand Down Expand Up @@ -119,7 +118,6 @@ void QgsLayoutViewToolAddItem::layoutReleaseEvent( QgsLayoutViewMouseEvent *even
settings.setValue( QStringLiteral( "LayoutDesigner/lastSizeUnit" ), static_cast< int >( item->sizeWithUnits().units() ) );

layout()->addLayoutItem( item );
layout()->undoStack()->stack()->push( new QgsLayoutItemAddItemCommand( item, tr( "Created %1" ).arg( QgsApplication::layoutItemRegistry()->itemMetadata( mItemType )->visibleName() ) ) );
layout()->setSelectedItem( item );
}

Expand Down
3 changes: 0 additions & 3 deletions tests/src/core/testqgslayoutitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1372,7 +1372,6 @@ void TestQgsLayoutItem::undoRedo()
item->setFrameStrokeColor( QColor( 255, 100, 200 ) );
l.addLayoutItem( item );

l.undoStack()->stack()->push( new QgsLayoutItemAddItemCommand( item, QString() ) );
QVERIFY( pItem );
QVERIFY( l.items().contains( item ) );
QCOMPARE( l.itemByUuid( uuid ), item );
Expand Down Expand Up @@ -1412,9 +1411,7 @@ void TestQgsLayoutItem::undoRedo()
QCOMPARE( item->frameStrokeColor().name(), QColor( 255, 100, 200 ).name() );

// delete item
QgsLayoutItemDeleteUndoCommand *deleteCommand = new QgsLayoutItemDeleteUndoCommand( item, QString() );
l.removeLayoutItem( item );
l.undoStack()->stack()->push( deleteCommand );

QgsApplication::sendPostedEvents( nullptr, QEvent::DeferredDelete );
QVERIFY( !pItem );
Expand Down

0 comments on commit a66f2cb

Please sign in to comment.