QGIS API Documentation  3.21.0-Master (909859188c)
qgslayoutitemundocommand.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayoutitemundocommand.cpp
3  ------------------------
4  begin : July 2017
5  copyright : (C) 2017 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7 ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
19 #include "qgslayoutitem.h"
20 #include "qgsreadwritecontext.h"
21 #include "qgslayout.h"
22 #include "qgsproject.h"
23 #include "qgslayoutundostack.h"
24 
26 QgsLayoutItemUndoCommand::QgsLayoutItemUndoCommand( QgsLayoutItem *item, const QString &text, int id, QUndoCommand *parent )
27  : QgsAbstractLayoutUndoCommand( text, id, parent )
28  , mItemUuid( item->uuid() )
29  , mLayout( item->layout() )
30  , mItemType( item->type() )
31 {
32 
33 }
34 
35 bool QgsLayoutItemUndoCommand::mergeWith( const QUndoCommand *command )
36 {
37  if ( command->id() == 0 )
38  return false;
39 
40  const QgsLayoutItemUndoCommand *c = dynamic_cast<const QgsLayoutItemUndoCommand *>( command );
41  if ( !c )
42  {
43  return false;
44  }
45  if ( c->itemUuid() != itemUuid() )
46  return false;
47 
48  setAfterState( c->afterState() );
49  return true;
50 }
51 
52 void QgsLayoutItemUndoCommand::saveState( QDomDocument &stateDoc ) const
53 {
54  stateDoc.clear();
55  QDomElement documentElement = stateDoc.createElement( QStringLiteral( "ItemState" ) );
56 
57  QgsLayoutItem *item = mLayout->itemByUuid( mItemUuid );
58  Q_ASSERT_X( item, "QgsLayoutItemUndoCommand::saveState", "could not retrieve item for saving state" );
59 
60  item->writeXml( documentElement, stateDoc, QgsReadWriteContext() );
61  stateDoc.appendChild( documentElement );
62 }
63 
64 void QgsLayoutItemUndoCommand::restoreState( QDomDocument &stateDoc )
65 {
66  // find item by uuid...
67  QgsLayoutItem *item = mLayout->itemByUuid( mItemUuid );
68  if ( !item )
69  {
70  // uh oh - it's been deleted! we need to create a new instance
71  item = recreateItem( mItemType, mLayout );
72  }
73 
74  item->readXml( stateDoc.documentElement().firstChild().toElement(), stateDoc, QgsReadWriteContext() );
75  item->finalizeRestoreFromXml();
76  mLayout->project()->setDirty( true );
77  mLayout->undoStack()->notifyUndoRedoOccurred( item );
78 }
79 
80 QgsLayoutItem *QgsLayoutItemUndoCommand::recreateItem( int itemType, QgsLayout *layout )
81 {
82  QgsLayoutItem *item = QgsApplication::layoutItemRegistry()->createItem( itemType, layout );
83  mLayout->addLayoutItemPrivate( item );
84  return item;
85 }
86 
87 QString QgsLayoutItemUndoCommand::itemUuid() const
88 {
89  return mItemUuid;
90 }
91 
92 QgsLayout *QgsLayoutItemUndoCommand::layout() const
93 {
94  return mLayout;
95 }
96 
97 
98 //
99 // QgsLayoutItemDeleteUndoCommand
100 //
101 
102 QgsLayoutItemDeleteUndoCommand::QgsLayoutItemDeleteUndoCommand( QgsLayoutItem *item, const QString &text, int id, QUndoCommand *parent )
103  : QgsLayoutItemUndoCommand( item, text, id, parent )
104 {
105  saveBeforeState();
106 }
107 
108 bool QgsLayoutItemDeleteUndoCommand::mergeWith( const QUndoCommand * )
109 {
110  return false;
111 }
112 
113 void QgsLayoutItemDeleteUndoCommand::redo()
114 {
115  if ( mFirstRun )
116  {
117  mFirstRun = false;
118  return;
119  }
120 
121  QgsLayoutItem *item = layout()->itemByUuid( itemUuid() );
122  //Q_ASSERT_X( item, "QgsLayoutItemDeleteUndoCommand::redo", "could not find item to re-delete!" );
123 
124  layout()->undoStack()->blockCommands( true );
125  if ( item )
126  layout()->removeLayoutItemPrivate( item );
127  layout()->undoStack()->blockCommands( false );
128 }
129 
130 QgsLayoutItemAddItemCommand::QgsLayoutItemAddItemCommand( QgsLayoutItem *item, const QString &text, int id, QUndoCommand *parent )
131  : QgsLayoutItemUndoCommand( item, text, id, parent )
132 {
133  saveAfterState();
134 }
135 
136 bool QgsLayoutItemAddItemCommand::containsChange() const
137 {
138  return true;
139 }
140 
141 bool QgsLayoutItemAddItemCommand::mergeWith( const QUndoCommand * )
142 {
143  return false;
144 }
145 
146 void QgsLayoutItemAddItemCommand::undo()
147 {
148  if ( mFirstRun )
149  {
150  mFirstRun = false;
151  return;
152  }
153 
154  QgsLayoutItem *item = layout()->itemByUuid( itemUuid() );
155  if ( item )
156  {
157  layout()->removeLayoutItemPrivate( item );
158  }
159 }
160 
161 
Base class for commands to undo/redo layout and layout object changes.
static QgsLayoutItemRegistry * layoutItemRegistry()
Returns the application's layout item registry, used for layout item types.
QgsLayoutItem * createItem(int type, QgsLayout *layout) const
Creates a new instance of a layout item given the item type, and target layout.
Base class for graphical items within a QgsLayout.
bool writeXml(QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context) const
Stores the item state in a DOM element.
virtual void finalizeRestoreFromXml()
Called after all pending items have been restored from XML.
bool readXml(const QDomElement &itemElement, const QDomDocument &document, const QgsReadWriteContext &context)
Sets the item state from a DOM element.
void blockCommands(bool blocked)
Sets whether undo commands for the layout should be temporarily blocked.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition: qgslayout.h:51
QgsLayoutItem * itemByUuid(const QString &uuid, bool includeTemplateUuids=false) const
Returns the layout item with matching uuid unique identifier, or nullptr if a matching item could not...
Definition: qgslayout.cpp:238
QgsLayoutUndoStack * undoStack()
Returns a pointer to the layout's undo stack, which manages undo/redo states for the layout and it's ...
Definition: qgslayout.cpp:686
The class is used as a container of context for various read/write operations on other objects.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c