mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
After a undo/redo action occurs, select the affected items
This commit is contained in:
parent
48a45b3bff
commit
72a1f77079
@ -10,7 +10,8 @@
|
||||
|
||||
|
||||
|
||||
class QgsLayoutUndoStack
|
||||
|
||||
class QgsLayoutUndoStack : QObject
|
||||
{
|
||||
%Docstring
|
||||
An undo stack for QgsLayouts.
|
||||
@ -86,6 +87,19 @@ class QgsLayoutUndoStack
|
||||
:rtype: QUndoStack
|
||||
%End
|
||||
|
||||
void notifyUndoRedoOccurred( QgsLayoutItem *item );
|
||||
%Docstring
|
||||
Notifies the stack that an undo or redo action occurred for a specified ``item``.
|
||||
%End
|
||||
|
||||
signals:
|
||||
|
||||
void undoRedoOccurredForItems( const QSet< QString > itemUuids );
|
||||
%Docstring
|
||||
Emitted when an undo or redo action has occurred, which affected a
|
||||
set of layout ``itemUuids``.
|
||||
%End
|
||||
|
||||
private:
|
||||
QgsLayoutUndoStack( const QgsLayoutUndoStack &other );
|
||||
};
|
||||
|
@ -581,6 +581,7 @@ void QgsLayoutDesignerDialog::setCurrentLayout( QgsLayout *layout )
|
||||
mLayoutToolbar->addAction( mUndoAction );
|
||||
mLayoutToolbar->addAction( mRedoAction );
|
||||
|
||||
connect( mLayout->undoStack(), &QgsLayoutUndoStack::undoRedoOccurredForItems, this, &QgsLayoutDesignerDialog::undoRedoOccurredForItems );
|
||||
connect( mActionClearGuides, &QAction::triggered, &mLayout->guides(), [ = ]
|
||||
{
|
||||
mLayout->guides().clear();
|
||||
@ -620,6 +621,9 @@ void QgsLayoutDesignerDialog::setIconSizes( int size )
|
||||
|
||||
void QgsLayoutDesignerDialog::showItemOptions( QgsLayoutItem *item, bool bringPanelToFront )
|
||||
{
|
||||
if ( mBlockItemOptions )
|
||||
return;
|
||||
|
||||
if ( !item )
|
||||
{
|
||||
delete mItemPropertiesStack->takeMainPanel();
|
||||
@ -1073,6 +1077,27 @@ void QgsLayoutDesignerDialog::dockVisibilityChanged( bool visible )
|
||||
}
|
||||
}
|
||||
|
||||
void QgsLayoutDesignerDialog::undoRedoOccurredForItems( const QSet<QString> itemUuids )
|
||||
{
|
||||
mBlockItemOptions = true;
|
||||
|
||||
mLayout->deselectAll();
|
||||
QgsLayoutItem *focusItem = nullptr;
|
||||
for ( const QString &uuid : itemUuids )
|
||||
{
|
||||
QgsLayoutItem *item = mLayout->itemByUuid( uuid );
|
||||
if ( !item )
|
||||
continue;
|
||||
|
||||
item->setSelected( true );
|
||||
focusItem = item;
|
||||
}
|
||||
mBlockItemOptions = false;
|
||||
|
||||
if ( focusItem )
|
||||
showItemOptions( focusItem );
|
||||
}
|
||||
|
||||
QgsLayoutView *QgsLayoutDesignerDialog::view()
|
||||
{
|
||||
return mView;
|
||||
|
@ -245,6 +245,7 @@ class QgsLayoutDesignerDialog: public QMainWindow, private Ui::QgsLayoutDesigner
|
||||
void addPages();
|
||||
void statusMessageReceived( const QString &message );
|
||||
void dockVisibilityChanged( bool visible );
|
||||
void undoRedoOccurredForItems( const QSet< QString > itemUuids );
|
||||
|
||||
private:
|
||||
|
||||
@ -312,6 +313,8 @@ class QgsLayoutDesignerDialog: public QMainWindow, private Ui::QgsLayoutDesigner
|
||||
};
|
||||
QMap< QString, PanelStatus > mPanelStatus;
|
||||
|
||||
bool mBlockItemOptions = false;
|
||||
|
||||
//! Save window state
|
||||
void saveWindowState();
|
||||
|
||||
|
@ -742,6 +742,7 @@ SET(QGIS_CORE_MOC_HDRS
|
||||
layout/qgslayoutmodel.h
|
||||
layout/qgslayoutpagecollection.h
|
||||
layout/qgslayoutobject.h
|
||||
layout/qgslayoutundostack.h
|
||||
|
||||
symbology/qgscptcityarchive.h
|
||||
symbology/qgssvgcache.h
|
||||
@ -1001,7 +1002,6 @@ SET(QGIS_CORE_HDRS
|
||||
layout/qgslayoutsize.h
|
||||
layout/qgslayoutsnapper.h
|
||||
layout/qgslayoutundocommand.h
|
||||
layout/qgslayoutundostack.h
|
||||
layout/qgslayoututils.h
|
||||
|
||||
metadata/qgslayermetadata.h
|
||||
|
@ -682,7 +682,7 @@ QString QgsLayoutItemPicture::picturePath() const
|
||||
return mSourcePath;
|
||||
}
|
||||
|
||||
bool QgsLayoutItemPicture::writePropertiesToElement( QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context ) const
|
||||
bool QgsLayoutItemPicture::writePropertiesToElement( QDomElement &elem, QDomDocument &, const QgsReadWriteContext &context ) const
|
||||
{
|
||||
QString imagePath = mSourcePath;
|
||||
|
||||
|
@ -72,6 +72,7 @@ void QgsLayoutItemUndoCommand::restoreState( QDomDocument &stateDoc )
|
||||
|
||||
item->readXml( stateDoc.documentElement().firstChild().toElement(), stateDoc, QgsReadWriteContext() );
|
||||
mLayout->project()->setDirty( true );
|
||||
mLayout->undoStack()->notifyUndoRedoOccurred( item );
|
||||
}
|
||||
|
||||
QgsLayoutItem *QgsLayoutItemUndoCommand::recreateItem( int itemType, QgsLayout *layout )
|
||||
|
@ -21,10 +21,11 @@
|
||||
#include <QUndoStack>
|
||||
|
||||
QgsLayoutUndoStack::QgsLayoutUndoStack( QgsLayout *layout )
|
||||
: mLayout( layout )
|
||||
: QObject()
|
||||
, mLayout( layout )
|
||||
, mUndoStack( new QUndoStack( layout ) )
|
||||
{
|
||||
|
||||
connect( mUndoStack.get(), &QUndoStack::indexChanged, this, &QgsLayoutUndoStack::indexChanged );
|
||||
}
|
||||
|
||||
void QgsLayoutUndoStack::beginMacro( const QString &commandText )
|
||||
@ -76,3 +77,17 @@ QUndoStack *QgsLayoutUndoStack::stack()
|
||||
return mUndoStack.get();
|
||||
|
||||
}
|
||||
|
||||
void QgsLayoutUndoStack::notifyUndoRedoOccurred( QgsLayoutItem *item )
|
||||
{
|
||||
mUndoRedoOccurredItemUuids.insert( item->uuid() );
|
||||
}
|
||||
|
||||
void QgsLayoutUndoStack::indexChanged()
|
||||
{
|
||||
if ( mUndoRedoOccurredItemUuids.empty() )
|
||||
return;
|
||||
|
||||
emit undoRedoOccurredForItems( mUndoRedoOccurredItemUuids );
|
||||
mUndoRedoOccurredItemUuids.clear();
|
||||
}
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "qgis.h"
|
||||
#include "qgis_core.h"
|
||||
#include "qgslayoutundocommand.h"
|
||||
#include "qgslayoutitem.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
class QgsLayout;
|
||||
@ -31,8 +33,10 @@ class QUndoStack;
|
||||
* An undo stack for QgsLayouts.
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
class CORE_EXPORT QgsLayoutUndoStack
|
||||
class CORE_EXPORT QgsLayoutUndoStack : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
@ -98,6 +102,23 @@ class CORE_EXPORT QgsLayoutUndoStack
|
||||
*/
|
||||
QUndoStack *stack();
|
||||
|
||||
/**
|
||||
* Notifies the stack that an undo or redo action occurred for a specified \a item.
|
||||
*/
|
||||
void notifyUndoRedoOccurred( QgsLayoutItem *item );
|
||||
|
||||
signals:
|
||||
|
||||
/**
|
||||
* Emitted when an undo or redo action has occurred, which affected a
|
||||
* set of layout \a itemUuids.
|
||||
*/
|
||||
void undoRedoOccurredForItems( const QSet< QString > itemUuids );
|
||||
|
||||
private slots:
|
||||
|
||||
void indexChanged();
|
||||
|
||||
private:
|
||||
|
||||
QgsLayout *mLayout = nullptr;
|
||||
@ -106,6 +127,8 @@ class CORE_EXPORT QgsLayoutUndoStack
|
||||
|
||||
std::vector< std::unique_ptr< QgsAbstractLayoutUndoCommand > > mActiveCommands;
|
||||
|
||||
QSet< QString > mUndoRedoOccurredItemUuids;
|
||||
|
||||
#ifdef SIP_RUN
|
||||
QgsLayoutUndoStack( const QgsLayoutUndoStack &other );
|
||||
#endif
|
||||
|
@ -41,6 +41,7 @@ class TestQgsLayout: public QObject
|
||||
void addItem();
|
||||
void layoutItems();
|
||||
void layoutItemByUuid();
|
||||
void undoRedoOccurred();
|
||||
|
||||
private:
|
||||
QString mReport;
|
||||
@ -419,6 +420,55 @@ void TestQgsLayout::layoutItemByUuid()
|
||||
QCOMPARE( l.itemByUuid( map1->uuid() ), map1 );
|
||||
}
|
||||
|
||||
void TestQgsLayout::undoRedoOccurred()
|
||||
{
|
||||
// test emitting undo/redo occurred signal
|
||||
QgsProject proj;
|
||||
QgsLayout l( &proj );
|
||||
|
||||
QSignalSpy spyOccurred( l.undoStack(), &QgsLayoutUndoStack::undoRedoOccurredForItems );
|
||||
|
||||
QgsLayoutItemShape *item = new QgsLayoutItemShape( &l );
|
||||
l.addLayoutItem( item );
|
||||
|
||||
QCOMPARE( spyOccurred.count(), 0 );
|
||||
//adds a new undo command
|
||||
item->setId( "test" );
|
||||
QCOMPARE( spyOccurred.count(), 0 );
|
||||
|
||||
QgsLayoutItemShape *item2 = new QgsLayoutItemShape( &l );
|
||||
l.addLayoutItem( item2 );
|
||||
item2->setId( "test2" );
|
||||
QCOMPARE( spyOccurred.count(), 0 );
|
||||
|
||||
l.undoStack()->stack()->undo();
|
||||
QCOMPARE( spyOccurred.count(), 1 );
|
||||
QSet< QString > items = qvariant_cast< QSet< QString > >( spyOccurred.at( 0 ).at( 0 ) );
|
||||
QCOMPARE( items, QSet< QString >() << item2->uuid() );
|
||||
|
||||
l.undoStack()->stack()->redo();
|
||||
QCOMPARE( spyOccurred.count(), 2 );
|
||||
items = qvariant_cast< QSet< QString> >( spyOccurred.at( 1 ).at( 0 ) );
|
||||
QCOMPARE( items, QSet< QString >() << item2->uuid() );
|
||||
|
||||
// macro undo
|
||||
l.undoStack()->beginMacro( QString() );
|
||||
item->setId( "new id" );
|
||||
item2->setId( "new id2" );
|
||||
l.undoStack()->endMacro();
|
||||
QCOMPARE( spyOccurred.count(), 2 );
|
||||
|
||||
l.undoStack()->stack()->undo();
|
||||
QCOMPARE( spyOccurred.count(), 3 );
|
||||
items = qvariant_cast< QSet< QString > >( spyOccurred.at( 2 ).at( 0 ) );
|
||||
QCOMPARE( items, QSet< QString >() << item->uuid() << item2->uuid() );
|
||||
l.undoStack()->stack()->redo();
|
||||
QCOMPARE( spyOccurred.count(), 4 );
|
||||
items = qvariant_cast< QSet< QString > >( spyOccurred.at( 3 ).at( 0 ) );
|
||||
QCOMPARE( items, QSet< QString >() << item->uuid() << item2->uuid() );
|
||||
|
||||
}
|
||||
|
||||
|
||||
QGSTEST_MAIN( TestQgsLayout )
|
||||
#include "testqgslayout.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user