Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[feature] CTRL-click in composer to select items below other items (fix
  • Loading branch information
nyalldawson authored and mhugent committed Sep 21, 2013
1 parent e447813 commit aaa2fcf
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 4 deletions.
24 changes: 22 additions & 2 deletions src/core/composer/qgscomposition.cpp
Expand Up @@ -170,10 +170,16 @@ int QgsComposition::numPages() const

QgsComposerItem* QgsComposition::composerItemAt( const QPointF & position )
{
return composerItemAt( position, 0 );
}

QgsComposerItem* QgsComposition::composerItemAt( const QPointF & position, const QgsComposerItem* belowItem )
{
//get a list of items which intersect the specified position, in descending z order
QList<QGraphicsItem*> itemList;
if ( mSelectionTolerance <= 0.0 )
{
itemList = items( position );
itemList = items( position, Qt::IntersectsItemShape, Qt::DescendingOrder );
}
else
{
Expand All @@ -182,13 +188,27 @@ QgsComposerItem* QgsComposition::composerItemAt( const QPointF & position )
}
QList<QGraphicsItem *>::iterator itemIt = itemList.begin();

bool foundBelowItem = false;
for ( ; itemIt != itemList.end(); ++itemIt )
{
QgsComposerItem* composerItem = dynamic_cast<QgsComposerItem *>( *itemIt );
QgsPaperItem* paperItem = dynamic_cast<QgsPaperItem*>( *itemIt );
if ( composerItem && !paperItem )
{
return composerItem;
// If we are not checking for a an item below a specified item, or if we've
// already found that item, then we've found our target
if ( ! belowItem || foundBelowItem )
{
return composerItem;
}
else
{
if ( composerItem == belowItem )
{
//Target item is next in list
foundBelowItem = true;
}
}
}
}
return 0;
Expand Down
5 changes: 5 additions & 0 deletions src/core/composer/qgscomposition.h
Expand Up @@ -131,6 +131,11 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
/**Returns the topmost composer item. Ignores mPaperItem*/
QgsComposerItem* composerItemAt( const QPointF & position );

/**Returns the highest composer item at a specified position which is below a specified item. Ignores mPaperItem
@note Added in QGIS 2.1
*/
QgsComposerItem* composerItemAt( const QPointF & position, const QgsComposerItem* belowItem );

/** Returns the page number (0-bsaed) given a coordinate */
int pageNumberAt( const QPointF& position ) const;

Expand Down
34 changes: 32 additions & 2 deletions src/gui/qgscomposerview.cpp
Expand Up @@ -89,13 +89,43 @@ void QgsComposerView::mousePressEvent( QMouseEvent* e )
//select/deselect items and pass mouse event further
case Select:
{
QgsComposerItem* selectedItem;
QgsComposerItem* previousSelectedItem = 0;

if ( e->modifiers() & Qt::ControlModifier )
{
//CTRL modifier, so we are trying to select the next item below the current one
//first, find currently selected item
QList<QgsComposerItem*> selectedItems = composition()->selectedComposerItems();
if ( selectedItems.size() > 0 )
{
previousSelectedItem = selectedItems.at( 0 );
}
}

if ( !( e->modifiers() & Qt::ShiftModifier ) ) //keep selection if shift key pressed
{
composition()->clearSelection();
}

//select topmost item at position of event
QgsComposerItem* selectedItem = composition()->composerItemAt( scenePoint );
if ( previousSelectedItem )
{
//select highest item just below previously selected item at position of event
selectedItem = composition()->composerItemAt( scenePoint, previousSelectedItem );

//if we didn't find a lower item we'll use the top-most as fall-back
//this duplicates mapinfo/illustrator/etc behaviour where ctrl-clicks are "cyclic"
if ( !selectedItem )
{
selectedItem = composition()->composerItemAt( scenePoint );
}
}
else
{
//select topmost item at position of event
selectedItem = composition()->composerItemAt( scenePoint );
}

if ( !selectedItem )
{
break;
Expand Down

0 comments on commit aaa2fcf

Please sign in to comment.