void QgsLayoutView::invertSelection() { if ( !currentLayout() ) { return; } QgsLayoutItem *focusedItem = nullptr; //check all items in layout const QList<QGraphicsItem *> itemList = currentLayout()->items(); for ( QGraphicsItem *graphicsItem : itemList ) { QgsLayoutItem *item = dynamic_cast<QgsLayoutItem *>( graphicsItem ); QgsLayoutItemPage *paperItem = dynamic_cast<QgsLayoutItemPage *>( graphicsItem ); if ( item && !paperItem ) { //flip selected state for items (and deselect any locked items) if ( item->isSelected() || item->isLocked() ) { item->setSelected( false ); } else { item->setSelected( true ); if ( !focusedItem ) focusedItem = item; } } } if ( focusedItem ) emit itemFocused( focusedItem ); }
void QgsLayoutViewToolSelect::layoutPressEvent( QgsLayoutViewMouseEvent *event ) { if ( mMouseHandles->shouldBlockEvent( event ) ) { //swallow clicks while dragging/resizing items return; } if ( mMouseHandles->isVisible() ) { //selection handles are being shown, get mouse action for current cursor position QgsLayoutMouseHandles::MouseAction mouseAction = mMouseHandles->mouseActionForScenePos( event->layoutPoint() ); if ( mouseAction != QgsLayoutMouseHandles::MoveItem && mouseAction != QgsLayoutMouseHandles::NoAction && mouseAction != QgsLayoutMouseHandles::SelectItem ) { //mouse is over a resize handle, so propagate event onward event->ignore(); return; } } if ( event->button() != Qt::LeftButton ) { event->ignore(); return; } QgsLayoutItem *selectedItem = nullptr; QgsLayoutItem *previousSelectedItem = nullptr; QList<QgsLayoutItem *> selectedItems = layout()->selectedLayoutItems(); if ( event->modifiers() & Qt::ControlModifier ) { //CTRL modifier, so we are trying to select the next item below the current one //first, find currently selected item if ( !selectedItems.isEmpty() ) { previousSelectedItem = selectedItems.at( 0 ); } } if ( previousSelectedItem ) { //select highest item just below previously selected item at position of event selectedItem = layout()->layoutItemAt( event->layoutPoint(), previousSelectedItem, true ); //if we didn't find a lower item we'll use the top-most as fall-back //this duplicates mapinfo/illustrator/etc behavior where ctrl-clicks are "cyclic" if ( !selectedItem ) { selectedItem = layout()->layoutItemAt( event->layoutPoint(), true ); } } else { //select topmost item at position of event selectedItem = layout()->layoutItemAt( event->layoutPoint(), true ); } if ( !selectedItem ) { //not clicking over an item, so start marquee selection mIsSelecting = true; mMousePressStartPos = event->pos(); mRubberBand->start( event->layoutPoint(), nullptr ); return; } if ( ( event->modifiers() & Qt::ShiftModifier ) && ( selectedItem->isSelected() ) ) { //SHIFT-clicking a selected item deselects it selectedItem->setSelected( false ); //Check if we have any remaining selected items, and if so, update the item panel const QList<QgsLayoutItem *> selectedItems = layout()->selectedLayoutItems(); if ( !selectedItems.isEmpty() ) { emit itemFocused( selectedItems.at( 0 ) ); } else { emit itemFocused( nullptr ); } } else { if ( ( !selectedItem->isSelected() ) && //keep selection if an already selected item pressed !( event->modifiers() & Qt::ShiftModifier ) ) //keep selection if shift key pressed { layout()->setSelectedItem( selectedItem ); // clears existing selection } else { selectedItem->setSelected( true ); } event->ignore(); emit itemFocused( selectedItem ); } }