Navigation Menu

Skip to content

Commit

Permalink
[FEATURE] Marquee select for composer items
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson authored and mhugent committed Oct 18, 2013
1 parent 7ea3184 commit 908d76a
Show file tree
Hide file tree
Showing 2 changed files with 171 additions and 58 deletions.
217 changes: 159 additions & 58 deletions src/gui/qgscomposerview.cpp
Expand Up @@ -47,6 +47,7 @@ QgsComposerView::QgsComposerView( QWidget* parent, const char* name, Qt::WFlags
, mRubberBandItem( 0 )
, mRubberBandLineItem( 0 )
, mMoveContentItem( 0 )
, mMarqueeSelect( false )
, mPaintingEnabled( true )
, mHorizontalRuler( 0 )
, mVerticalRuler( 0 )
Expand Down Expand Up @@ -173,7 +174,8 @@ void QgsComposerView::mousePressEvent( QMouseEvent* e )

if ( !selectedItem )
{
composition()->clearSelection();
//not clicking over an item, so start marquee selection
startMarqueeSelect( scenePoint );
break;
}

Expand Down Expand Up @@ -246,7 +248,7 @@ void QgsComposerView::mousePressEvent( QMouseEvent* e )
{
mRubberBandStartPos = QPointF( snappedScenePoint.x(), snappedScenePoint.y() );
mRubberBandLineItem = new QGraphicsLineItem( snappedScenePoint.x(), snappedScenePoint.y(), snappedScenePoint.x(), snappedScenePoint.y() );
mRubberBandLineItem->setZValue( 100 );
mRubberBandLineItem->setZValue( 1000 );
scene()->addItem( mRubberBandLineItem );
scene()->update();
break;
Expand All @@ -264,7 +266,7 @@ void QgsComposerView::mousePressEvent( QMouseEvent* e )
mRubberBandStartPos = QPointF( snappedScenePoint.x(), snappedScenePoint.y() );
t.translate( snappedScenePoint.x(), snappedScenePoint.y() );
mRubberBandItem->setTransform( t );
mRubberBandItem->setZValue( 100 );
mRubberBandItem->setZValue( 1000 );
scene()->addItem( mRubberBandItem );
scene()->update();
}
Expand Down Expand Up @@ -349,19 +351,15 @@ void QgsComposerView::addShape( Tool currentTool )

if ( !mRubberBandItem || mRubberBandItem->rect().width() < 0.1 || mRubberBandItem->rect().width() < 0.1 )
{
scene()->removeItem( mRubberBandItem );
delete mRubberBandItem;
mRubberBandItem = 0;
removeRubberBand();
return;
}
if ( composition() )
{
QgsComposerShape* composerShape = new QgsComposerShape( mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(), mRubberBandItem->rect().height(), composition() );
composerShape->setShapeType( shape );
composition()->addComposerShape( composerShape );
scene()->removeItem( mRubberBandItem );
delete mRubberBandItem;
mRubberBandItem = 0;
removeRubberBand();
emit actionFinished();
composition()->pushAddRemoveCommand( composerShape, tr( "Shape added" ) );
}
Expand All @@ -379,6 +377,102 @@ void QgsComposerView::updateRulers()
}
}

void QgsComposerView::removeRubberBand()
{
if ( mRubberBandItem )
{
scene()->removeItem( mRubberBandItem );
delete mRubberBandItem;
mRubberBandItem = 0;
}
}

void QgsComposerView::startMarqueeSelect( QPointF & scenePoint )
{
mMarqueeSelect = true;

QTransform t;
mRubberBandItem = new QGraphicsRectItem( 0, 0, 0, 0 );
mRubberBandItem->setBrush( QBrush( QColor( 225, 50, 70, 25 ) ) );
mRubberBandItem->setPen( QPen( Qt::DotLine ) );
mRubberBandStartPos = QPointF( scenePoint.x(), scenePoint.y() );
t.translate( scenePoint.x(), scenePoint.y() );
mRubberBandItem->setTransform( t );
mRubberBandItem->setZValue( 1000 );
scene()->addItem( mRubberBandItem );
scene()->update();
}

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;
}

QRect boundsRect = QRect( 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::mouseReleaseEvent( QMouseEvent* e )
{
if ( !composition() )
Expand Down Expand Up @@ -406,6 +500,11 @@ void QgsComposerView::mouseReleaseEvent( QMouseEvent* e )
}
viewport()->setCursor( Qt::ArrowCursor );
}
}

if ( mMarqueeSelect )
{
endMarqueeSelect( e );
return;
}

Expand Down Expand Up @@ -462,21 +561,14 @@ void QgsComposerView::mouseReleaseEvent( QMouseEvent* e )
case AddMap:
if ( !mRubberBandItem || mRubberBandItem->rect().width() < 0.1 || mRubberBandItem->rect().width() < 0.1 )
{
if ( mRubberBandItem )
{
scene()->removeItem( mRubberBandItem );
delete mRubberBandItem;
mRubberBandItem = 0;
}
removeRubberBand();
return;
}
if ( composition() )
{
QgsComposerMap* composerMap = new QgsComposerMap( composition(), mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(), mRubberBandItem->rect().height() );
composition()->addComposerMap( composerMap );
scene()->removeItem( mRubberBandItem );
delete mRubberBandItem;
mRubberBandItem = 0;
removeRubberBand();
emit actionFinished();
composition()->pushAddRemoveCommand( composerMap, tr( "Map added" ) );
}
Expand All @@ -495,9 +587,7 @@ void QgsComposerView::mouseReleaseEvent( QMouseEvent* e )
composition()->beginMultiFrameCommand( composerHtml, tr( "Html frame added" ) );
composerHtml->addFrame( frame );
composition()->endMultiFrameCommand();
scene()->removeItem( mRubberBandItem );
delete mRubberBandItem;
mRubberBandItem = 0;
removeRubberBand();
emit actionFinished();
}
default:
Expand Down Expand Up @@ -543,6 +633,12 @@ void QgsComposerView::mouseMoveEvent( QMouseEvent* e )
{
QPointF scenePoint = mapToScene( e->pos() );

if ( mMarqueeSelect )
{
updateRubberBand( scenePoint );
return;
}

switch ( mCurrentTool )
{
case Select:
Expand All @@ -565,43 +661,7 @@ void QgsComposerView::mouseMoveEvent( QMouseEvent* e )
case AddHtml:
//adjust rubber band item
{
double x = 0;
double y = 0;
double width = 0;
double height = 0;

double dx = scenePoint.x() - mRubberBandStartPos.x();
double dy = scenePoint.y() - mRubberBandStartPos.y();

if ( dx < 0 )
{
x = scenePoint.x();
width = -dx;
}
else
{
x = mRubberBandStartPos.x();
width = dx;
}

if ( dy < 0 )
{
y = scenePoint.y();
height = -dy;
}
else
{
y = mRubberBandStartPos.y();
height = dy;
}

if ( mRubberBandItem )
{
mRubberBandItem->setRect( 0, 0, width, height );
QTransform t;
t.translate( x, y );
mRubberBandItem->setTransform( t );
}
updateRubberBand( scenePoint );
break;
}

Expand All @@ -622,6 +682,47 @@ void QgsComposerView::mouseMoveEvent( QMouseEvent* e )
}
}

void QgsComposerView::updateRubberBand( QPointF & pos )
{
double x = 0;
double y = 0;
double width = 0;
double height = 0;

double dx = pos.x() - mRubberBandStartPos.x();
double dy = pos.y() - mRubberBandStartPos.y();

if ( dx < 0 )
{
x = pos.x();
width = -dx;
}
else
{
x = mRubberBandStartPos.x();
width = dx;
}

if ( dy < 0 )
{
y = pos.y();
height = -dy;
}
else
{
y = mRubberBandStartPos.y();
height = dy;
}

if ( mRubberBandItem )
{
mRubberBandItem->setRect( 0, 0, width, height );
QTransform t;
t.translate( x, y );
mRubberBandItem->setTransform( t );
}
}

void QgsComposerView::mouseDoubleClickEvent( QMouseEvent* e )
{
e->ignore();
Expand Down
12 changes: 12 additions & 0 deletions src/gui/qgscomposerview.h
Expand Up @@ -161,6 +161,9 @@ class GUI_EXPORT QgsComposerView: public QGraphicsView
/**Start of rubber band creation*/
QPointF mRubberBandStartPos;

/**True if user is currently selecting by marquee*/
bool mMarqueeSelect;

bool mPaintingEnabled;

QgsComposerRuler* mHorizontalRuler;
Expand All @@ -175,6 +178,15 @@ class GUI_EXPORT QgsComposerView: public QGraphicsView

/**Zoom composition from a mouse wheel event*/
void wheelZoom( QWheelEvent * event );
/**Redraws the rubber band*/
void updateRubberBand( QPointF & pos );
/**Removes the rubber band and cleans up*/
void removeRubberBand();

/**Starts a marquee selection*/
void startMarqueeSelect( QPointF & scenePoint );
/**Finalises a marquee selection*/
void endMarqueeSelect( QMouseEvent* e );

//void connectAddRemoveCommandSignals( QgsAddRemoveItemCommand* c );

Expand Down

0 comments on commit 908d76a

Please sign in to comment.