@@ -25,8 +25,6 @@ QgsLayoutItemGroup::QgsLayoutItemGroup( QgsLayout *layout )
2525
2626QgsLayoutItemGroup::~QgsLayoutItemGroup ()
2727{
28- if ( mLayout )
29- mLayout ->undoStack ()->beginMacro ( tr ( " Removed group" ) );
3028 // loop through group members and remove them from the scene
3129 for ( QgsLayoutItem *item : qgsAsConst ( mItems ) )
3230 {
@@ -37,10 +35,8 @@ QgsLayoutItemGroup::~QgsLayoutItemGroup()
3735 if ( mLayout )
3836 mLayout ->removeLayoutItem ( item );
3937 else
40- item-> deleteLater () ;
38+ delete item;
4139 }
42- if ( mLayout )
43- mLayout ->undoStack ()->endMacro ();
4440}
4541
4642int QgsLayoutItemGroup::type () const
@@ -63,6 +59,11 @@ QString QgsLayoutItemGroup::displayName() const
6359 return tr ( " <Group>" );
6460}
6561
62+ QgsLayoutItemGroup *QgsLayoutItemGroup::create ( QgsLayout *layout, const QVariantMap & )
63+ {
64+ return new QgsLayoutItemGroup ( layout );
65+ }
66+
6667void QgsLayoutItemGroup::addItem ( QgsLayoutItem *item )
6768{
6869 if ( !item )
@@ -107,7 +108,7 @@ QList<QgsLayoutItem *> QgsLayoutItemGroup::items() const
107108
108109void QgsLayoutItemGroup::setVisibility ( const bool visible )
109110{
110- if ( mLayout )
111+ if ( ! shouldBlockUndoCommands () )
111112 mLayout ->undoStack ()->beginMacro ( tr ( " Set group visibility" ) );
112113 // also set visibility for all items within the group
113114 for ( QgsLayoutItem *item : qgsAsConst ( mItems ) )
@@ -118,7 +119,7 @@ void QgsLayoutItemGroup::setVisibility( const bool visible )
118119 }
119120 // lastly set visibility for group item itself
120121 QgsLayoutItem::setVisibility ( visible );
121- if ( mLayout )
122+ if ( ! shouldBlockUndoCommands () )
122123 mLayout ->undoStack ()->endMacro ();
123124}
124125
@@ -127,7 +128,8 @@ void QgsLayoutItemGroup::attemptMove( const QgsLayoutPoint &point )
127128 if ( !mLayout )
128129 return ;
129130
130- mLayout ->undoStack ()->beginMacro ( tr ( " Moved group" ) );
131+ if ( !shouldBlockUndoCommands () )
132+ mLayout ->undoStack ()->beginMacro ( tr ( " Moved group" ) );
131133
132134 QPointF scenePoint = mLayout ->convertToLayoutUnits ( point );
133135 double deltaX = scenePoint.x () - pos ().x ();
@@ -139,7 +141,12 @@ void QgsLayoutItemGroup::attemptMove( const QgsLayoutPoint &point )
139141 if ( !item )
140142 continue ;
141143
142- mLayout ->undoStack ()->beginCommand ( item, QString () );
144+ std::unique_ptr< QgsAbstractLayoutUndoCommand > command;
145+ if ( !shouldBlockUndoCommands () )
146+ {
147+ command.reset ( createCommand ( QString (), 0 ) );
148+ command->saveBeforeState ();
149+ }
143150
144151 // need to convert delta from layout units -> item units
145152 QgsLayoutPoint itemPos = item->positionWithUnits ();
@@ -148,11 +155,16 @@ void QgsLayoutItemGroup::attemptMove( const QgsLayoutPoint &point )
148155 itemPos.setY ( itemPos.y () + deltaPos.y () );
149156 item->attemptMove ( itemPos );
150157
151- mLayout ->undoStack ()->endCommand ();
158+ if ( command )
159+ {
160+ command->saveAfterState ();
161+ mLayout ->undoStack ()->stack ()->push ( command.release () );
162+ }
152163 }
153164 // lastly move group item itself
154165 QgsLayoutItem::attemptMove ( point );
155- mLayout ->undoStack ()->endMacro ();
166+ if ( !shouldBlockUndoCommands () )
167+ mLayout ->undoStack ()->endMacro ();
156168 resetBoundingRect ();
157169}
158170
@@ -161,7 +173,8 @@ void QgsLayoutItemGroup::attemptResize( const QgsLayoutSize &size )
161173 if ( !mLayout )
162174 return ;
163175
164- mLayout ->undoStack ()->beginMacro ( tr ( " Resized group" ) );
176+ if ( !shouldBlockUndoCommands () )
177+ mLayout ->undoStack ()->beginMacro ( tr ( " Resized group" ) );
165178
166179 QRectF oldRect = rect ();
167180 QSizeF newSizeLayoutUnits = mLayout ->convertToLayoutUnits ( size );
@@ -174,6 +187,13 @@ void QgsLayoutItemGroup::attemptResize( const QgsLayoutSize &size )
174187 if ( !item )
175188 continue ;
176189
190+ std::unique_ptr< QgsAbstractLayoutUndoCommand > command;
191+ if ( !shouldBlockUndoCommands () )
192+ {
193+ command.reset ( createCommand ( QString (), 0 ) );
194+ command->saveBeforeState ();
195+ }
196+
177197 QRectF itemRect = mapRectFromItem ( item, item->rect () );
178198 QgsLayoutUtils::relativeResizeRect ( itemRect, oldRect, newRect );
179199
@@ -186,11 +206,76 @@ void QgsLayoutItemGroup::attemptResize( const QgsLayoutSize &size )
186206
187207 QgsLayoutSize itemSize = mLayout ->convertFromLayoutUnits ( itemRect.size (), item->sizeWithUnits ().units () );
188208 item->attemptResize ( itemSize );
209+
210+ if ( command )
211+ {
212+ command->saveAfterState ();
213+ mLayout ->undoStack ()->stack ()->push ( command.release () );
214+ }
189215 }
190216 QgsLayoutItem::attemptResize ( size );
191- mLayout ->undoStack ()->endMacro ();
217+ if ( !shouldBlockUndoCommands () )
218+ mLayout ->undoStack ()->endMacro ();
219+
220+ resetBoundingRect ();
221+ }
222+
223+ bool QgsLayoutItemGroup::writeXml ( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context ) const
224+ {
225+ QDomElement element = document.createElement ( QStringLiteral ( " LayoutItem" ) );
226+ element.setAttribute ( QStringLiteral ( " type" ), stringType () );
227+
228+ writePropertiesToElement ( element, document, context );
229+
230+ for ( QgsLayoutItem *item : mItems )
231+ {
232+ if ( !item )
233+ continue ;
234+
235+ QDomElement childItem = document.createElement ( QStringLiteral ( " ComposerItemGroupElement" ) );
236+ childItem.setAttribute ( QStringLiteral ( " uuid" ), item->uuid () );
237+ element.appendChild ( childItem );
238+ }
239+
240+ parentElement.appendChild ( element );
241+
242+ return true ;
243+ }
244+
245+ bool QgsLayoutItemGroup::readXml ( const QDomElement &itemElement, const QDomDocument &document, const QgsReadWriteContext &context )
246+ {
247+ if ( itemElement.nodeName () != QStringLiteral ( " LayoutItem" ) || itemElement.attribute ( QStringLiteral ( " type" ) ) != stringType () )
248+ {
249+ return false ;
250+ }
251+
252+ bool result = readPropertiesFromElement ( itemElement, document, context );
253+
254+ QList<QgsLayoutItem *> items;
255+ mLayout ->layoutItems ( items );
256+
257+ QDomNodeList elementNodes = itemElement.elementsByTagName ( QStringLiteral ( " ComposerItemGroupElement" ) );
258+ for ( int i = 0 ; i < elementNodes.count (); ++i )
259+ {
260+ QDomNode elementNode = elementNodes.at ( i );
261+ if ( !elementNode.isElement () )
262+ continue ;
263+
264+ QString uuid = elementNode.toElement ().attribute ( QStringLiteral ( " uuid" ) );
265+
266+ for ( QgsLayoutItem *item : qgsAsConst ( items ) )
267+ {
268+ if ( item && ( item->mUuid == uuid /* TODO || item->mTemplateUuid == uuid */ ) )
269+ {
270+ addItem ( item );
271+ break ;
272+ }
273+ }
274+ }
192275
193276 resetBoundingRect ();
277+
278+ return result;
194279}
195280
196281void QgsLayoutItemGroup::paint ( QPainter *, const QStyleOptionGraphicsItem *, QWidget * )
0 commit comments