void QgsComposerMouseHandles::selectionChanged() { //listen out for selected items' size and rotation changed signals QList<QGraphicsItem *> itemList = composition()->items(); QList<QGraphicsItem *>::iterator itemIt = itemList.begin(); for ( ; itemIt != itemList.end(); ++itemIt ) { QgsComposerItem* item = dynamic_cast<QgsComposerItem *>( *itemIt ); if ( item ) { if ( item->selected() ) { QObject::connect( item, SIGNAL( sizeChanged() ), this, SLOT( selectedItemSizeChanged() ) ); QObject::connect( item, SIGNAL( itemRotationChanged( double ) ), this, SLOT( selectedItemRotationChanged() ) ); QObject::connect( item, SIGNAL( frameChanged() ), this, SLOT( selectedItemSizeChanged() ) ); QObject::connect( item, SIGNAL( lockChanged() ), this, SLOT( selectedItemSizeChanged() ) ); } else { QObject::disconnect( item, SIGNAL( sizeChanged() ), this, nullptr ); QObject::disconnect( item, SIGNAL( itemRotationChanged( double ) ), this, nullptr ); QObject::disconnect( item, SIGNAL( frameChanged() ), this, nullptr ); QObject::disconnect( item, SIGNAL( lockChanged() ), this, nullptr ); } }
void QgsComposerView::selectAll() { if ( !composition() ) { return; } //select all items in composer QList<QGraphicsItem *> itemList = composition()->items(); QList<QGraphicsItem *>::iterator itemIt = itemList.begin(); for ( ; itemIt != itemList.end(); ++itemIt ) { QgsComposerItem* mypItem = dynamic_cast<QgsComposerItem *>( *itemIt ); QgsPaperItem* paperItem = dynamic_cast<QgsPaperItem*>( *itemIt ); if ( mypItem && !paperItem ) { if ( !mypItem->positionLock() ) { mypItem->setSelected( true ); } else { //deselect all locked items mypItem->setSelected( false ); } emit selectedItemChanged( mypItem ); } } }
void QgsComposerView::selectInvert() { if ( !composition() ) { return; } //check all items in composer QList<QGraphicsItem *> itemList = composition()->items(); QList<QGraphicsItem *>::iterator itemIt = itemList.begin(); for ( ; itemIt != itemList.end(); ++itemIt ) { QgsComposerItem* mypItem = dynamic_cast<QgsComposerItem *>( *itemIt ); QgsPaperItem* paperItem = dynamic_cast<QgsPaperItem*>( *itemIt ); if ( mypItem && !paperItem ) { //flip selected state for items (and deselect any locked items) if ( mypItem->selected() || mypItem->positionLock() ) { mypItem->setSelected( false ); } else { mypItem->setSelected( true ); emit selectedItemChanged( mypItem ); } } } }
bool QgsComposerModel::setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole ) { Q_UNUSED( role ); if ( !index.isValid() ) return false; QgsComposerItem *item = itemFromIndex( index ); if ( !item ) { return false; } switch ( index.column() ) { case Visibility: //first column is item visibility item->setVisibility( value.toBool() ); return true; case LockStatus: //second column is item lock state item->setPositionLock( value.toBool() ); return true; case ItemId: //last column is item id item->setId( value.toString() ); return true; } return false; }
void QgsComposerItemCommand::restoreState( QDomDocument& stateDoc ) const { QgsComposerItem* destItem = item(); if ( !destItem ) { return; } destItem->readXML( stateDoc.documentElement().firstChild().toElement(), stateDoc ); destItem->repaint(); QgsProject::instance()->dirty( true ); }
bool QgsComposerProxyModel::filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const { //get QgsComposerItem corresponding to row QModelIndex index = sourceModel()->index( source_row, 0, source_parent ); QgsComposerItem *item = itemFromSourceIndex( index ); if ( !item ) return false; // specific exceptions if ( mExceptedList.contains( item ) ) return false; // filter by type if ( mItemTypeFilter != QgsComposerItem::ComposerItem && item->type() != mItemTypeFilter ) return false; return true; }
void QgsComposition::updateZValues() { int counter = 1; QLinkedList<QgsComposerItem*>::iterator it = mItemZList.begin(); QgsComposerItem* currentItem = 0; QUndoCommand* parentCommand = new QUndoCommand( tr( "Item z-order changed" ) ); for ( ; it != mItemZList.end(); ++it ) { currentItem = *it; if ( currentItem ) { QgsComposerItemCommand* subcommand = new QgsComposerItemCommand( *it, "", parentCommand ); subcommand->savePreviousState(); currentItem->setZValue( counter ); subcommand->saveAfterState(); } ++counter; } mUndoStack.push( parentCommand ); }
void QgsComposerView::wheelEvent( QWheelEvent* event ) { if ( currentTool() == MoveItemContent ) { //move item content tool, so scroll events get handled by the selected composer item QPointF scenePoint = mapToScene( event->pos() ); //select topmost item at position of event QgsComposerItem* theItem = composition()->composerItemAt( scenePoint ); if ( theItem ) { if ( theItem->isSelected() ) { QPointF itemPoint = theItem->mapFromScene( scenePoint ); theItem->beginCommand( tr( "Zoom item content" ) ); theItem->zoomContent( event->delta(), itemPoint.x(), itemPoint.y() ); theItem->endCommand(); } } } else { //not using move item content tool, so zoom whole composition wheelZoom( event ); } }
void QgsComposerModel::rebuildZList() { QList<QgsComposerItem *> sortedList; //rebuild the item z order list based on the current zValues of items in the scene //get items in descending zValue order QList<QGraphicsItem *> itemList = mComposition->items( Qt::DescendingOrder ); QList<QGraphicsItem *>::iterator itemIt = itemList.begin(); for ( ; itemIt != itemList.end(); ++itemIt ) { QgsComposerItem *composerItem = dynamic_cast<QgsComposerItem *>( *itemIt ); if ( composerItem ) { if ( composerItem->type() != QgsComposerItem::ComposerPaper ) { sortedList.append( composerItem ); } } } mItemZList = sortedList; rebuildSceneItemList(); }
QVariant QgsComposerModel::data( const QModelIndex &index, int role ) const { if ( !index.isValid() ) return QVariant(); QgsComposerItem *item = itemFromIndex( index ); if ( !item ) { return QVariant(); } switch ( role ) { case Qt::DisplayRole: if ( index.column() == ItemId ) { return item->displayName(); } else { return QVariant(); } case Qt::EditRole: if ( index.column() == ItemId ) { return item->id(); } else { return QVariant(); } case Qt::UserRole: //store item uuid in userrole so we can later get the QModelIndex for a specific item return item->uuid(); case Qt::TextAlignmentRole: return Qt::AlignLeft & Qt::AlignVCenter; case Qt::CheckStateRole: switch ( index.column() ) { case Visibility: //column 0 is visibility of item return item->isVisible() ? Qt::Checked : Qt::Unchecked; case LockStatus: //column 1 is locked state of item return item->positionLock() ? Qt::Checked : Qt::Unchecked; default: return QVariant(); } default: return QVariant(); } }
QMimeData *QgsComposerModel::mimeData( const QModelIndexList &indexes ) const { QMimeData *mimeData = new QMimeData(); QByteArray encodedData; QDataStream stream( &encodedData, QIODevice::WriteOnly ); Q_FOREACH ( const QModelIndex &index, indexes ) { if ( index.isValid() && index.column() == ItemId ) { QgsComposerItem *item = itemFromIndex( index ); if ( !item ) { continue; } QString text = item->uuid(); stream << text; } } mimeData->setData( QStringLiteral( "application/x-vnd.qgis.qgis.composeritemid" ), encodedData ); return mimeData; }
void QgsComposerView::wheelEvent( QWheelEvent* event ) { QPointF scenePoint = mapToScene( event->pos() ); //select topmost item at position of event QgsComposerItem* theItem = composition()->composerItemAt( scenePoint ); if ( theItem ) { if ( theItem->isSelected() ) { QPointF itemPoint = theItem->mapFromScene( scenePoint ); theItem->beginCommand( tr( "Zoom item content" ) ); theItem->zoomContent( event->delta(), itemPoint.x(), itemPoint.y() ); theItem->endCommand(); } } }
int QgsComposition::boundingRectOfSelectedItems( QRectF& bRect ) { QList<QgsComposerItem*> selectedItems = selectedComposerItems(); if ( selectedItems.size() < 1 ) { return 1; } //set the box to the first item QgsComposerItem* currentItem = selectedItems.at( 0 ); double minX = currentItem->transform().dx(); double minY = currentItem->transform().dy(); double maxX = minX + currentItem->rect().width(); double maxY = minY + currentItem->rect().height(); double currentMinX, currentMinY, currentMaxX, currentMaxY; for ( int i = 1; i < selectedItems.size(); ++i ) { currentItem = selectedItems.at( i ); currentMinX = currentItem->transform().dx(); currentMinY = currentItem->transform().dy(); currentMaxX = currentMinX + currentItem->rect().width(); currentMaxY = currentMinY + currentItem->rect().height(); if ( currentMinX < minX ) minX = currentMinX; if ( currentMaxX > maxX ) maxX = currentMaxX; if ( currentMinY < minY ) minY = currentMinY; if ( currentMaxY > maxY ) maxY = currentMaxY; } bRect.setTopLeft( QPointF( minX, minY ) ); bRect.setBottomRight( QPointF( maxX, maxY ) ); return 0; }
void QgsComposerView::wheelEvent( QWheelEvent* event ) { if ( mRubberBandItem || mRubberBandLineItem ) { //ignore wheel events while marquee operations are active (eg, creating new item) return; } if ( composition()->selectionHandles()->isDragging() || composition()->selectionHandles()->isResizing() ) { //ignore wheel events while dragging/resizing items return; } if ( currentTool() == MoveItemContent ) { //move item content tool, so scroll events get handled by the selected composer item QPointF scenePoint = mapToScene( event->pos() ); //select topmost item at position of event QgsComposerItem* theItem = composition()->composerItemAt( scenePoint, true ); if ( theItem ) { if ( theItem->isSelected() ) { QPointF itemPoint = theItem->mapFromScene( scenePoint ); theItem->beginCommand( tr( "Zoom item content" ) ); theItem->zoomContent( event->delta(), itemPoint.x(), itemPoint.y() ); theItem->endCommand(); } } } else { //not using move item content tool, so zoom whole composition wheelZoom( event ); } }
void QgsComposerView::mousePressEvent( QMouseEvent* e ) { if ( !composition() ) { return; } QPointF scenePoint = mapToScene( e->pos() ); QPointF snappedScenePoint = composition()->snapPointToGrid( scenePoint ); mMousePressStartPos = e->pos(); //lock/unlock position of item with right click if ( e->button() == Qt::RightButton ) { QgsComposerItem* selectedItem = composition()->composerItemAt( scenePoint ); if ( selectedItem ) { bool lock = selectedItem->positionLock() ? false : true; selectedItem->setPositionLock( lock ); selectedItem->update(); } return; } else if ( e->button() == Qt::MidButton ) { //pan composer with middle button mPanning = true; mMouseLastXY = e->pos(); if ( composition() ) { //lock cursor to closed hand cursor composition()->setPreventCursorChange( true ); } viewport()->setCursor( Qt::ClosedHandCursor ); return; } switch ( mCurrentTool ) { //select/deselect items and pass mouse event further case Select: { //check if we are clicking on a selection handle if ( composition()->selectionHandles()->isVisible() ) { //selection handles are being shown, get mouse action for current cursor position QgsComposerMouseHandles::MouseAction mouseAction = composition()->selectionHandles()->mouseActionForScenePos( scenePoint ); if ( mouseAction != QgsComposerMouseHandles::MoveItem && mouseAction != QgsComposerMouseHandles::NoAction && mouseAction != QgsComposerMouseHandles::SelectItem ) { //mouse is over a resize handle, so propagate event onward QGraphicsView::mousePressEvent( e ); return; } } QgsComposerItem* selectedItem = 0; 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 ( 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 ) { //not clicking over an item, so start marquee selection startMarqueeSelect( scenePoint ); break; } if (( !selectedItem->selected() ) && //keep selection if an already selected item pressed !( e->modifiers() & Qt::ShiftModifier ) ) //keep selection if shift key pressed { composition()->clearSelection(); } if (( e->modifiers() & Qt::ShiftModifier ) && ( selectedItem->selected() ) ) { //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 QList<QgsComposerItem*> selectedItems = composition()->selectedComposerItems(); if ( selectedItems.size() > 0 ) { emit selectedItemChanged( selectedItems.at( 0 ) ); } } else { selectedItem->setSelected( true ); QGraphicsView::mousePressEvent( e ); emit selectedItemChanged( selectedItem ); } break; } case Zoom: { if ( !( e->modifiers() & Qt::ShiftModifier ) ) { //zoom in action startMarqueeZoom( scenePoint ); } else { //zoom out action, so zoom out and recenter on clicked point double scaleFactor = 2; //get current visible part of scene QRect viewportRect( 0, 0, viewport()->width(), viewport()->height() ); QgsRectangle visibleRect = QgsRectangle( mapToScene( viewportRect ).boundingRect() ); //transform the mouse pos to scene coordinates QPointF scenePoint = mapToScene( e->pos() ); visibleRect.scale( scaleFactor, scenePoint.x(), scenePoint.y() ); QRectF boundsRect = visibleRect.toRectF(); //zoom view to fit desired bounds fitInView( boundsRect, Qt::KeepAspectRatio ); } break; } case Pan: { //pan action mPanning = true; mMouseLastXY = e->pos(); viewport()->setCursor( Qt::ClosedHandCursor ); break; } case MoveItemContent: { //get a list of items at clicked position QList<QGraphicsItem *> itemsAtCursorPos = items( e->pos() ); if ( itemsAtCursorPos.size() == 0 ) { //no items at clicked position return; } //find highest QgsComposerItem at clicked position //(other graphics items may be higher, eg selection handles) QList<QGraphicsItem*>::iterator itemIter = itemsAtCursorPos.begin(); for ( ; itemIter != itemsAtCursorPos.end(); ++itemIter ) { QgsComposerItem* item = dynamic_cast<QgsComposerItem *>(( *itemIter ) ); if ( item ) { //we've found the highest QgsComposerItem mMoveContentStartPos = scenePoint; mMoveContentItem = item; break; } } //no QgsComposerItem at clicked position return; } case AddArrow: { mRubberBandStartPos = QPointF( snappedScenePoint.x(), snappedScenePoint.y() ); mRubberBandLineItem = new QGraphicsLineItem( snappedScenePoint.x(), snappedScenePoint.y(), snappedScenePoint.x(), snappedScenePoint.y() ); mRubberBandLineItem->setZValue( 1000 ); scene()->addItem( mRubberBandLineItem ); scene()->update(); break; } //create rubber band for map and ellipse items case AddMap: case AddRectangle: case AddTriangle: case AddEllipse: case AddHtml: { QTransform t; mRubberBandItem = new QGraphicsRectItem( 0, 0, 0, 0 ); mRubberBandStartPos = QPointF( snappedScenePoint.x(), snappedScenePoint.y() ); t.translate( snappedScenePoint.x(), snappedScenePoint.y() ); mRubberBandItem->setTransform( t ); mRubberBandItem->setZValue( 1000 ); scene()->addItem( mRubberBandItem ); scene()->update(); } break; case AddLabel: if ( composition() ) { QgsComposerLabel* newLabelItem = new QgsComposerLabel( composition() ); newLabelItem->setText( tr( "QGIS" ) ); newLabelItem->adjustSizeToText(); newLabelItem->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), newLabelItem->rect().width(), newLabelItem->rect().height() ) ); composition()->addComposerLabel( newLabelItem ); composition()->clearSelection(); newLabelItem->setSelected( true ); emit selectedItemChanged( newLabelItem ); emit actionFinished(); composition()->pushAddRemoveCommand( newLabelItem, tr( "Label added" ) ); } break; case AddScalebar: if ( composition() ) { QgsComposerScaleBar* newScaleBar = new QgsComposerScaleBar( composition() ); newScaleBar->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), 20, 20 ) ); composition()->addComposerScaleBar( newScaleBar ); QList<const QgsComposerMap*> mapItemList = composition()->composerMapItems(); if ( mapItemList.size() > 0 ) { newScaleBar->setComposerMap( mapItemList.at( 0 ) ); } newScaleBar->applyDefaultSize(); //4 segments, 1/5 of composer map width composition()->clearSelection(); newScaleBar->setSelected( true ); emit selectedItemChanged( newScaleBar ); emit actionFinished(); composition()->pushAddRemoveCommand( newScaleBar, tr( "Scale bar added" ) ); } break; case AddLegend: { if ( composition() ) { QgsComposerLegend* newLegend = new QgsComposerLegend( composition() ); newLegend->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), newLegend->rect().width(), newLegend->rect().height() ) ); composition()->addComposerLegend( newLegend ); newLegend->updateLegend(); composition()->clearSelection(); newLegend->setSelected( true ); emit selectedItemChanged( newLegend ); emit actionFinished(); composition()->pushAddRemoveCommand( newLegend, tr( "Legend added" ) ); } break; } case AddPicture: if ( composition() ) { QgsComposerPicture* newPicture = new QgsComposerPicture( composition() ); newPicture->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), 30, 30 ) ); composition()->addComposerPicture( newPicture ); composition()->clearSelection(); newPicture->setSelected( true ); emit selectedItemChanged( newPicture ); emit actionFinished(); composition()->pushAddRemoveCommand( newPicture, tr( "Picture added" ) ); } break; case AddTable: if ( composition() ) { QgsComposerAttributeTable* newTable = new QgsComposerAttributeTable( composition() ); newTable->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), 50, 50 ) ); composition()->addComposerTable( newTable ); composition()->clearSelection(); newTable->setSelected( true ); emit selectedItemChanged( newTable ); emit actionFinished(); composition()->pushAddRemoveCommand( newTable, tr( "Table added" ) ); } break; default: break; } }
void QgsComposerItem::changeItemRectangle( const QPointF& currentPosition, const QPointF& mouseMoveStartPos, const QGraphicsRectItem* originalItem, double dx, double dy, QGraphicsRectItem* changeItem ) { Q_UNUSED( dx ); Q_UNUSED( dy ); if ( !changeItem || !originalItem || !mComposition ) { return; } //test if change item is a composer item. If so, prefer call to setSceneRect() instead of setTransform() and setRect() QgsComposerItem* changeComposerItem = dynamic_cast<QgsComposerItem *>( changeItem ); double mx = 0.0, my = 0.0, rx = 0.0, ry = 0.0; QPointF snappedPosition = mComposition->snapPointToGrid( currentPosition ); //double diffX = snappedPosition.x() - mouseMoveStartPos.x(); //double diffY = snappedPosition.y() - mouseMoveStartPos.y(); double diffX = 0; double diffY = 0; switch ( mCurrentMouseMoveAction ) { //vertical resize case QgsComposerItem::ResizeUp: diffY = snappedPosition.y() - originalItem->transform().dy(); mx = 0; my = diffY; rx = 0; ry = -diffY; break; case QgsComposerItem::ResizeDown: diffY = snappedPosition.y() - ( originalItem->transform().dy() + originalItem->rect().height() ); mx = 0; my = 0; rx = 0; ry = diffY; break; //horizontal resize case QgsComposerItem::ResizeLeft: diffX = snappedPosition.x() - originalItem->transform().dx(); mx = diffX, my = 0; rx = -diffX; ry = 0; break; case QgsComposerItem::ResizeRight: diffX = snappedPosition.x() - ( originalItem->transform().dx() + originalItem->rect().width() ); mx = 0; my = 0; rx = diffX, ry = 0; break; //diagonal resize case QgsComposerItem::ResizeLeftUp: diffX = snappedPosition.x() - originalItem->transform().dx(); diffY = snappedPosition.y() - originalItem->transform().dy(); mx = diffX, my = diffY; rx = -diffX; ry = -diffY; break; case QgsComposerItem::ResizeRightDown: diffX = snappedPosition.x() - ( originalItem->transform().dx() + originalItem->rect().width() ); diffY = snappedPosition.y() - ( originalItem->transform().dy() + originalItem->rect().height() ); mx = 0; my = 0; rx = diffX, ry = diffY; break; case QgsComposerItem::ResizeRightUp: diffX = snappedPosition.x() - ( originalItem->transform().dx() + originalItem->rect().width() ); diffY = snappedPosition.y() - originalItem->transform().dy(); mx = 0; my = diffY, rx = diffX, ry = -diffY; break; case QgsComposerItem::ResizeLeftDown: diffX = snappedPosition.x() - originalItem->transform().dx(); diffY = snappedPosition.y() - ( originalItem->transform().dy() + originalItem->rect().height() ); mx = diffX, my = 0; rx = -diffX; ry = diffY; break; case QgsComposerItem::MoveItem: { //calculate total move difference double moveX = currentPosition.x() - mouseMoveStartPos.x(); double moveY = currentPosition.y() - mouseMoveStartPos.y(); QPointF upperLeftPoint( originalItem->transform().dx() + moveX, originalItem->transform().dy() + moveY ); QPointF snappedLeftPoint = mComposition->snapPointToGrid( upperLeftPoint ); double moveRectX = snappedLeftPoint.x() - originalItem->transform().dx(); double moveRectY = snappedLeftPoint.y() - originalItem->transform().dy(); if ( !changeComposerItem ) { QTransform moveTransform; moveTransform.translate( originalItem->transform().dx() + moveRectX, originalItem->transform().dy() + moveRectY ); changeItem->setTransform( moveTransform ); } else //for composer items, we prefer setSceneRect as subclasses can implement custom behaviour (e.g. item group) { changeComposerItem->setSceneRect( QRectF( originalItem->transform().dx() + moveRectX, originalItem->transform().dy() + moveRectY, originalItem->rect().width(), originalItem->rect().height() ) ); changeComposerItem->updateItem(); } } return; case QgsComposerItem::NoAction: break; } if ( !changeComposerItem ) { QTransform itemTransform; itemTransform.translate( originalItem->transform().dx() + mx, originalItem->transform().dy() + my ); changeItem->setTransform( itemTransform ); QRectF itemRect( 0, 0, originalItem->rect().width() + rx, originalItem->rect().height() + ry ); changeItem->setRect( itemRect ); } else //for composer items, we prefer setSceneRect as subclasses can implement custom behaviour (e.g. item group) { changeComposerItem->setSceneRect( QRectF( originalItem->transform().dx() + mx, originalItem->transform().dy() + my, originalItem->rect().width() + rx, originalItem->rect().height() + ry ) ); changeComposerItem->updateItem(); } }
void QgsComposerView::mousePressEvent( QMouseEvent* e ) { if ( !composition() ) { return; } QPointF scenePoint = mapToScene( e->pos() ); QPointF snappedScenePoint = composition()->snapPointToGrid( scenePoint ); //lock/unlock position of item with right click if ( e->button() == Qt::RightButton ) { QgsComposerItem* selectedItem = composition()->composerItemAt( scenePoint ); if ( selectedItem ) { bool lock = selectedItem->positionLock() ? false : true; selectedItem->setPositionLock( lock ); selectedItem->update(); //make sure the new cursor is correct QPointF itemPoint = selectedItem->mapFromScene( scenePoint ); selectedItem->updateCursor( itemPoint ); } return; } switch ( mCurrentTool ) { //select/deselect items and pass mouse event further case Select: { if ( !mShiftKeyPressed ) //keep selection if shift key pressed { composition()->clearSelection(); } //select topmost item at position of event QgsComposerItem* selectedItem = composition()->composerItemAt( scenePoint ); if ( !selectedItem ) { break; } selectedItem->setSelected( true ); QGraphicsView::mousePressEvent( e ); emit selectedItemChanged( selectedItem ); break; } case MoveItemContent: { //store item as member if it is selected and cursor is over item QgsComposerItem* item = dynamic_cast<QgsComposerItem *>( itemAt( e->pos() ) ); if ( item ) { mMoveContentStartPos = scenePoint; } mMoveContentItem = item; break; } case AddArrow: { mRubberBandStartPos = QPointF( snappedScenePoint.x(), snappedScenePoint.y() ); mRubberBandLineItem = new QGraphicsLineItem( snappedScenePoint.x(), snappedScenePoint.y(), snappedScenePoint.x(), snappedScenePoint.y() ); mRubberBandLineItem->setZValue( 100 ); scene()->addItem( mRubberBandLineItem ); scene()->update(); break; } //create rubber band for map and ellipse items case AddMap: case AddShape: { QTransform t; mRubberBandItem = new QGraphicsRectItem( 0, 0, 0, 0 ); mRubberBandStartPos = QPointF( snappedScenePoint.x(), snappedScenePoint.y() ); t.translate( snappedScenePoint.x(), snappedScenePoint.y() ); mRubberBandItem->setTransform( t ); mRubberBandItem->setZValue( 100 ); scene()->addItem( mRubberBandItem ); scene()->update(); } break; case AddLabel: if ( composition() ) { QgsComposerLabel* newLabelItem = new QgsComposerLabel( composition() ); newLabelItem->setText( tr( "Quantum GIS" ) ); newLabelItem->adjustSizeToText(); newLabelItem->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), newLabelItem->rect().width(), newLabelItem->rect().height() ) ); composition()->addComposerLabel( newLabelItem ); emit actionFinished(); composition()->pushAddRemoveCommand( newLabelItem, tr( "Label added" ) ); } break; case AddScalebar: if ( composition() ) { QgsComposerScaleBar* newScaleBar = new QgsComposerScaleBar( composition() ); newScaleBar->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), 20, 20 ) ); composition()->addComposerScaleBar( newScaleBar ); QList<const QgsComposerMap*> mapItemList = composition()->composerMapItems(); if ( mapItemList.size() > 0 ) { newScaleBar->setComposerMap( mapItemList.at( 0 ) ); } newScaleBar->applyDefaultSize(); //4 segments, 1/5 of composer map width emit actionFinished(); composition()->pushAddRemoveCommand( newScaleBar, tr( "Scale bar added" ) ); } break; case AddLegend: { if ( composition() ) { QgsComposerLegend* newLegend = new QgsComposerLegend( composition() ); newLegend->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), newLegend->rect().width(), newLegend->rect().height() ) ); composition()->addComposerLegend( newLegend ); newLegend->updateLegend(); emit actionFinished(); composition()->pushAddRemoveCommand( newLegend, tr( "Legend added" ) ); } break; } case AddPicture: if ( composition() ) { QgsComposerPicture* newPicture = new QgsComposerPicture( composition() ); newPicture->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), 30, 30 ) ); composition()->addComposerPicture( newPicture ); emit actionFinished(); composition()->pushAddRemoveCommand( newPicture, tr( "Picture added" ) ); } break; case AddTable: if ( composition() ) { QgsComposerAttributeTable* newTable = new QgsComposerAttributeTable( composition() ); newTable->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), 50, 50 ) ); composition()->addComposerTable( newTable ); emit actionFinished(); composition()->pushAddRemoveCommand( newTable, tr( "Table added" ) ); } break; default: break; } }
QVariant QgsComposerModel::data( const QModelIndex &index, int role ) const { if ( !index.isValid() ) return QVariant(); QgsComposerItem *item = itemFromIndex( index ); if ( !item ) { return QVariant(); } switch ( role ) { case Qt::DisplayRole: if ( index.column() == ItemId ) { return item->displayName(); } else { return QVariant(); } case Qt::EditRole: if ( index.column() == ItemId ) { return item->id(); } else { return QVariant(); } case Qt::UserRole: //store item uuid in userrole so we can later get the QModelIndex for a specific item return item->uuid(); case Qt::UserRole+1: //user role stores reference in column object return qVariantFromValue( qobject_cast<QObject *>( item ) ); case Qt::TextAlignmentRole: return Qt::AlignLeft & Qt::AlignVCenter; case Qt::CheckStateRole: switch ( index.column() ) { case Visibility: //column 0 is visibility of item return item->isVisible() ? Qt::Checked : Qt::Unchecked; case LockStatus: //column 1 is locked state of item return item->positionLock() ? Qt::Checked : Qt::Unchecked; default: return QVariant(); } case Qt::FontRole: if ( index.column() == ItemId && item->isSelected() ) { //draw name of selected items in bold QFont boldFont; boldFont.setBold( true ); return boldFont; } return QVariant(); default: return QVariant(); } }
void QgsComposerItem::changeItemRectangle( const QPointF& currentPosition, const QPointF& mouseMoveStartPos, const QGraphicsRectItem* originalItem, double dx, double dy, QGraphicsRectItem* changeItem ) { Q_UNUSED( dx ); Q_UNUSED( dy ); if ( !changeItem || !originalItem || !mComposition ) { return; } //test if change item is a composer item. If so, prefer call to setSceneRect() instead of setTransform() and setRect() QgsComposerItem* changeComposerItem = dynamic_cast<QgsComposerItem *>( changeItem ); double mx = 0.0, my = 0.0, rx = 0.0, ry = 0.0; QPointF snappedPosition = mComposition->snapPointToGrid( currentPosition ); //snap to grid and align to other items if ( mComposition->alignmentSnap() && mCurrentMouseMoveAction != QgsComposerItem::MoveItem ) { double alignX = 0; double alignY = 0; snappedPosition = mComposition->alignPos( snappedPosition, dynamic_cast<const QgsComposerItem*>( originalItem ), alignX, alignY ); if ( alignX != -1 ) { QGraphicsLineItem* item = hAlignSnapItem(); item->setLine( QLineF( alignX, 0, alignX, mComposition->paperHeight() ) ); item->show(); } else { deleteHAlignSnapItem(); } if ( alignY != -1 ) { QGraphicsLineItem* item = vAlignSnapItem(); item->setLine( QLineF( 0, alignY, mComposition->paperWidth(), alignY ) ); item->show(); } else { deleteVAlignSnapItem(); } } double diffX = 0; double diffY = 0; switch ( mCurrentMouseMoveAction ) { //vertical resize case QgsComposerItem::ResizeUp: diffY = snappedPosition.y() - originalItem->transform().dy(); mx = 0; my = diffY; rx = 0; ry = -diffY; break; case QgsComposerItem::ResizeDown: diffY = snappedPosition.y() - ( originalItem->transform().dy() + originalItem->rect().height() ); mx = 0; my = 0; rx = 0; ry = diffY; break; //horizontal resize case QgsComposerItem::ResizeLeft: diffX = snappedPosition.x() - originalItem->transform().dx(); mx = diffX, my = 0; rx = -diffX; ry = 0; break; case QgsComposerItem::ResizeRight: diffX = snappedPosition.x() - ( originalItem->transform().dx() + originalItem->rect().width() ); mx = 0; my = 0; rx = diffX, ry = 0; break; //diagonal resize case QgsComposerItem::ResizeLeftUp: diffX = snappedPosition.x() - originalItem->transform().dx(); diffY = snappedPosition.y() - originalItem->transform().dy(); mx = diffX, my = diffY; rx = -diffX; ry = -diffY; break; case QgsComposerItem::ResizeRightDown: diffX = snappedPosition.x() - ( originalItem->transform().dx() + originalItem->rect().width() ); diffY = snappedPosition.y() - ( originalItem->transform().dy() + originalItem->rect().height() ); mx = 0; my = 0; rx = diffX, ry = diffY; break; case QgsComposerItem::ResizeRightUp: diffX = snappedPosition.x() - ( originalItem->transform().dx() + originalItem->rect().width() ); diffY = snappedPosition.y() - originalItem->transform().dy(); mx = 0; my = diffY, rx = diffX, ry = -diffY; break; case QgsComposerItem::ResizeLeftDown: diffX = snappedPosition.x() - originalItem->transform().dx(); diffY = snappedPosition.y() - ( originalItem->transform().dy() + originalItem->rect().height() ); mx = diffX, my = 0; rx = -diffX; ry = diffY; break; case QgsComposerItem::MoveItem: { //calculate total move difference double moveX = currentPosition.x() - mouseMoveStartPos.x(); double moveY = currentPosition.y() - mouseMoveStartPos.y(); QPointF upperLeftPoint( originalItem->transform().dx() + moveX, originalItem->transform().dy() + moveY ); QPointF snappedLeftPoint = mComposition->snapPointToGrid( upperLeftPoint ); if ( snappedLeftPoint != upperLeftPoint ) //don't do align snap if grid snap has been done { deleteAlignItems(); } else if ( mComposition->alignmentSnap() ) //align item { double alignX = 0; double alignY = 0; snappedLeftPoint = mComposition->alignItem( dynamic_cast<const QgsComposerItem*>( originalItem ), alignX, alignY, moveX, moveY ); if ( alignX != -1 ) { QGraphicsLineItem* item = hAlignSnapItem(); int numPages = mComposition->numPages(); double yLineCoord = 300; //default in case there is no single page if ( numPages > 0 ) { yLineCoord = mComposition->paperHeight() * numPages + mComposition->spaceBetweenPages() * ( numPages - 1 ); } item->setLine( QLineF( alignX, 0, alignX, yLineCoord ) ); item->show(); } else { deleteHAlignSnapItem(); } if ( alignY != -1 ) { QGraphicsLineItem* item = vAlignSnapItem(); item->setLine( QLineF( 0, alignY, mComposition->paperWidth(), alignY ) ); item->show(); } else { deleteVAlignSnapItem(); } } double moveRectX = snappedLeftPoint.x() - originalItem->transform().dx(); double moveRectY = snappedLeftPoint.y() - originalItem->transform().dy(); if ( !changeComposerItem ) { QTransform moveTransform; moveTransform.translate( originalItem->transform().dx() + moveRectX, originalItem->transform().dy() + moveRectY ); changeItem->setTransform( moveTransform ); } else //for composer items, we prefer setSceneRect as subclasses can implement custom behaviour (e.g. item group) { changeComposerItem->setSceneRect( QRectF( originalItem->transform().dx() + moveRectX, originalItem->transform().dy() + moveRectY, originalItem->rect().width(), originalItem->rect().height() ) ); changeComposerItem->updateItem(); } } return; case QgsComposerItem::NoAction: break; } if ( !changeComposerItem ) { QTransform itemTransform; itemTransform.translate( originalItem->transform().dx() + mx, originalItem->transform().dy() + my ); changeItem->setTransform( itemTransform ); QRectF itemRect( 0, 0, originalItem->rect().width() + rx, originalItem->rect().height() + ry ); changeItem->setRect( itemRect ); } else //for composer items, we prefer setSceneRect as subclasses can implement custom behaviour (e.g. item group) { changeComposerItem->setSceneRect( QRectF( originalItem->transform().dx() + mx, originalItem->transform().dy() + my, originalItem->rect().width() + rx, originalItem->rect().height() + ry ) ); changeComposerItem->updateItem(); } }
void QgsComposerView::endMarqueeSelect( QMouseEvent* e ) { mMarqueeSelect = false; bool subtractingSelection = false; if ( e->modifiers() & Qt::ShiftModifier ) { //shift modifer means adding to selection, nothing required here } else if ( e->modifiers() & Qt::ControlModifier ) { //control modifier means subtract from current selection subtractingSelection = true; } else { //not adding to or removing from selection, so clear current selection composition()->clearSelection(); } if ( !mRubberBandItem || ( mRubberBandItem->rect().width() < 0.1 && mRubberBandItem->rect().height() < 0.1 ) ) { //just a click, do nothing removeRubberBand(); return; } QRectF boundsRect = QRectF( mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(), mRubberBandItem->rect().height() ); //determine item selection mode, default to intersection Qt::ItemSelectionMode selectionMode = Qt::IntersectsItemShape; if ( e->modifiers() & Qt::AltModifier ) { //alt modifier switches to contains selection mode selectionMode = Qt::ContainsItemShape; } //find all items in rubber band QList<QGraphicsItem *> itemList = composition()->items( boundsRect, selectionMode ); QList<QGraphicsItem *>::iterator itemIt = itemList.begin(); for ( ; itemIt != itemList.end(); ++itemIt ) { QgsComposerItem* mypItem = dynamic_cast<QgsComposerItem *>( *itemIt ); QgsPaperItem* paperItem = dynamic_cast<QgsPaperItem*>( *itemIt ); if ( mypItem && !paperItem ) { if ( !mypItem->positionLock() ) { if ( subtractingSelection ) { mypItem->setSelected( false ); } else { mypItem->setSelected( true ); } } } } removeRubberBand(); //update item panel QList<QgsComposerItem*> selectedItemList = composition()->selectedComposerItems(); if ( selectedItemList.size() > 0 ) { emit selectedItemChanged( selectedItemList[0] ); } }
void QgsComposerView::mousePressEvent( QMouseEvent* e ) { if ( !composition() ) { return; } QPointF scenePoint = mapToScene( e->pos() ); QPointF snappedScenePoint = composition()->snapPointToGrid( scenePoint ); //lock/unlock position of item with right click if ( e->button() == Qt::RightButton ) { QgsComposerItem* selectedItem = composition()->composerItemAt( scenePoint ); if ( selectedItem ) { bool lock = selectedItem->positionLock() ? false : true; selectedItem->setPositionLock( lock ); selectedItem->update(); //make sure the new cursor is correct QPointF itemPoint = selectedItem->mapFromScene( scenePoint ); selectedItem->updateCursor( itemPoint ); } return; } switch ( mCurrentTool ) { //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(); } 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; } if (( e->modifiers() & Qt::ShiftModifier ) && ( selectedItem->selected() ) ) { //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 QList<QgsComposerItem*> selectedItems = composition()->selectedComposerItems(); if ( selectedItems.size() > 0 ) { emit selectedItemChanged( selectedItems.at( 0 ) ); } } else { selectedItem->setSelected( true ); QGraphicsView::mousePressEvent( e ); emit selectedItemChanged( selectedItem ); } break; } case MoveItemContent: { //store item as member if it is selected and cursor is over item QgsComposerItem* item = dynamic_cast<QgsComposerItem *>( itemAt( e->pos() ) ); if ( item ) { mMoveContentStartPos = scenePoint; } mMoveContentItem = item; break; } case AddArrow: { mRubberBandStartPos = QPointF( snappedScenePoint.x(), snappedScenePoint.y() ); mRubberBandLineItem = new QGraphicsLineItem( snappedScenePoint.x(), snappedScenePoint.y(), snappedScenePoint.x(), snappedScenePoint.y() ); mRubberBandLineItem->setZValue( 100 ); scene()->addItem( mRubberBandLineItem ); scene()->update(); break; } //create rubber band for map and ellipse items case AddMap: case AddRectangle: case AddTriangle: case AddEllipse: case AddHtml: { QTransform t; mRubberBandItem = new QGraphicsRectItem( 0, 0, 0, 0 ); mRubberBandStartPos = QPointF( snappedScenePoint.x(), snappedScenePoint.y() ); t.translate( snappedScenePoint.x(), snappedScenePoint.y() ); mRubberBandItem->setTransform( t ); mRubberBandItem->setZValue( 100 ); scene()->addItem( mRubberBandItem ); scene()->update(); } break; case AddLabel: if ( composition() ) { QgsComposerLabel* newLabelItem = new QgsComposerLabel( composition() ); newLabelItem->setText( tr( "QGIS" ) ); newLabelItem->adjustSizeToText(); newLabelItem->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), newLabelItem->rect().width(), newLabelItem->rect().height() ) ); composition()->addComposerLabel( newLabelItem ); emit actionFinished(); composition()->pushAddRemoveCommand( newLabelItem, tr( "Label added" ) ); } break; case AddScalebar: if ( composition() ) { QgsComposerScaleBar* newScaleBar = new QgsComposerScaleBar( composition() ); newScaleBar->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), 20, 20 ) ); composition()->addComposerScaleBar( newScaleBar ); QList<const QgsComposerMap*> mapItemList = composition()->composerMapItems(); if ( mapItemList.size() > 0 ) { newScaleBar->setComposerMap( mapItemList.at( 0 ) ); } newScaleBar->applyDefaultSize(); //4 segments, 1/5 of composer map width emit actionFinished(); composition()->pushAddRemoveCommand( newScaleBar, tr( "Scale bar added" ) ); } break; case AddLegend: { if ( composition() ) { QgsComposerLegend* newLegend = new QgsComposerLegend( composition() ); newLegend->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), newLegend->rect().width(), newLegend->rect().height() ) ); composition()->addComposerLegend( newLegend ); newLegend->updateLegend(); emit actionFinished(); composition()->pushAddRemoveCommand( newLegend, tr( "Legend added" ) ); } break; } case AddPicture: if ( composition() ) { QgsComposerPicture* newPicture = new QgsComposerPicture( composition() ); newPicture->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), 30, 30 ) ); composition()->addComposerPicture( newPicture ); emit actionFinished(); composition()->pushAddRemoveCommand( newPicture, tr( "Picture added" ) ); } break; case AddTable: if ( composition() ) { QgsComposerAttributeTable* newTable = new QgsComposerAttributeTable( composition() ); newTable->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), 50, 50 ) ); composition()->addComposerTable( newTable ); emit actionFinished(); composition()->pushAddRemoveCommand( newTable, tr( "Table added" ) ); } break; default: break; } }