~ubuntu-branches/ubuntu/trusty/qgis/trusty

« back to all changes in this revision

Viewing changes to src/gui/qgscomposerview.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Johan Van de Wauw
  • Date: 2010-07-11 20:23:24 UTC
  • mfrom: (3.1.4 squeeze)
  • Revision ID: james.westby@ubuntu.com-20100711202324-5ktghxa7hracohmr
Tags: 1.4.0+12730-3ubuntu1
* Merge from Debian unstable (LP: #540941).
* Fix compilation issues with QT 4.7
* Add build-depends on libqt4-webkit-dev 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
                         qgscomposerview.cpp
 
3
                         -------------------
 
4
    begin                : January 2005
 
5
    copyright            : (C) 2005 by Radim Blazek
 
6
    email                : blazek@itc.it
 
7
 ***************************************************************************/
 
8
 
 
9
/***************************************************************************
 
10
 *                                                                         *
 
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.                                   *
 
15
 *                                                                         *
 
16
 ***************************************************************************/
 
17
 
 
18
#include <QMainWindow>
 
19
#include <QMouseEvent>
 
20
#include <QKeyEvent>
 
21
 
 
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"
 
31
 
 
32
QgsComposerView::QgsComposerView( QWidget* parent, const char* name, Qt::WFlags f ) :
 
33
    QGraphicsView( parent ), mShiftKeyPressed( false ), mRubberBandItem( 0 ), mRubberBandLineItem( 0 ), mMoveContentItem( 0 )
 
34
{
 
35
  setResizeAnchor( QGraphicsView::AnchorViewCenter );
 
36
  setMouseTracking( true );
 
37
  viewport()->setMouseTracking( true );
 
38
}
 
39
 
 
40
void QgsComposerView::mousePressEvent( QMouseEvent* e )
 
41
{
 
42
  if ( !composition() )
 
43
  {
 
44
    return;
 
45
  }
 
46
 
 
47
  QPointF scenePoint = mapToScene( e->pos() );
 
48
  QPointF snappedScenePoint = composition()->snapPointToGrid( scenePoint );
 
49
 
 
50
  //lock/unlock position of item with right click
 
51
  if ( e->button() == Qt::RightButton )
 
52
  {
 
53
    QgsComposerItem* selectedItem = composition()->composerItemAt( scenePoint );
 
54
    if ( selectedItem )
 
55
    {
 
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 );
 
62
    }
 
63
    return;
 
64
  }
 
65
 
 
66
  switch ( mCurrentTool )
 
67
  {
 
68
      //select/deselect items and pass mouse event further
 
69
    case Select:
 
70
    {
 
71
      if ( !mShiftKeyPressed ) //keep selection if shift key pressed
 
72
      {
 
73
        composition()->clearSelection();
 
74
      }
 
75
 
 
76
      //select topmost item at position of event
 
77
      QgsComposerItem* selectedItem = composition()->composerItemAt( scenePoint );
 
78
      if ( !selectedItem )
 
79
      {
 
80
        break;
 
81
      }
 
82
 
 
83
      selectedItem->setSelected( true );
 
84
      QGraphicsView::mousePressEvent( e );
 
85
      emit selectedItemChanged( selectedItem );
 
86
      break;
 
87
    }
 
88
 
 
89
    case MoveItemContent:
 
90
    {
 
91
      //store item as member if it is selected and cursor is over item
 
92
      QgsComposerItem* item = dynamic_cast<QgsComposerItem *>( itemAt( e->pos() ) );
 
93
      if ( item )
 
94
      {
 
95
        mMoveContentStartPos = scenePoint;
 
96
      }
 
97
      mMoveContentItem = item;
 
98
      break;
 
99
    }
 
100
 
 
101
    case AddArrow:
 
102
    {
 
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 );
 
107
      scene()->update();
 
108
    }
 
109
 
 
110
    //create rubber band for map and ellipse items
 
111
    case AddMap:
 
112
    case AddShape:
 
113
    {
 
114
      QTransform t;
 
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 );
 
121
      scene()->update();
 
122
    }
 
123
    break;
 
124
 
 
125
    case AddLabel:
 
126
    {
 
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();
 
133
    }
 
134
    break;
 
135
 
 
136
    case AddScalebar:
 
137
    {
 
138
      QgsComposerScaleBar* newScaleBar = new QgsComposerScaleBar( composition() );
 
139
      addComposerScaleBar( newScaleBar );
 
140
      newScaleBar->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), 20, 20 ) );
 
141
      emit actionFinished();
 
142
    }
 
143
    break;
 
144
 
 
145
    case AddLegend:
 
146
    {
 
147
      QgsComposerLegend* newLegend = new QgsComposerLegend( composition() );
 
148
      addComposerLegend( newLegend );
 
149
      newLegend->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), newLegend->rect().width(), newLegend->rect().height() ) );
 
150
      break;
 
151
    }
 
152
    case AddPicture:
 
153
    {
 
154
      QgsComposerPicture* newPicture = new QgsComposerPicture( composition() );
 
155
      addComposerPicture( newPicture );
 
156
      newPicture->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), 30, 30 ) );
 
157
      emit actionFinished();
 
158
    }
 
159
 
 
160
    default:
 
161
      break;
 
162
  }
 
163
}
 
164
 
 
165
void QgsComposerView::mouseReleaseEvent( QMouseEvent* e )
 
166
{
 
167
  if ( !composition() )
 
168
  {
 
169
    return;
 
170
  }
 
171
 
 
172
  QPointF scenePoint = mapToScene( e->pos() );
 
173
 
 
174
  switch ( mCurrentTool )
 
175
  {
 
176
    case Select:
 
177
    {
 
178
      QGraphicsView::mouseReleaseEvent( e );
 
179
      break;
 
180
    }
 
181
 
 
182
    case MoveItemContent:
 
183
    {
 
184
      if ( mMoveContentItem )
 
185
      {
 
186
        //update map preview if composer map
 
187
        QgsComposerMap* composerMap = dynamic_cast<QgsComposerMap *>( mMoveContentItem );
 
188
        if ( composerMap )
 
189
        {
 
190
          composerMap->setOffset( 0, 0 );
 
191
        }
 
192
 
 
193
        double moveX = scenePoint.x() - mMoveContentStartPos.x();
 
194
        double moveY = scenePoint.y() - mMoveContentStartPos.y();
 
195
        mMoveContentItem->moveContent( -moveX, -moveY );
 
196
        mMoveContentItem = 0;
 
197
      }
 
198
      break;
 
199
    }
 
200
    case AddArrow:
 
201
    {
 
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();
 
210
      break;
 
211
    }
 
212
 
 
213
    case AddShape:
 
214
    {
 
215
      if ( !mRubberBandItem || mRubberBandItem->rect().width() < 0.1 || mRubberBandItem->rect().width() < 0.1 )
 
216
      {
 
217
        scene()->removeItem( mRubberBandItem );
 
218
        delete mRubberBandItem;
 
219
        mRubberBandItem = 0;
 
220
        return;
 
221
      }
 
222
 
 
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();
 
228
      break;
 
229
    }
 
230
 
 
231
    case AddMap:
 
232
    {
 
233
      if ( !mRubberBandItem || mRubberBandItem->rect().width() < 0.1 || mRubberBandItem->rect().width() < 0.1 )
 
234
      {
 
235
        scene()->removeItem( mRubberBandItem );
 
236
        delete mRubberBandItem;
 
237
        return;
 
238
      }
 
239
 
 
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;
 
244
      mRubberBandItem = 0;
 
245
      emit actionFinished();
 
246
    }
 
247
    break;
 
248
 
 
249
    default:
 
250
      break;
 
251
  }
 
252
}
 
253
 
 
254
void QgsComposerView::mouseMoveEvent( QMouseEvent* e )
 
255
{
 
256
  if ( !composition() )
 
257
  {
 
258
    return;
 
259
  }
 
260
 
 
261
  if ( e->buttons() == Qt::NoButton )
 
262
  {
 
263
    if ( mCurrentTool == Select )
 
264
    {
 
265
      QGraphicsView::mouseMoveEvent( e );
 
266
    }
 
267
  }
 
268
  else
 
269
  {
 
270
    QPointF scenePoint = mapToScene( e->pos() );
 
271
 
 
272
    switch ( mCurrentTool )
 
273
    {
 
274
      case Select:
 
275
        QGraphicsView::mouseMoveEvent( e );
 
276
        break;
 
277
 
 
278
      case AddArrow:
 
279
      {
 
280
        if ( mRubberBandLineItem )
 
281
        {
 
282
          mRubberBandLineItem->setLine( mRubberBandStartPos.x(), mRubberBandStartPos.y(),  scenePoint.x(),  scenePoint.y() );
 
283
        }
 
284
        break;
 
285
      }
 
286
 
 
287
      case AddMap:
 
288
      case AddShape:
 
289
        //adjust rubber band item
 
290
      {
 
291
        double x = 0;
 
292
        double y = 0;
 
293
        double width = 0;
 
294
        double height = 0;
 
295
 
 
296
        double dx = scenePoint.x() - mRubberBandStartPos.x();
 
297
        double dy = scenePoint.y() - mRubberBandStartPos.y();
 
298
 
 
299
        if ( dx < 0 )
 
300
        {
 
301
          x = scenePoint.x();
 
302
          width = -dx;
 
303
        }
 
304
        else
 
305
        {
 
306
          x = mRubberBandStartPos.x();
 
307
          width = dx;
 
308
        }
 
309
 
 
310
        if ( dy < 0 )
 
311
        {
 
312
          y = scenePoint.y();
 
313
          height = -dy;
 
314
        }
 
315
        else
 
316
        {
 
317
          y = mRubberBandStartPos.y();
 
318
          height = dy;
 
319
        }
 
320
 
 
321
        if ( mRubberBandItem )
 
322
        {
 
323
          mRubberBandItem->setRect( 0, 0, width, height );
 
324
          QTransform t;
 
325
          t.translate( x, y );
 
326
          mRubberBandItem->setTransform( t );
 
327
        }
 
328
        break;
 
329
      }
 
330
 
 
331
      case MoveItemContent:
 
332
      {
 
333
        //update map preview if composer map
 
334
        QgsComposerMap* composerMap = dynamic_cast<QgsComposerMap *>( mMoveContentItem );
 
335
        if ( composerMap )
 
336
        {
 
337
          composerMap->setOffset( scenePoint.x() - mMoveContentStartPos.x(), scenePoint.y() - mMoveContentStartPos.y() );
 
338
          composerMap->update();
 
339
        }
 
340
        break;
 
341
      }
 
342
      default:
 
343
        break;
 
344
    }
 
345
  }
 
346
}
 
347
 
 
348
void QgsComposerView::keyPressEvent( QKeyEvent * e )
 
349
{
 
350
  if ( e->key() == Qt::Key_Shift )
 
351
  {
 
352
    mShiftKeyPressed = true;
 
353
  }
 
354
 
 
355
  if ( !composition() )
 
356
  {
 
357
    return;
 
358
  }
 
359
 
 
360
  QList<QgsComposerItem*> composerItemList = composition()->selectedComposerItems();
 
361
  QList<QgsComposerItem*>::iterator itemIt = composerItemList.begin();
 
362
 
 
363
  //delete selected items
 
364
  if ( e->key() == Qt::Key_Delete )
 
365
  {
 
366
    for ( ; itemIt != composerItemList.end(); ++itemIt )
 
367
    {
 
368
      QgsComposerMap* map = dynamic_cast<QgsComposerMap *>( *itemIt );
 
369
      if ( !map || !map->isDrawing() ) //don't delete a composer map while it draws
 
370
      {
 
371
        composition()->removeItem( *itemIt );
 
372
        emit itemRemoved( *itemIt );
 
373
      }
 
374
    }
 
375
  }
 
376
 
 
377
  else if ( e->key() == Qt::Key_Left )
 
378
  {
 
379
    for ( ; itemIt != composerItemList.end(); ++itemIt )
 
380
    {
 
381
      ( *itemIt )->move( -1.0, 0.0 );
 
382
    }
 
383
  }
 
384
  else if ( e->key() == Qt::Key_Right )
 
385
  {
 
386
    for ( ; itemIt != composerItemList.end(); ++itemIt )
 
387
    {
 
388
      ( *itemIt )->move( 1.0, 0.0 );
 
389
    }
 
390
  }
 
391
  else if ( e->key() == Qt::Key_Down )
 
392
  {
 
393
    for ( ; itemIt != composerItemList.end(); ++itemIt )
 
394
    {
 
395
      ( *itemIt )->move( 0.0, 1.0 );
 
396
    }
 
397
  }
 
398
  else if ( e->key() == Qt::Key_Up )
 
399
  {
 
400
    for ( ; itemIt != composerItemList.end(); ++itemIt )
 
401
    {
 
402
      ( *itemIt )->move( 0.0, -1.0 );
 
403
    }
 
404
  }
 
405
}
 
406
 
 
407
void QgsComposerView::keyReleaseEvent( QKeyEvent * e )
 
408
{
 
409
  if ( e->key() == Qt::Key_Shift )
 
410
  {
 
411
    mShiftKeyPressed = false;
 
412
  }
 
413
}
 
414
 
 
415
void QgsComposerView::wheelEvent( QWheelEvent* event )
 
416
{
 
417
  QPointF scenePoint = mapToScene( event->pos() );
 
418
 
 
419
  //select topmost item at position of event
 
420
  QgsComposerItem* theItem = composition()->composerItemAt( scenePoint );
 
421
  if ( theItem )
 
422
  {
 
423
    if ( theItem->isSelected() )
 
424
    {
 
425
      QPointF itemPoint = theItem->mapFromScene( scenePoint );
 
426
      theItem->zoomContent( event->delta(), itemPoint.x(), itemPoint.y() );
 
427
    }
 
428
  }
 
429
}
 
430
 
 
431
void QgsComposerView::setComposition( QgsComposition* c )
 
432
{
 
433
  setScene( c );
 
434
}
 
435
 
 
436
QgsComposition* QgsComposerView::composition()
 
437
{
 
438
  if ( scene() )
 
439
  {
 
440
    QgsComposition* c = dynamic_cast<QgsComposition *>( scene() );
 
441
    if ( c )
 
442
    {
 
443
      return c;
 
444
    }
 
445
  }
 
446
  return 0;
 
447
}
 
448
 
 
449
void QgsComposerView::addComposerArrow( QgsComposerArrow* arrow )
 
450
{
 
451
  composition()->addItem( arrow );
 
452
  emit composerArrowAdded( arrow );
 
453
  scene()->clearSelection();
 
454
  arrow->setSelected( true );
 
455
  emit selectedItemChanged( arrow );
 
456
}
 
457
 
 
458
void QgsComposerView::addComposerLabel( QgsComposerLabel* label )
 
459
{
 
460
  composition()->addItem( label );
 
461
  emit composerLabelAdded( label );
 
462
  scene()->clearSelection();
 
463
  label->setSelected( true );
 
464
  emit selectedItemChanged( label );
 
465
}
 
466
 
 
467
void QgsComposerView::addComposerMap( QgsComposerMap* map )
 
468
{
 
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 );
 
472
  map->cache();
 
473
  emit composerMapAdded( map );
 
474
  scene()->clearSelection();
 
475
  map->setSelected( true );
 
476
  emit selectedItemChanged( map );
 
477
}
 
478
 
 
479
void QgsComposerView::addComposerScaleBar( QgsComposerScaleBar* scaleBar )
 
480
{
 
481
  //take first available map...
 
482
  QList<const QgsComposerMap*> mapItemList = composition()->composerMapItems();
 
483
  if ( mapItemList.size() > 0 )
 
484
  {
 
485
    scaleBar->setComposerMap( mapItemList.at( 0 ) );
 
486
  }
 
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 );
 
493
}
 
494
 
 
495
void QgsComposerView::addComposerLegend( QgsComposerLegend* legend )
 
496
{
 
497
  scene()->addItem( legend );
 
498
  emit composerLegendAdded( legend );
 
499
  scene()->clearSelection();
 
500
  legend->setSelected( true );
 
501
  emit selectedItemChanged( legend );
 
502
  emit actionFinished();
 
503
}
 
504
 
 
505
void QgsComposerView::addComposerPicture( QgsComposerPicture* picture )
 
506
{
 
507
  scene()->addItem( picture );
 
508
  emit composerPictureAdded( picture );
 
509
  scene()->clearSelection();
 
510
  picture->setSelected( true );
 
511
  emit selectedItemChanged( picture );
 
512
}
 
513
 
 
514
void QgsComposerView::addComposerShape( QgsComposerShape* shape )
 
515
{
 
516
  scene()->addItem( shape );
 
517
  emit composerShapeAdded( shape );
 
518
  scene()->clearSelection();
 
519
  shape->setSelected( true );
 
520
  emit selectedItemChanged( shape );
 
521
}
 
522
 
 
523
void QgsComposerView::groupItems()
 
524
{
 
525
  if ( !composition() )
 
526
  {
 
527
    return;
 
528
  }
 
529
 
 
530
  QList<QgsComposerItem*> selectionList = composition()->selectedComposerItems();
 
531
  if ( selectionList.size() < 2 )
 
532
  {
 
533
    return; //not enough items for a group
 
534
  }
 
535
 
 
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* ) ) );
 
539
 
 
540
  QList<QgsComposerItem*>::iterator itemIter = selectionList.begin();
 
541
  for ( ; itemIter != selectionList.end(); ++itemIter )
 
542
  {
 
543
    itemGroup->addItem( *itemIter );
 
544
  }
 
545
  composition()->addItem( itemGroup );
 
546
  itemGroup->setSelected( true );
 
547
  emit selectedItemChanged( itemGroup );
 
548
}
 
549
 
 
550
void QgsComposerView::ungroupItems()
 
551
{
 
552
  if ( !composition() )
 
553
  {
 
554
    return;
 
555
  }
 
556
 
 
557
  QList<QgsComposerItem*> selectionList = composition()->selectedComposerItems();
 
558
  QList<QgsComposerItem*>::iterator itemIter = selectionList.begin();
 
559
  for ( ; itemIter != selectionList.end(); ++itemIter )
 
560
  {
 
561
    QgsComposerItemGroup* itemGroup = dynamic_cast<QgsComposerItemGroup *>( *itemIter );
 
562
    if ( itemGroup )
 
563
    {
 
564
      itemGroup->removeItems();
 
565
      composition()->removeItem( *itemIter );
 
566
      delete( *itemIter );
 
567
      emit itemRemoved( *itemIter );
 
568
    }
 
569
  }
 
570
 
 
571
}
 
572
 
 
573
void QgsComposerView::sendItemRemovedSignal( QgsComposerItem* item )
 
574
{
 
575
  emit itemRemoved( item );
 
576
}
 
577
 
 
578
QMainWindow* QgsComposerView::composerWindow()
 
579
{
 
580
  QObject* composerObject = 0;
 
581
  QObject* currentObject = parent();
 
582
  if ( !currentObject )
 
583
  {
 
584
    return qobject_cast<QMainWindow *>( currentObject );
 
585
  }
 
586
 
 
587
  while ( true )
 
588
  {
 
589
    if ( currentObject->parent() == 0 )
 
590
    {
 
591
      composerObject = currentObject;
 
592
      break;
 
593
    }
 
594
    currentObject = currentObject->parent();
 
595
  }
 
596
 
 
597
  return qobject_cast<QMainWindow *>( composerObject );
 
598
}
 
599