mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
Port select next above/below actions
This commit is contained in:
parent
dbb31253e9
commit
4cba2b90ef
@ -177,6 +177,8 @@ class QgsLayoutView: QGraphicsView
|
||||
Selects all items in the view.
|
||||
.. seealso:: deselectAll()
|
||||
.. seealso:: invertSelection()
|
||||
.. seealso:: selectNextItemAbove()
|
||||
.. seealso:: selectNextItemBelow()
|
||||
%End
|
||||
|
||||
void deselectAll();
|
||||
@ -192,6 +194,22 @@ class QgsLayoutView: QGraphicsView
|
||||
and deselecting and selected items.
|
||||
.. seealso:: selectAll()
|
||||
.. seealso:: deselectAll()
|
||||
%End
|
||||
|
||||
void selectNextItemAbove();
|
||||
%Docstring
|
||||
Selects the next item above the existing selection, by item z order.
|
||||
.. seealso:: selectNextItemBelow()
|
||||
.. seealso:: selectAll()
|
||||
.. seealso:: deselectAll()
|
||||
%End
|
||||
|
||||
void selectNextItemBelow();
|
||||
%Docstring
|
||||
Selects the next item below the existing selection, by item z order.
|
||||
.. seealso:: selectNextItemAbove()
|
||||
.. seealso:: selectAll()
|
||||
.. seealso:: deselectAll()
|
||||
%End
|
||||
|
||||
void viewChanged();
|
||||
|
@ -194,9 +194,14 @@ QgsLayoutDesignerDialog::QgsLayoutDesignerDialog( QWidget *parent, Qt::WindowFla
|
||||
connect( mActionSelectAll, &QAction::triggered, mView, &QgsLayoutView::selectAll );
|
||||
connect( mActionDeselectAll, &QAction::triggered, mView, &QgsLayoutView::deselectAll );
|
||||
connect( mActionInvertSelection, &QAction::triggered, mView, &QgsLayoutView::invertSelection );
|
||||
connect( mActionSelectNextAbove, &QAction::triggered, mView, &QgsLayoutView::selectNextItemAbove );
|
||||
connect( mActionSelectNextBelow, &QAction::triggered, mView, &QgsLayoutView::selectNextItemBelow );
|
||||
|
||||
connect( mActionAddPages, &QAction::triggered, this, &QgsLayoutDesignerDialog::addPages );
|
||||
|
||||
connect( mActionUnlockAll, &QAction::triggered, this, &QgsLayoutDesignerDialog::unlockAllItems );
|
||||
connect( mActionLockItems, &QAction::triggered, this, &QgsLayoutDesignerDialog::lockSelectedItems );
|
||||
|
||||
//create status bar labels
|
||||
mStatusCursorXLabel = new QLabel( mStatusBar );
|
||||
mStatusCursorXLabel->setMinimumWidth( 100 );
|
||||
@ -477,6 +482,22 @@ void QgsLayoutDesignerDialog::snapToItems( bool enabled )
|
||||
mLayout->snapper().setSnapToItems( enabled );
|
||||
}
|
||||
|
||||
void QgsLayoutDesignerDialog::unlockAllItems()
|
||||
{
|
||||
if ( mLayout )
|
||||
{
|
||||
mLayout->unlockAllItems();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsLayoutDesignerDialog::lockSelectedItems()
|
||||
{
|
||||
if ( mLayout )
|
||||
{
|
||||
mLayout->lockSelectedItems();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsLayoutDesignerDialog::closeEvent( QCloseEvent * )
|
||||
{
|
||||
emit aboutToClose();
|
||||
|
@ -149,6 +149,18 @@ class QgsLayoutDesignerDialog: public QMainWindow, private Ui::QgsLayoutDesigner
|
||||
*/
|
||||
void snapToItems( bool enabled );
|
||||
|
||||
/**
|
||||
* Unlocks all locked items in the layout.
|
||||
* \see lockSelectedItems()
|
||||
*/
|
||||
void unlockAllItems();
|
||||
|
||||
/**
|
||||
* Locks any selected items in the layout.
|
||||
* \see unlockAllItems()
|
||||
*/
|
||||
void lockSelectedItems();
|
||||
|
||||
signals:
|
||||
|
||||
/**
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "qgslayoutviewtooltemporarymousepan.h"
|
||||
#include "qgslayoutmousehandles.h"
|
||||
#include "qgslayoutruler.h"
|
||||
#include "qgslayoutmodel.h"
|
||||
#include "qgssettings.h"
|
||||
#include "qgsrectangle.h"
|
||||
#include "qgsapplication.h"
|
||||
@ -353,6 +354,50 @@ void QgsLayoutView::invertSelection()
|
||||
emit itemFocused( focusedItem );
|
||||
}
|
||||
|
||||
|
||||
void selectNextByZOrder( QgsLayout *layout, bool above )
|
||||
{
|
||||
if ( !layout )
|
||||
return;
|
||||
|
||||
QgsLayoutItem *previousSelectedItem = nullptr;
|
||||
const QList<QgsLayoutItem *> selectedItems = layout->selectedLayoutItems();
|
||||
if ( !selectedItems.isEmpty() )
|
||||
{
|
||||
previousSelectedItem = selectedItems.at( 0 );
|
||||
}
|
||||
|
||||
if ( !previousSelectedItem )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//select item with target z value
|
||||
QgsLayoutItem *selectedItem = nullptr;
|
||||
if ( !above )
|
||||
selectedItem = layout->itemsModel()->findItemBelow( previousSelectedItem );
|
||||
else
|
||||
selectedItem = layout->itemsModel()->findItemAbove( previousSelectedItem );
|
||||
|
||||
if ( !selectedItem )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//OK, found a good target item
|
||||
layout->setSelectedItem( selectedItem );
|
||||
}
|
||||
|
||||
void QgsLayoutView::selectNextItemAbove()
|
||||
{
|
||||
selectNextByZOrder( currentLayout(), true );
|
||||
}
|
||||
|
||||
void QgsLayoutView::selectNextItemBelow()
|
||||
{
|
||||
selectNextByZOrder( currentLayout(), false );
|
||||
}
|
||||
|
||||
void QgsLayoutView::mousePressEvent( QMouseEvent *event )
|
||||
{
|
||||
mSnapMarker->setVisible( false );
|
||||
|
@ -219,6 +219,8 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView
|
||||
* Selects all items in the view.
|
||||
* \see deselectAll()
|
||||
* \see invertSelection()
|
||||
* \see selectNextItemAbove()
|
||||
* \see selectNextItemBelow()
|
||||
*/
|
||||
void selectAll();
|
||||
|
||||
@ -237,6 +239,22 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView
|
||||
*/
|
||||
void invertSelection();
|
||||
|
||||
/**
|
||||
* Selects the next item above the existing selection, by item z order.
|
||||
* \see selectNextItemBelow()
|
||||
* \see selectAll()
|
||||
* \see deselectAll()
|
||||
*/
|
||||
void selectNextItemAbove();
|
||||
|
||||
/**
|
||||
* Selects the next item below the existing selection, by item z order.
|
||||
* \see selectNextItemAbove()
|
||||
* \see selectAll()
|
||||
* \see deselectAll()
|
||||
*/
|
||||
void selectNextItemBelow();
|
||||
|
||||
/**
|
||||
* Updates associated rulers and other widgets after view extent or zoom has changed.
|
||||
* This should be called after calling any of the QGraphicsView
|
||||
|
@ -151,9 +151,17 @@
|
||||
<addaction name="mActionSelectNextBelow"/>
|
||||
<addaction name="mActionSelectNextAbove"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuLayout">
|
||||
<property name="title">
|
||||
<string>Layout</string>
|
||||
</property>
|
||||
<addaction name="mActionLockItems"/>
|
||||
<addaction name="mActionUnlockAll"/>
|
||||
</widget>
|
||||
<addaction name="mLayoutMenu"/>
|
||||
<addaction name="menuEdit"/>
|
||||
<addaction name="mMenuView"/>
|
||||
<addaction name="menuLayout"/>
|
||||
<addaction name="mItemMenu"/>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="mNavigationToolbar">
|
||||
@ -171,6 +179,19 @@
|
||||
<addaction name="mActionZoomActual"/>
|
||||
<addaction name="mActionZoomAll"/>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="mActionsToolbar">
|
||||
<property name="windowTitle">
|
||||
<string>toolBar</string>
|
||||
</property>
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
</attribute>
|
||||
<attribute name="toolBarBreak">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<addaction name="mActionLockItems"/>
|
||||
<addaction name="mActionUnlockAll"/>
|
||||
</widget>
|
||||
<action name="mActionClose">
|
||||
<property name="text">
|
||||
<string>&Close</string>
|
||||
@ -536,6 +557,33 @@
|
||||
<string>Ctrl+Alt+]</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="mActionLockItems">
|
||||
<property name="icon">
|
||||
<iconset resource="../../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/locked.svg</normaloff>:/images/themes/default/locked.svg</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Loc&k Selected Items</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+L</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="mActionUnlockAll">
|
||||
<property name="icon">
|
||||
<iconset resource="../../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/unlocked.svg</normaloff>:/images/themes/default/unlocked.svg</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Unl&ock All</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Unlock All Items</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Shift+L</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../../../images/images.qrc"/>
|
||||
|
@ -179,6 +179,78 @@ class TestQgsLayoutView(unittest.TestCase):
|
||||
self.assertFalse(item2.isSelected())
|
||||
self.assertFalse(item3.isSelected()) # locked
|
||||
|
||||
def testSelectNextByZOrder(self):
|
||||
p = QgsProject()
|
||||
l = QgsLayout(p)
|
||||
|
||||
# add some items
|
||||
item1 = QgsLayoutItemMap(l)
|
||||
l.addItem(item1)
|
||||
item2 = QgsLayoutItemMap(l)
|
||||
l.addItem(item2)
|
||||
item3 = QgsLayoutItemMap(l)
|
||||
item3.setLocked(True)
|
||||
l.addItem(item3)
|
||||
|
||||
view = QgsLayoutView()
|
||||
# no layout, no crash
|
||||
view.selectNextItemAbove()
|
||||
view.selectNextItemBelow()
|
||||
|
||||
view.setCurrentLayout(l)
|
||||
|
||||
focused_item_spy = QSignalSpy(view.itemFocused)
|
||||
|
||||
# no selection
|
||||
view.selectNextItemAbove()
|
||||
view.selectNextItemBelow()
|
||||
self.assertEqual(len(focused_item_spy), 0)
|
||||
|
||||
l.setSelectedItem(item1)
|
||||
self.assertEqual(len(focused_item_spy), 1)
|
||||
# already bottom most
|
||||
view.selectNextItemBelow()
|
||||
self.assertTrue(item1.isSelected())
|
||||
self.assertFalse(item2.isSelected())
|
||||
self.assertFalse(item3.isSelected())
|
||||
self.assertEqual(len(focused_item_spy), 1)
|
||||
|
||||
view.selectNextItemAbove()
|
||||
self.assertFalse(item1.isSelected())
|
||||
self.assertTrue(item2.isSelected())
|
||||
self.assertFalse(item3.isSelected())
|
||||
self.assertEqual(len(focused_item_spy), 2)
|
||||
|
||||
view.selectNextItemAbove()
|
||||
self.assertFalse(item1.isSelected())
|
||||
self.assertFalse(item2.isSelected())
|
||||
self.assertTrue(item3.isSelected())
|
||||
self.assertEqual(len(focused_item_spy), 3)
|
||||
|
||||
view.selectNextItemAbove() # already top most
|
||||
self.assertFalse(item1.isSelected())
|
||||
self.assertFalse(item2.isSelected())
|
||||
self.assertTrue(item3.isSelected())
|
||||
self.assertEqual(len(focused_item_spy), 3)
|
||||
|
||||
view.selectNextItemBelow()
|
||||
self.assertFalse(item1.isSelected())
|
||||
self.assertTrue(item2.isSelected())
|
||||
self.assertFalse(item3.isSelected())
|
||||
self.assertEqual(len(focused_item_spy), 4)
|
||||
|
||||
view.selectNextItemBelow()
|
||||
self.assertTrue(item1.isSelected())
|
||||
self.assertFalse(item2.isSelected())
|
||||
self.assertFalse(item3.isSelected())
|
||||
self.assertEqual(len(focused_item_spy), 5)
|
||||
|
||||
view.selectNextItemBelow() # back to bottom most
|
||||
self.assertTrue(item1.isSelected())
|
||||
self.assertFalse(item2.isSelected())
|
||||
self.assertFalse(item3.isSelected())
|
||||
self.assertEqual(len(focused_item_spy), 5)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Loading…
x
Reference in New Issue
Block a user