1
/***************************************************************************
5
copyright : (C) 2005 by Radim Blazek
7
***************************************************************************/
9
/***************************************************************************
11
* This program is free software; you can redistribute it and/or modify *
12
* it under the terms of the GNU General Public License as published by *
13
* the Free Software Foundation; either version 2 of the License, or *
14
* (at your option) any later version. *
16
***************************************************************************/
18
#include <QMainWindow>
19
#include <QMouseEvent>
22
#include "qgscomposerview.h"
23
#include "qgscomposerarrow.h"
24
#include "qgscomposerlabel.h"
25
#include "qgscomposerlegend.h"
26
#include "qgscomposermap.h"
27
#include "qgscomposeritemgroup.h"
28
#include "qgscomposerpicture.h"
29
#include "qgscomposerscalebar.h"
30
#include "qgscomposershape.h"
32
QgsComposerView::QgsComposerView( QWidget* parent, const char* name, Qt::WFlags f ) :
33
QGraphicsView( parent ), mShiftKeyPressed( false ), mRubberBandItem( 0 ), mRubberBandLineItem( 0 ), mMoveContentItem( 0 )
35
setResizeAnchor( QGraphicsView::AnchorViewCenter );
36
setMouseTracking( true );
37
viewport()->setMouseTracking( true );
40
void QgsComposerView::mousePressEvent( QMouseEvent* e )
47
QPointF scenePoint = mapToScene( e->pos() );
48
QPointF snappedScenePoint = composition()->snapPointToGrid( scenePoint );
50
//lock/unlock position of item with right click
51
if ( e->button() == Qt::RightButton )
53
QgsComposerItem* selectedItem = composition()->composerItemAt( scenePoint );
56
bool lock = selectedItem->positionLock() ? false : true;
57
selectedItem->setPositionLock( lock );
58
selectedItem->update();
59
//make sure the new cursor is correct
60
QPointF itemPoint = selectedItem->mapFromScene( scenePoint );
61
selectedItem->updateCursor( itemPoint );
66
switch ( mCurrentTool )
68
//select/deselect items and pass mouse event further
71
if ( !mShiftKeyPressed ) //keep selection if shift key pressed
73
composition()->clearSelection();
76
//select topmost item at position of event
77
QgsComposerItem* selectedItem = composition()->composerItemAt( scenePoint );
83
selectedItem->setSelected( true );
84
QGraphicsView::mousePressEvent( e );
85
emit selectedItemChanged( selectedItem );
91
//store item as member if it is selected and cursor is over item
92
QgsComposerItem* item = dynamic_cast<QgsComposerItem *>( itemAt( e->pos() ) );
95
mMoveContentStartPos = scenePoint;
97
mMoveContentItem = item;
103
mRubberBandStartPos = QPointF( snappedScenePoint.x(), snappedScenePoint.y() );
104
mRubberBandLineItem = new QGraphicsLineItem( snappedScenePoint.x(), snappedScenePoint.y(), snappedScenePoint.x(), snappedScenePoint.y() );
105
mRubberBandLineItem->setZValue( 100 );
106
scene()->addItem( mRubberBandLineItem );
110
//create rubber band for map and ellipse items
115
mRubberBandItem = new QGraphicsRectItem( 0, 0, 0, 0 );
116
mRubberBandStartPos = QPointF( snappedScenePoint.x(), snappedScenePoint.y() );
117
t.translate( snappedScenePoint.x(), snappedScenePoint.y() );
118
mRubberBandItem->setTransform( t );
119
mRubberBandItem->setZValue( 100 );
120
scene()->addItem( mRubberBandItem );
127
QgsComposerLabel* newLabelItem = new QgsComposerLabel( composition() );
128
newLabelItem->setText( "Quantum GIS" );
129
newLabelItem->adjustSizeToText();
130
newLabelItem->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), newLabelItem->rect().width(), newLabelItem->rect().height() ) );
131
addComposerLabel( newLabelItem );
132
emit actionFinished();
138
QgsComposerScaleBar* newScaleBar = new QgsComposerScaleBar( composition() );
139
addComposerScaleBar( newScaleBar );
140
newScaleBar->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), 20, 20 ) );
141
emit actionFinished();
147
QgsComposerLegend* newLegend = new QgsComposerLegend( composition() );
148
addComposerLegend( newLegend );
149
newLegend->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), newLegend->rect().width(), newLegend->rect().height() ) );
154
QgsComposerPicture* newPicture = new QgsComposerPicture( composition() );
155
addComposerPicture( newPicture );
156
newPicture->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), 30, 30 ) );
157
emit actionFinished();
165
void QgsComposerView::mouseReleaseEvent( QMouseEvent* e )
167
if ( !composition() )
172
QPointF scenePoint = mapToScene( e->pos() );
174
switch ( mCurrentTool )
178
QGraphicsView::mouseReleaseEvent( e );
182
case MoveItemContent:
184
if ( mMoveContentItem )
186
//update map preview if composer map
187
QgsComposerMap* composerMap = dynamic_cast<QgsComposerMap *>( mMoveContentItem );
190
composerMap->setOffset( 0, 0 );
193
double moveX = scenePoint.x() - mMoveContentStartPos.x();
194
double moveY = scenePoint.y() - mMoveContentStartPos.y();
195
mMoveContentItem->moveContent( -moveX, -moveY );
196
mMoveContentItem = 0;
202
QPointF scenePoint = mapToScene( e->pos() );
203
QPointF snappedScenePoint = composition()->snapPointToGrid( scenePoint );
204
QgsComposerArrow* composerArrow = new QgsComposerArrow( mRubberBandStartPos, QPointF( snappedScenePoint.x(), snappedScenePoint.y() ), composition() );
205
addComposerArrow( composerArrow );
206
scene()->removeItem( mRubberBandLineItem );
207
delete mRubberBandLineItem;
208
mRubberBandLineItem = 0;
209
emit actionFinished();
215
if ( !mRubberBandItem || mRubberBandItem->rect().width() < 0.1 || mRubberBandItem->rect().width() < 0.1 )
217
scene()->removeItem( mRubberBandItem );
218
delete mRubberBandItem;
223
QgsComposerShape* composerShape = new QgsComposerShape( mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(), mRubberBandItem->rect().height(), composition() );
224
addComposerShape( composerShape );
225
scene()->removeItem( mRubberBandItem );
226
delete mRubberBandItem;
227
emit actionFinished();
233
if ( !mRubberBandItem || mRubberBandItem->rect().width() < 0.1 || mRubberBandItem->rect().width() < 0.1 )
235
scene()->removeItem( mRubberBandItem );
236
delete mRubberBandItem;
240
QgsComposerMap* composerMap = new QgsComposerMap( composition(), mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(), mRubberBandItem->rect().height() );
241
addComposerMap( composerMap );
242
scene()->removeItem( mRubberBandItem );
243
delete mRubberBandItem;
245
emit actionFinished();
254
void QgsComposerView::mouseMoveEvent( QMouseEvent* e )
256
if ( !composition() )
261
if ( e->buttons() == Qt::NoButton )
263
if ( mCurrentTool == Select )
265
QGraphicsView::mouseMoveEvent( e );
270
QPointF scenePoint = mapToScene( e->pos() );
272
switch ( mCurrentTool )
275
QGraphicsView::mouseMoveEvent( e );
280
if ( mRubberBandLineItem )
282
mRubberBandLineItem->setLine( mRubberBandStartPos.x(), mRubberBandStartPos.y(), scenePoint.x(), scenePoint.y() );
289
//adjust rubber band item
296
double dx = scenePoint.x() - mRubberBandStartPos.x();
297
double dy = scenePoint.y() - mRubberBandStartPos.y();
306
x = mRubberBandStartPos.x();
317
y = mRubberBandStartPos.y();
321
if ( mRubberBandItem )
323
mRubberBandItem->setRect( 0, 0, width, height );
326
mRubberBandItem->setTransform( t );
331
case MoveItemContent:
333
//update map preview if composer map
334
QgsComposerMap* composerMap = dynamic_cast<QgsComposerMap *>( mMoveContentItem );
337
composerMap->setOffset( scenePoint.x() - mMoveContentStartPos.x(), scenePoint.y() - mMoveContentStartPos.y() );
338
composerMap->update();
348
void QgsComposerView::keyPressEvent( QKeyEvent * e )
350
if ( e->key() == Qt::Key_Shift )
352
mShiftKeyPressed = true;
355
if ( !composition() )
360
QList<QgsComposerItem*> composerItemList = composition()->selectedComposerItems();
361
QList<QgsComposerItem*>::iterator itemIt = composerItemList.begin();
363
//delete selected items
364
if ( e->key() == Qt::Key_Delete )
366
for ( ; itemIt != composerItemList.end(); ++itemIt )
368
QgsComposerMap* map = dynamic_cast<QgsComposerMap *>( *itemIt );
369
if ( !map || !map->isDrawing() ) //don't delete a composer map while it draws
371
composition()->removeItem( *itemIt );
372
emit itemRemoved( *itemIt );
377
else if ( e->key() == Qt::Key_Left )
379
for ( ; itemIt != composerItemList.end(); ++itemIt )
381
( *itemIt )->move( -1.0, 0.0 );
384
else if ( e->key() == Qt::Key_Right )
386
for ( ; itemIt != composerItemList.end(); ++itemIt )
388
( *itemIt )->move( 1.0, 0.0 );
391
else if ( e->key() == Qt::Key_Down )
393
for ( ; itemIt != composerItemList.end(); ++itemIt )
395
( *itemIt )->move( 0.0, 1.0 );
398
else if ( e->key() == Qt::Key_Up )
400
for ( ; itemIt != composerItemList.end(); ++itemIt )
402
( *itemIt )->move( 0.0, -1.0 );
407
void QgsComposerView::keyReleaseEvent( QKeyEvent * e )
409
if ( e->key() == Qt::Key_Shift )
411
mShiftKeyPressed = false;
415
void QgsComposerView::wheelEvent( QWheelEvent* event )
417
QPointF scenePoint = mapToScene( event->pos() );
419
//select topmost item at position of event
420
QgsComposerItem* theItem = composition()->composerItemAt( scenePoint );
423
if ( theItem->isSelected() )
425
QPointF itemPoint = theItem->mapFromScene( scenePoint );
426
theItem->zoomContent( event->delta(), itemPoint.x(), itemPoint.y() );
431
void QgsComposerView::setComposition( QgsComposition* c )
436
QgsComposition* QgsComposerView::composition()
440
QgsComposition* c = dynamic_cast<QgsComposition *>( scene() );
449
void QgsComposerView::addComposerArrow( QgsComposerArrow* arrow )
451
composition()->addItem( arrow );
452
emit composerArrowAdded( arrow );
453
scene()->clearSelection();
454
arrow->setSelected( true );
455
emit selectedItemChanged( arrow );
458
void QgsComposerView::addComposerLabel( QgsComposerLabel* label )
460
composition()->addItem( label );
461
emit composerLabelAdded( label );
462
scene()->clearSelection();
463
label->setSelected( true );
464
emit selectedItemChanged( label );
467
void QgsComposerView::addComposerMap( QgsComposerMap* map )
469
scene()->addItem( map );
470
//set default preview mode to cache. Must be done here between adding composer map to scene and emiting signal
471
map->setPreviewMode( QgsComposerMap::Cache );
473
emit composerMapAdded( map );
474
scene()->clearSelection();
475
map->setSelected( true );
476
emit selectedItemChanged( map );
479
void QgsComposerView::addComposerScaleBar( QgsComposerScaleBar* scaleBar )
481
//take first available map...
482
QList<const QgsComposerMap*> mapItemList = composition()->composerMapItems();
483
if ( mapItemList.size() > 0 )
485
scaleBar->setComposerMap( mapItemList.at( 0 ) );
487
scaleBar->applyDefaultSettings(); //4 segments, 1/5 of composer map width
488
scene()->addItem( scaleBar );
489
emit composerScaleBarAdded( scaleBar );
490
scene()->clearSelection();
491
scaleBar->setSelected( true );
492
emit selectedItemChanged( scaleBar );
495
void QgsComposerView::addComposerLegend( QgsComposerLegend* legend )
497
scene()->addItem( legend );
498
emit composerLegendAdded( legend );
499
scene()->clearSelection();
500
legend->setSelected( true );
501
emit selectedItemChanged( legend );
502
emit actionFinished();
505
void QgsComposerView::addComposerPicture( QgsComposerPicture* picture )
507
scene()->addItem( picture );
508
emit composerPictureAdded( picture );
509
scene()->clearSelection();
510
picture->setSelected( true );
511
emit selectedItemChanged( picture );
514
void QgsComposerView::addComposerShape( QgsComposerShape* shape )
516
scene()->addItem( shape );
517
emit composerShapeAdded( shape );
518
scene()->clearSelection();
519
shape->setSelected( true );
520
emit selectedItemChanged( shape );
523
void QgsComposerView::groupItems()
525
if ( !composition() )
530
QList<QgsComposerItem*> selectionList = composition()->selectedComposerItems();
531
if ( selectionList.size() < 2 )
533
return; //not enough items for a group
536
QgsComposerItemGroup* itemGroup = new QgsComposerItemGroup( composition() );
537
//connect signal/slot to let item group tell if child items get removed
538
connect( itemGroup, SIGNAL( childItemDeleted( QgsComposerItem* ) ), this, SLOT( sendItemRemovedSignal( QgsComposerItem* ) ) );
540
QList<QgsComposerItem*>::iterator itemIter = selectionList.begin();
541
for ( ; itemIter != selectionList.end(); ++itemIter )
543
itemGroup->addItem( *itemIter );
545
composition()->addItem( itemGroup );
546
itemGroup->setSelected( true );
547
emit selectedItemChanged( itemGroup );
550
void QgsComposerView::ungroupItems()
552
if ( !composition() )
557
QList<QgsComposerItem*> selectionList = composition()->selectedComposerItems();
558
QList<QgsComposerItem*>::iterator itemIter = selectionList.begin();
559
for ( ; itemIter != selectionList.end(); ++itemIter )
561
QgsComposerItemGroup* itemGroup = dynamic_cast<QgsComposerItemGroup *>( *itemIter );
564
itemGroup->removeItems();
565
composition()->removeItem( *itemIter );
567
emit itemRemoved( *itemIter );
573
void QgsComposerView::sendItemRemovedSignal( QgsComposerItem* item )
575
emit itemRemoved( item );
578
QMainWindow* QgsComposerView::composerWindow()
580
QObject* composerObject = 0;
581
QObject* currentObject = parent();
582
if ( !currentObject )
584
return qobject_cast<QMainWindow *>( currentObject );
589
if ( currentObject->parent() == 0 )
591
composerObject = currentObject;
594
currentObject = currentObject->parent();
597
return qobject_cast<QMainWindow *>( composerObject );