QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgslayoutview.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayoutview.cpp
3  -----------------
4  Date : July 2017
5  Copyright : (C) 2017 Nyall Dawson
6  Email : nyall dot dawson at gmail dot com
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 "qgslayoutview.h"
19 #include "qgslayout.h"
20 #include "qgslayoutframe.h"
21 #include "qgslayoutmultiframe.h"
22 #include "qgslayoutviewtool.h"
27 #include "qgslayoutmousehandles.h"
28 #include "qgslayoutruler.h"
29 #include "qgslayoutmodel.h"
30 #include "qgssettings.h"
31 #include "qgsrectangle.h"
32 #include "qgsapplication.h"
34 #include "qgsproject.h"
35 #include "qgslayoutitemgroup.h"
37 #include "qgslayoutundostack.h"
39 #include "qgsreadwritecontext.h"
40 #include <memory>
41 #include <QDesktopWidget>
42 #include <QMenu>
43 #include <QClipboard>
44 
45 #define MIN_VIEW_SCALE 0.05
46 #define MAX_VIEW_SCALE 1000.0
47 
48 QgsLayoutView::QgsLayoutView( QWidget *parent )
49  : QGraphicsView( parent )
50 {
51  setResizeAnchor( QGraphicsView::AnchorViewCenter );
52  setMouseTracking( true );
53  viewport()->setMouseTracking( true );
54 
55  // set the "scene" background on the view using stylesheets
56  // we don't want to use QGraphicsScene::setBackgroundBrush because we want to keep
57  // a transparent background for exports, and it's only a cosmetic thing for the view only
58  // ALSO - only set it on the viewport - we don't want scrollbars/etc affected by this
59  viewport()->setStyleSheet( QStringLiteral( "background-color:#d7d7d7;" ) );
60 
61  mSpacePanTool = new QgsLayoutViewToolTemporaryKeyPan( this );
62  mMidMouseButtonPanTool = new QgsLayoutViewToolTemporaryMousePan( this );
63  mSpaceZoomTool = new QgsLayoutViewToolTemporaryKeyZoom( this );
64 
65  mPreviewEffect = new QgsPreviewEffect( this );
66  viewport()->setGraphicsEffect( mPreviewEffect );
67 
68  connect( this, &QgsLayoutView::zoomLevelChanged, this, &QgsLayoutView::invalidateCachedRenders );
69 }
70 
72 {
73  emit willBeDeleted();
74 }
75 
77 {
78  return qobject_cast<QgsLayout *>( scene() );
79 }
80 
82 {
83  return qobject_cast<const QgsLayout *>( scene() );
84 }
85 
87 {
88  setScene( layout );
89 
92 
93  viewChanged();
94 
95  // IMPORTANT!
96  // previous snap markers, snap lines are owned by previous layout - so don't delete them here!
97  mSnapMarker = new QgsLayoutViewSnapMarker();
98  mSnapMarker->hide();
99  layout->addItem( mSnapMarker );
100  mHorizontalSnapLine = createSnapLine();
101  mHorizontalSnapLine->hide();
102  layout->addItem( mHorizontalSnapLine );
103  mVerticalSnapLine = createSnapLine();
104  mVerticalSnapLine->hide();
105  layout->addItem( mVerticalSnapLine );
106  mSectionLabel = nullptr;
107 
108  if ( mHorizontalRuler )
109  {
110  connect( &layout->guides(), &QAbstractItemModel::dataChanged, mHorizontalRuler, [ = ] { mHorizontalRuler->update(); } );
111  connect( &layout->guides(), &QAbstractItemModel::rowsInserted, mHorizontalRuler, [ = ] { mHorizontalRuler->update(); } );
112  connect( &layout->guides(), &QAbstractItemModel::rowsRemoved, mHorizontalRuler, [ = ] { mHorizontalRuler->update(); } );
113  connect( &layout->guides(), &QAbstractItemModel::modelReset, mHorizontalRuler, [ = ] { mHorizontalRuler->update(); } );
114  }
115  if ( mVerticalRuler )
116  {
117  connect( &layout->guides(), &QAbstractItemModel::dataChanged, mVerticalRuler, [ = ] { mVerticalRuler->update(); } );
118  connect( &layout->guides(), &QAbstractItemModel::rowsInserted, mVerticalRuler, [ = ] { mVerticalRuler->update(); } );
119  connect( &layout->guides(), &QAbstractItemModel::rowsRemoved, mVerticalRuler, [ = ] { mVerticalRuler->update(); } );
120  connect( &layout->guides(), &QAbstractItemModel::modelReset, mVerticalRuler, [ = ] { mVerticalRuler->update(); } );
121  }
122 
123  //emit layoutSet, so that designer dialogs can update for the new layout
124  emit layoutSet( layout );
125 }
126 
128 {
129  return mTool;
130 }
131 
133 {
134  if ( !tool )
135  return;
136 
137  if ( mTool )
138  {
139  mTool->deactivate();
140  disconnect( mTool, &QgsLayoutViewTool::itemFocused, this, &QgsLayoutView::itemFocused );
141  }
142 
143  if ( mSnapMarker )
144  mSnapMarker->hide();
145  if ( mHorizontalSnapLine )
146  mHorizontalSnapLine->hide();
147  if ( mVerticalSnapLine )
148  mVerticalSnapLine->hide();
149 
150  // activate new tool before setting it - gives tools a chance
151  // to respond to whatever the current tool is
152  tool->activate();
153  mTool = tool;
155  emit toolSet( mTool );
156 }
157 
159 {
160  if ( mTool && mTool == tool )
161  {
162  mTool->deactivate();
163  emit toolSet( nullptr );
164  setCursor( Qt::ArrowCursor );
165  }
166 }
167 
169 {
170  mPreviewEffect->setEnabled( enabled );
171 }
172 
174 {
175  return mPreviewEffect->isEnabled();
176 }
177 
179 {
180  mPreviewEffect->setMode( mode );
181 }
182 
184 {
185  return mPreviewEffect->mode();
186 }
187 
188 void QgsLayoutView::scaleSafe( double scale )
189 {
190  double currentScale = transform().m11();
191  scale *= currentScale;
192  scale = qBound( MIN_VIEW_SCALE, scale, MAX_VIEW_SCALE );
193  setTransform( QTransform::fromScale( scale, scale ) );
194  emit zoomLevelChanged();
195  viewChanged();
196 }
197 
198 void QgsLayoutView::setZoomLevel( double level )
199 {
200  if ( !currentLayout() )
201  return;
202 
203  if ( currentLayout()->units() == QgsUnitTypes::LayoutPixels )
204  {
205  setTransform( QTransform::fromScale( level, level ) );
206  }
207  else
208  {
209  double dpi = QgsApplication::desktop()->logicalDpiX();
210  //monitor dpi is not always correct - so make sure the value is sane
211  if ( ( dpi < 60 ) || ( dpi > 1200 ) )
212  dpi = 72;
213 
214  //desired pixel width for 1mm on screen
215  level = qBound( MIN_VIEW_SCALE, level, MAX_VIEW_SCALE );
216  double mmLevel = currentLayout()->convertFromLayoutUnits( level, QgsUnitTypes::LayoutMillimeters ).length() * dpi / 25.4;
217  setTransform( QTransform::fromScale( mmLevel, mmLevel ) );
218  }
219  emit zoomLevelChanged();
220  viewChanged();
221 }
222 
224 {
225  mHorizontalRuler = ruler;
226  ruler->setLayoutView( this );
227  if ( QgsLayout *layout = currentLayout() )
228  {
229  connect( &layout->guides(), &QAbstractItemModel::dataChanged, ruler, [ = ] { mHorizontalRuler->update(); } );
230  connect( &layout->guides(), &QAbstractItemModel::rowsInserted, ruler, [ = ] { mHorizontalRuler->update(); } );
231  connect( &layout->guides(), &QAbstractItemModel::rowsRemoved, ruler, [ = ] { mHorizontalRuler->update(); } );
232  connect( &layout->guides(), &QAbstractItemModel::modelReset, ruler, [ = ] { mHorizontalRuler->update(); } );
233  }
234  viewChanged();
235 }
236 
238 {
239  mVerticalRuler = ruler;
240  ruler->setLayoutView( this );
241  if ( QgsLayout *layout = currentLayout() )
242  {
243  connect( &layout->guides(), &QAbstractItemModel::dataChanged, ruler, [ = ] { mVerticalRuler->update(); } );
244  connect( &layout->guides(), &QAbstractItemModel::rowsInserted, ruler, [ = ] { mVerticalRuler->update(); } );
245  connect( &layout->guides(), &QAbstractItemModel::rowsRemoved, ruler, [ = ] { mVerticalRuler->update(); } );
246  connect( &layout->guides(), &QAbstractItemModel::modelReset, ruler, [ = ] { mVerticalRuler->update(); } );
247  }
248  viewChanged();
249 }
250 
252 {
253  mMenuProvider.reset( provider );
254 }
255 
257 {
258  return mMenuProvider.get();
259 }
260 
261 QList<QgsLayoutItemPage *> QgsLayoutView::visiblePages() const
262 {
263  if ( !currentLayout() )
264  return QList< QgsLayoutItemPage *>();
265 
266  //get current visible part of scene
267  QRect viewportRect( 0, 0, viewport()->width(), viewport()->height() );
268  QRectF visibleRect = mapToScene( viewportRect ).boundingRect();
269  return currentLayout()->pageCollection()->visiblePages( visibleRect );
270 }
271 
273 {
274  if ( !currentLayout() )
275  return QList< int >();
276 
277  //get current visible part of scene
278  QRect viewportRect( 0, 0, viewport()->width(), viewport()->height() );
279  QRectF visibleRect = mapToScene( viewportRect ).boundingRect();
280  return currentLayout()->pageCollection()->visiblePageNumbers( visibleRect );
281 }
282 
284 {
285  if ( !currentLayout() )
286  return;
287 
288  const QList<QgsLayoutItem *> selectedItems = currentLayout()->selectedLayoutItems();
289  QgsLayoutAligner::alignItems( currentLayout(), selectedItems, alignment );
290 }
291 
293 {
294  if ( !currentLayout() )
295  return;
296 
297  const QList<QgsLayoutItem *> selectedItems = currentLayout()->selectedLayoutItems();
298  QgsLayoutAligner::distributeItems( currentLayout(), selectedItems, distribution );
299 }
300 
302 {
303  if ( !currentLayout() )
304  return;
305 
306  const QList<QgsLayoutItem *> selectedItems = currentLayout()->selectedLayoutItems();
307  QgsLayoutAligner::resizeItems( currentLayout(), selectedItems, resize );
308 }
309 
311 {
312  copyItems( currentLayout()->selectedLayoutItems(), operation );
313 }
314 
315 void QgsLayoutView::copyItems( const QList<QgsLayoutItem *> &items, QgsLayoutView::ClipboardOperation operation )
316 {
317  if ( !currentLayout() )
318  return;
319 
320  QgsReadWriteContext context;
321  QDomDocument doc;
322  QDomElement documentElement = doc.createElement( QStringLiteral( "LayoutItemClipboard" ) );
323  if ( operation == ClipboardCut )
324  currentLayout()->undoStack()->beginMacro( tr( "Cut Items" ) );
325 
326  QSet< QgsLayoutMultiFrame * > copiedMultiFrames;
327 
328  for ( QgsLayoutItem *item : items )
329  {
330  // copy every child from a group
331  if ( QgsLayoutItemGroup *itemGroup = qobject_cast<QgsLayoutItemGroup *>( item ) )
332  {
333  const QList<QgsLayoutItem *> groupedItems = itemGroup->items();
334  for ( const QgsLayoutItem *groupedItem : groupedItems )
335  {
336  groupedItem->writeXml( documentElement, doc, context );
337  }
338  }
339  else if ( QgsLayoutFrame *frame = qobject_cast<QgsLayoutFrame *>( item ) )
340  {
341  // copy multiframe too
342  if ( frame->multiFrame() && !copiedMultiFrames.contains( frame->multiFrame() ) )
343  {
344  frame->multiFrame()->writeXml( documentElement, doc, context );
345  copiedMultiFrames.insert( frame->multiFrame() );
346  }
347  }
348  item->writeXml( documentElement, doc, context );
349  if ( operation == ClipboardCut )
350  currentLayout()->removeLayoutItem( item );
351  }
352  doc.appendChild( documentElement );
353  if ( operation == ClipboardCut )
354  {
356  currentLayout()->update();
357  }
358 
359  //remove the UUIDs since we don't want any duplicate UUID
360  QDomNodeList itemsNodes = doc.elementsByTagName( QStringLiteral( "LayoutItem" ) );
361  for ( int i = 0; i < itemsNodes.count(); ++i )
362  {
363  QDomNode itemNode = itemsNodes.at( i );
364  if ( itemNode.isElement() )
365  {
366  itemNode.toElement().removeAttribute( QStringLiteral( "uuid" ) );
367  itemNode.toElement().removeAttribute( QStringLiteral( "groupUuid" ) );
368  }
369  }
370  QDomNodeList multiFrameNodes = doc.elementsByTagName( QStringLiteral( "LayoutMultiFrame" ) );
371  for ( int i = 0; i < multiFrameNodes.count(); ++i )
372  {
373  QDomNode multiFrameNode = multiFrameNodes.at( i );
374  if ( multiFrameNode.isElement() )
375  {
376  multiFrameNode.toElement().removeAttribute( QStringLiteral( "uuid" ) );
377  QDomNodeList frameNodes = multiFrameNode.toElement().elementsByTagName( QStringLiteral( "childFrame" ) );
378  for ( int j = 0; j < frameNodes.count(); ++j )
379  {
380  QDomNode itemNode = frameNodes.at( j );
381  if ( itemNode.isElement() )
382  {
383  itemNode.toElement().removeAttribute( QStringLiteral( "uuid" ) );
384  }
385  }
386  }
387  }
388 
389  QMimeData *mimeData = new QMimeData;
390  mimeData->setData( QStringLiteral( "text/xml" ), doc.toByteArray() );
391  QClipboard *clipboard = QApplication::clipboard();
392  clipboard->setMimeData( mimeData );
393 }
394 
395 QList< QgsLayoutItem * > QgsLayoutView::pasteItems( QgsLayoutView::PasteMode mode )
396 {
397  if ( !currentLayout() )
398  return QList< QgsLayoutItem * >();
399 
400  QList< QgsLayoutItem * > pastedItems;
401  QDomDocument doc;
402  QClipboard *clipboard = QApplication::clipboard();
403  if ( doc.setContent( clipboard->mimeData()->data( QStringLiteral( "text/xml" ) ) ) )
404  {
405  QDomElement docElem = doc.documentElement();
406  if ( docElem.tagName() == QLatin1String( "LayoutItemClipboard" ) )
407  {
408  QPointF pt;
409  switch ( mode )
410  {
411  case PasteModeCursor:
412  case PasteModeInPlace:
413  {
414  // place items at cursor position
415  pt = mapToScene( mapFromGlobal( QCursor::pos() ) );
416  break;
417  }
418  case PasteModeCenter:
419  {
420  // place items in center of viewport
421  pt = mapToScene( viewport()->rect().center() );
422  break;
423  }
424  }
425  bool pasteInPlace = ( mode == PasteModeInPlace );
426  currentLayout()->undoStack()->beginMacro( tr( "Paste Items" ) );
427  currentLayout()->undoStack()->beginCommand( currentLayout(), tr( "Paste Items" ) );
428  pastedItems = currentLayout()->addItemsFromXml( docElem, doc, QgsReadWriteContext(), &pt, pasteInPlace );
431  }
432  }
433  return pastedItems;
434 }
435 
436 QList<QgsLayoutItem *> QgsLayoutView::pasteItems( QPointF layoutPoint )
437 {
438  if ( !currentLayout() )
439  return QList<QgsLayoutItem *>();
440 
441  QList< QgsLayoutItem * > pastedItems;
442  QDomDocument doc;
443  QClipboard *clipboard = QApplication::clipboard();
444  if ( doc.setContent( clipboard->mimeData()->data( QStringLiteral( "text/xml" ) ) ) )
445  {
446  QDomElement docElem = doc.documentElement();
447  if ( docElem.tagName() == QLatin1String( "LayoutItemClipboard" ) )
448  {
449  currentLayout()->undoStack()->beginMacro( tr( "Paste Items" ) );
450  currentLayout()->undoStack()->beginCommand( currentLayout(), tr( "Paste Items" ) );
451  pastedItems = currentLayout()->addItemsFromXml( docElem, doc, QgsReadWriteContext(), &layoutPoint, false );
454  }
455  }
456  return pastedItems;
457 }
458 
460 {
461  QDomDocument doc;
462  QClipboard *clipboard = QApplication::clipboard();
463  if ( doc.setContent( clipboard->mimeData()->data( QStringLiteral( "text/xml" ) ) ) )
464  {
465  QDomElement docElem = doc.documentElement();
466  if ( docElem.tagName() == QLatin1String( "LayoutItemClipboard" ) )
467  return true;
468  }
469  return false;
470 }
471 
472 QPointF QgsLayoutView::deltaForKeyEvent( QKeyEvent *event )
473 {
474  // increment used for cursor key item movement
475  double increment = 1.0;
476  if ( event->modifiers() & Qt::ShiftModifier )
477  {
478  //holding shift while pressing cursor keys results in a big step
479  increment = 10.0;
480  }
481  else if ( event->modifiers() & Qt::AltModifier )
482  {
483  //holding alt while pressing cursor keys results in a 1 pixel step
484  double viewScale = transform().m11();
485  if ( viewScale > 0 )
486  {
487  increment = 1 / viewScale;
488  }
489  }
490 
491  double deltaX = 0;
492  double deltaY = 0;
493  switch ( event->key() )
494  {
495  case Qt::Key_Left:
496  deltaX = -increment;
497  break;
498  case Qt::Key_Right:
499  deltaX = increment;
500  break;
501  case Qt::Key_Up:
502  deltaY = -increment;
503  break;
504  case Qt::Key_Down:
505  deltaY = increment;
506  break;
507  default:
508  break;
509  }
510 
511  return QPointF( deltaX, deltaY );
512 }
513 
515 {
516  mPaintingEnabled = enabled;
517  if ( enabled )
518  update();
519 }
520 
521 void QgsLayoutView::setSectionLabel( const QString &label )
522 {
523  if ( !currentLayout() )
524  return;
525 
526  if ( !mSectionLabel )
527  {
528  mSectionLabel = new QgsLayoutReportSectionLabel( currentLayout(), this );
529  currentLayout()->addItem( mSectionLabel );
530  mSectionLabel->setRect( 0, -200, 1000, 200 );
531  mSectionLabel->setZValue( -1 );
532  }
533  mSectionLabel->setLabel( label );
534 }
535 
537 {
538  if ( !scene() )
539  return;
540 
541  fitInView( scene()->sceneRect(), Qt::KeepAspectRatio );
542  viewChanged();
543  emit zoomLevelChanged();
544 }
545 
547 {
548  if ( !scene() )
549  return;
550 
551  //get current visible part of scene
552  QRect viewportRect( 0, 0, viewport()->width(), viewport()->height() );
553  QRectF visibleRect = mapToScene( viewportRect ).boundingRect();
554 
555  double verticalCenter = ( visibleRect.top() + visibleRect.bottom() ) / 2.0;
556  // expand out visible rect to include left/right edges of scene
557  // centered on current visible vertical center
558  // note that we can't have a 0 height rect - fitInView doesn't handle that
559  // so we just set a very small height instead.
560  const double tinyHeight = 0.01;
561  QRectF targetRect( scene()->sceneRect().left(),
562  verticalCenter - tinyHeight,
563  scene()->sceneRect().width(),
564  tinyHeight * 2 );
565 
566  fitInView( targetRect, Qt::KeepAspectRatio );
567  emit zoomLevelChanged();
568  viewChanged();
569 }
570 
572 {
573  scaleSafe( 2 );
574 }
575 
577 {
578  scaleSafe( 0.5 );
579 }
580 
582 {
583  setZoomLevel( 1.0 );
584 }
585 
587 {
588  emit zoomLevelChanged();
589 }
590 
592 {
593  if ( !currentLayout() )
594  {
595  return;
596  }
597 
598  //select all items in layout
599  QgsLayoutItem *focusedItem = nullptr;
600  const QList<QGraphicsItem *> itemList = currentLayout()->items();
601  for ( QGraphicsItem *graphicsItem : itemList )
602  {
603  QgsLayoutItem *item = dynamic_cast<QgsLayoutItem *>( graphicsItem );
604  QgsLayoutItemPage *paperItem = dynamic_cast<QgsLayoutItemPage *>( graphicsItem );
605  if ( item && !paperItem )
606  {
607  if ( !item->isLocked() )
608  {
609  item->setSelected( true );
610  if ( !focusedItem )
611  focusedItem = item;
612  }
613  else
614  {
615  //deselect all locked items
616  item->setSelected( false );
617  }
618  }
619  }
620  emit itemFocused( focusedItem );
621 }
622 
624 {
625  if ( !currentLayout() )
626  {
627  return;
628  }
629 
631 }
632 
634 {
635  if ( !currentLayout() )
636  {
637  return;
638  }
639 
640  QgsLayoutItem *focusedItem = nullptr;
641  //check all items in layout
642  const QList<QGraphicsItem *> itemList = currentLayout()->items();
643  for ( QGraphicsItem *graphicsItem : itemList )
644  {
645  QgsLayoutItem *item = dynamic_cast<QgsLayoutItem *>( graphicsItem );
646  QgsLayoutItemPage *paperItem = dynamic_cast<QgsLayoutItemPage *>( graphicsItem );
647  if ( item && !paperItem )
648  {
649  //flip selected state for items (and deselect any locked items)
650  if ( item->isSelected() || item->isLocked() )
651  {
652  item->setSelected( false );
653  }
654  else
655  {
656  item->setSelected( true );
657  if ( !focusedItem )
658  focusedItem = item;
659  }
660  }
661  }
662  if ( focusedItem )
663  emit itemFocused( focusedItem );
664 }
665 
666 
667 void selectNextByZOrder( QgsLayout *layout, bool above )
668 {
669  if ( !layout )
670  return;
671 
672  QgsLayoutItem *previousSelectedItem = nullptr;
673  const QList<QgsLayoutItem *> selectedItems = layout->selectedLayoutItems();
674  if ( !selectedItems.isEmpty() )
675  {
676  previousSelectedItem = selectedItems.at( 0 );
677  }
678 
679  if ( !previousSelectedItem )
680  {
681  return;
682  }
683 
684  //select item with target z value
685  QgsLayoutItem *selectedItem = nullptr;
686  if ( !above )
687  selectedItem = layout->itemsModel()->findItemBelow( previousSelectedItem );
688  else
689  selectedItem = layout->itemsModel()->findItemAbove( previousSelectedItem );
690 
691  if ( !selectedItem )
692  {
693  return;
694  }
695 
696  //OK, found a good target item
697  layout->setSelectedItem( selectedItem );
698 }
699 
701 {
703 }
704 
706 {
707  selectNextByZOrder( currentLayout(), false );
708 }
709 
711 {
712  if ( !currentLayout() )
713  return;
714 
715  const QList<QgsLayoutItem *> selectedItems = currentLayout()->selectedLayoutItems();
716  bool itemsRaised = false;
717  for ( QgsLayoutItem *item : selectedItems )
718  {
719  itemsRaised = itemsRaised | currentLayout()->raiseItem( item, true );
720  }
721 
722  if ( !itemsRaised )
723  {
724  //no change
725  return;
726  }
727 
728  //update all positions
730  currentLayout()->update();
731 }
732 
734 {
735  if ( !currentLayout() )
736  return;
737 
738  const QList<QgsLayoutItem *> selectedItems = currentLayout()->selectedLayoutItems();
739  bool itemsLowered = false;
740  for ( QgsLayoutItem *item : selectedItems )
741  {
742  itemsLowered = itemsLowered | currentLayout()->lowerItem( item, true );
743  }
744 
745  if ( !itemsLowered )
746  {
747  //no change
748  return;
749  }
750 
751  //update all positions
753  currentLayout()->update();
754 }
755 
757 {
758  if ( !currentLayout() )
759  return;
760 
761  const QList<QgsLayoutItem *> selectedItems = currentLayout()->selectedLayoutItems();
762  bool itemsRaised = false;
763  for ( QgsLayoutItem *item : selectedItems )
764  {
765  itemsRaised = itemsRaised | currentLayout()->moveItemToTop( item, true );
766  }
767 
768  if ( !itemsRaised )
769  {
770  //no change
771  return;
772  }
773 
774  //update all positions
776  currentLayout()->update();
777 }
778 
780 {
781  if ( !currentLayout() )
782  return;
783 
784  const QList<QgsLayoutItem *> selectedItems = currentLayout()->selectedLayoutItems();
785  bool itemsLowered = false;
786  for ( QgsLayoutItem *item : selectedItems )
787  {
788  itemsLowered = itemsLowered | currentLayout()->moveItemToBottom( item, true );
789  }
790 
791  if ( !itemsLowered )
792  {
793  //no change
794  return;
795  }
796 
797  //update all positions
799  currentLayout()->update();
800 }
801 
803 {
804  if ( !currentLayout() )
805  return;
806 
807  currentLayout()->undoStack()->beginMacro( tr( "Lock Items" ) );
808  const QList<QgsLayoutItem *> selectionList = currentLayout()->selectedLayoutItems();
809  for ( QgsLayoutItem *item : selectionList )
810  {
811  item->setLocked( true );
812  }
813 
816 }
817 
819 {
820  if ( !currentLayout() )
821  return;
822 
823  //unlock all items in layout
824  currentLayout()->undoStack()->beginMacro( tr( "Unlock Items" ) );
825 
826  //first, clear the selection
828 
829  QgsLayoutItem *focusItem = nullptr;
830 
831  const QList<QGraphicsItem *> itemList = currentLayout()->items();
832  for ( QGraphicsItem *graphicItem : itemList )
833  {
834  QgsLayoutItem *item = dynamic_cast<QgsLayoutItem *>( graphicItem );
835  if ( item && item->isLocked() )
836  {
837  focusItem = item;
838  item->setLocked( false );
839  //select unlocked items, same behavior as illustrator
840  item->setSelected( true );
841  }
842  }
844 
845  emit itemFocused( focusItem );
846 }
847 
849 {
850  if ( !currentLayout() )
851  return;
852 
853  deleteItems( currentLayout()->selectedLayoutItems() );
854 }
855 
856 void QgsLayoutView::deleteItems( const QList<QgsLayoutItem *> &items )
857 {
858  if ( !currentLayout() )
859  return;
860 
861  if ( items.empty() )
862  return;
863 
864  currentLayout()->undoStack()->beginMacro( tr( "Delete Items" ) );
865  //delete selected items
866  for ( QgsLayoutItem *item : items )
867  {
868  currentLayout()->removeLayoutItem( item );
869  }
871  currentLayout()->project()->setDirty( true );
872 }
873 
875 {
876  if ( !currentLayout() )
877  {
878  return;
879  }
880 
881  //group selected items
882  const QList<QgsLayoutItem *> selectionList = currentLayout()->selectedLayoutItems();
883  QgsLayoutItemGroup *itemGroup = currentLayout()->groupItems( selectionList );
884 
885  if ( !itemGroup )
886  {
887  //group could not be created
888  return;
889  }
890 
891  for ( QgsLayoutItem *item : selectionList )
892  {
893  item->setSelected( false );
894  }
895 
896  currentLayout()->setSelectedItem( itemGroup );
897 }
898 
900 {
901  if ( !currentLayout() )
902  {
903  return;
904  }
905 
906  QList< QgsLayoutItem * > ungroupedItems;
907  //hunt through selection for any groups, and ungroup them
908  const QList<QgsLayoutItem *> selectionList = currentLayout()->selectedLayoutItems();
909  for ( QgsLayoutItem *item : selectionList )
910  {
911  if ( item->type() == QgsLayoutItemRegistry::LayoutGroup )
912  {
913  QgsLayoutItemGroup *itemGroup = static_cast<QgsLayoutItemGroup *>( item );
914  ungroupedItems.append( currentLayout()->ungroupItems( itemGroup ) );
915  }
916  }
917 
918  if ( !ungroupedItems.empty() )
919  {
920  for ( QgsLayoutItem *item : qgis::as_const( ungroupedItems ) )
921  {
922  item->setSelected( true );
923  }
924  emit itemFocused( ungroupedItems.at( 0 ) );
925  }
926 }
927 
928 void QgsLayoutView::mousePressEvent( QMouseEvent *event )
929 {
930  if ( !currentLayout() )
931  return;
932 
933  if ( mSnapMarker )
934  mSnapMarker->setVisible( false );
935 
936  if ( mTool )
937  {
938  std::unique_ptr<QgsLayoutViewMouseEvent> me( new QgsLayoutViewMouseEvent( this, event, mTool->flags() & QgsLayoutViewTool::FlagSnaps ) );
939  mTool->layoutPressEvent( me.get() );
940  event->setAccepted( me->isAccepted() );
941  }
942 
943  if ( !mTool || !event->isAccepted() )
944  {
945  if ( event->button() == Qt::MidButton )
946  {
947  // Pan layout with middle mouse button
948  setTool( mMidMouseButtonPanTool );
949  event->accept();
950  }
951  else if ( event->button() == Qt::RightButton && mMenuProvider )
952  {
953  QMenu *menu = mMenuProvider->createContextMenu( this, currentLayout(), mapToScene( event->pos() ) );
954  if ( menu )
955  {
956  menu->exec( event->globalPos() );
957  delete menu;
958  }
959  }
960  else
961  {
962  QGraphicsView::mousePressEvent( event );
963  }
964  }
965 }
966 
967 void QgsLayoutView::mouseReleaseEvent( QMouseEvent *event )
968 {
969  if ( !currentLayout() )
970  return;
971 
972  if ( mTool )
973  {
974  std::unique_ptr<QgsLayoutViewMouseEvent> me( new QgsLayoutViewMouseEvent( this, event, mTool->flags() & QgsLayoutViewTool::FlagSnaps ) );
975  mTool->layoutReleaseEvent( me.get() );
976  event->setAccepted( me->isAccepted() );
977  }
978 
979  if ( !mTool || !event->isAccepted() )
980  QGraphicsView::mouseReleaseEvent( event );
981 }
982 
983 void QgsLayoutView::mouseMoveEvent( QMouseEvent *event )
984 {
985  if ( !currentLayout() )
986  return;
987 
988  mMouseCurrentXY = event->pos();
989 
990  QPointF cursorPos = mapToScene( mMouseCurrentXY );
991  if ( mTool )
992  {
993  std::unique_ptr<QgsLayoutViewMouseEvent> me( new QgsLayoutViewMouseEvent( this, event, false ) );
994  if ( mTool->flags() & QgsLayoutViewTool::FlagSnaps )
995  {
996  me->snapPoint( mHorizontalSnapLine, mVerticalSnapLine, mTool->ignoredSnapItems() );
997  }
998  if ( mTool->flags() & QgsLayoutViewTool::FlagSnaps )
999  {
1000  //draw snapping point indicator
1001  if ( me->isSnapped() )
1002  {
1003  cursorPos = me->snappedPoint();
1004  if ( mSnapMarker )
1005  {
1006  mSnapMarker->setPos( me->snappedPoint() );
1007  mSnapMarker->setVisible( true );
1008  }
1009  }
1010  else if ( mSnapMarker )
1011  {
1012  mSnapMarker->setVisible( false );
1013  }
1014  }
1015  mTool->layoutMoveEvent( me.get() );
1016  event->setAccepted( me->isAccepted() );
1017  }
1018 
1019  //update cursor position in status bar
1020  emit cursorPosChanged( cursorPos );
1021 
1022  if ( !mTool || !event->isAccepted() )
1023  QGraphicsView::mouseMoveEvent( event );
1024 }
1025 
1026 void QgsLayoutView::mouseDoubleClickEvent( QMouseEvent *event )
1027 {
1028  if ( !currentLayout() )
1029  return;
1030 
1031  if ( mTool )
1032  {
1033  std::unique_ptr<QgsLayoutViewMouseEvent> me( new QgsLayoutViewMouseEvent( this, event, mTool->flags() & QgsLayoutViewTool::FlagSnaps ) );
1034  mTool->layoutDoubleClickEvent( me.get() );
1035  event->setAccepted( me->isAccepted() );
1036  }
1037 
1038  if ( !mTool || !event->isAccepted() )
1039  QGraphicsView::mouseDoubleClickEvent( event );
1040 }
1041 
1042 void QgsLayoutView::wheelEvent( QWheelEvent *event )
1043 {
1044  if ( !currentLayout() )
1045  return;
1046 
1047  if ( mTool )
1048  {
1049  mTool->wheelEvent( event );
1050  }
1051 
1052  if ( !mTool || !event->isAccepted() )
1053  {
1054  event->accept();
1055  wheelZoom( event );
1056  }
1057 }
1058 
1059 void QgsLayoutView::keyPressEvent( QKeyEvent *event )
1060 {
1061  if ( !currentLayout() )
1062  return;
1063 
1064  if ( mTool )
1065  {
1066  mTool->keyPressEvent( event );
1067  }
1068 
1069  if ( mTool && event->isAccepted() )
1070  return;
1071 
1072  if ( event->key() == Qt::Key_Space && ! event->isAutoRepeat() )
1073  {
1074  if ( !( event->modifiers() & Qt::ControlModifier ) )
1075  {
1076  // Pan layout with space bar
1077  setTool( mSpacePanTool );
1078  }
1079  else
1080  {
1081  //ctrl+space pressed, so switch to temporary keyboard based zoom tool
1082  setTool( mSpaceZoomTool );
1083  }
1084  event->accept();
1085  }
1086  else if ( event->key() == Qt::Key_Left
1087  || event->key() == Qt::Key_Right
1088  || event->key() == Qt::Key_Up
1089  || event->key() == Qt::Key_Down )
1090  {
1091  QgsLayout *l = currentLayout();
1092  const QList<QgsLayoutItem *> layoutItemList = l->selectedLayoutItems();
1093 
1094  QPointF delta = deltaForKeyEvent( event );
1095 
1096  l->undoStack()->beginMacro( tr( "Move Item" ) );
1097  for ( QgsLayoutItem *item : layoutItemList )
1098  {
1099  l->undoStack()->beginCommand( item, tr( "Move Item" ), QgsLayoutItem::UndoIncrementalMove );
1100  item->attemptMoveBy( delta.x(), delta.y() );
1101  l->undoStack()->endCommand();
1102  }
1103  l->undoStack()->endMacro();
1104  event->accept();
1105  }
1106 }
1107 
1108 void QgsLayoutView::keyReleaseEvent( QKeyEvent *event )
1109 {
1110  if ( !currentLayout() )
1111  return;
1112 
1113  if ( mTool )
1114  {
1115  mTool->keyReleaseEvent( event );
1116  }
1117 
1118  if ( !mTool || !event->isAccepted() )
1119  QGraphicsView::keyReleaseEvent( event );
1120 }
1121 
1122 void QgsLayoutView::resizeEvent( QResizeEvent *event )
1123 {
1124  QGraphicsView::resizeEvent( event );
1125  emit zoomLevelChanged();
1126  viewChanged();
1127 }
1128 
1129 void QgsLayoutView::scrollContentsBy( int dx, int dy )
1130 {
1131  QGraphicsView::scrollContentsBy( dx, dy );
1132  viewChanged();
1133 }
1134 
1135 void QgsLayoutView::dragEnterEvent( QDragEnterEvent *e )
1136 {
1137  // By default graphics view delegates the drag events to graphics items.
1138  // But we do not want that and by ignoring the drag enter we let the
1139  // parent (e.g. QgsLayoutDesignerDialog) to handle drops of files.
1140  e->ignore();
1141 }
1142 
1143 void QgsLayoutView::paintEvent( QPaintEvent *event )
1144 {
1145  if ( mPaintingEnabled )
1146  {
1147  QGraphicsView::paintEvent( event );
1148  event->accept();
1149  }
1150  else
1151  {
1152  event->ignore();
1153  }
1154 }
1155 
1156 void QgsLayoutView::invalidateCachedRenders()
1157 {
1158  if ( !currentLayout() )
1159  return;
1160 
1161  //redraw cached map items
1162  QList< QgsLayoutItem *> items;
1163  currentLayout()->layoutItems( items );
1164 
1165  for ( QgsLayoutItem *item : qgis::as_const( items ) )
1166  {
1167  item->invalidateCache();
1168  }
1169 }
1170 
1172 {
1173  if ( mHorizontalRuler )
1174  {
1175  mHorizontalRuler->setSceneTransform( viewportTransform() );
1176  }
1177  if ( mVerticalRuler )
1178  {
1179  mVerticalRuler->setSceneTransform( viewportTransform() );
1180  }
1181 
1182  // determine page at center of view
1183  QRect viewportRect( 0, 0, viewport()->width(), viewport()->height() );
1184  QRectF visibleRect = mapToScene( viewportRect ).boundingRect();
1185  QPointF centerVisible = visibleRect.center();
1186 
1187  if ( currentLayout() && currentLayout()->pageCollection() )
1188  {
1189  int newPage = currentLayout()->pageCollection()->pageNumberForPoint( centerVisible );
1190  if ( newPage != mCurrentPage )
1191  {
1192  mCurrentPage = newPage;
1193  emit pageChanged( mCurrentPage );
1194  }
1195  }
1196 }
1197 
1198 void QgsLayoutView::pushStatusMessage( const QString &message )
1199 {
1200  emit statusMessage( message );
1201 }
1202 
1203 void QgsLayoutView::wheelZoom( QWheelEvent *event )
1204 {
1205  //get mouse wheel zoom behavior settings
1206  QgsSettings settings;
1207  double zoomFactor = settings.value( QStringLiteral( "qgis/zoom_factor" ), 2 ).toDouble();
1208 
1209  // "Normal" mouse have an angle delta of 120, precision mouses provide data faster, in smaller steps
1210  zoomFactor = 1.0 + ( zoomFactor - 1.0 ) / 120.0 * std::fabs( event->angleDelta().y() );
1211 
1212  if ( event->modifiers() & Qt::ControlModifier )
1213  {
1214  //holding ctrl while wheel zooming results in a finer zoom
1215  zoomFactor = 1.0 + ( zoomFactor - 1.0 ) / 20.0;
1216  }
1217 
1218  //calculate zoom scale factor
1219  bool zoomIn = event->angleDelta().y() > 0;
1220  double scaleFactor = ( zoomIn ? 1 / zoomFactor : zoomFactor );
1221 
1222  //get current visible part of scene
1223  QRect viewportRect( 0, 0, viewport()->width(), viewport()->height() );
1224  QgsRectangle visibleRect = QgsRectangle( mapToScene( viewportRect ).boundingRect() );
1225 
1226  //transform the mouse pos to scene coordinates
1227  QPointF scenePoint = mapToScene( event->pos() );
1228 
1229  //adjust view center
1230  QgsPointXY oldCenter( visibleRect.center() );
1231  QgsPointXY newCenter( scenePoint.x() + ( ( oldCenter.x() - scenePoint.x() ) * scaleFactor ),
1232  scenePoint.y() + ( ( oldCenter.y() - scenePoint.y() ) * scaleFactor ) );
1233  centerOn( newCenter.x(), newCenter.y() );
1234 
1235  //zoom layout
1236  if ( zoomIn )
1237  {
1238  scaleSafe( zoomFactor );
1239  }
1240  else
1241  {
1242  scaleSafe( 1 / zoomFactor );
1243  }
1244 }
1245 
1246 QGraphicsLineItem *QgsLayoutView::createSnapLine() const
1247 {
1248  std::unique_ptr< QGraphicsLineItem> item( new QGraphicsLineItem( nullptr ) );
1249  QPen pen = QPen( QColor( Qt::blue ) );
1250  pen.setStyle( Qt::DotLine );
1251  pen.setWidthF( 0.0 );
1252  item->setPen( pen );
1253  item->setZValue( QgsLayout::ZSmartGuide );
1254  return item.release();
1255 }
1256 
1257 //
1258 // QgsLayoutViewSnapMarker
1259 //
1260 
1262 QgsLayoutViewSnapMarker::QgsLayoutViewSnapMarker()
1263  : QGraphicsRectItem( QRectF( 0, 0, 0, 0 ) )
1264 {
1265  QFont f;
1266  QFontMetrics fm( f );
1267 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
1268  mSize = fm.width( QStringLiteral( "X" ) );
1269 #else
1270  mSize = fm.horizontalAdvance( 'X' );
1271 #endif
1272  setPen( QPen( Qt::transparent, mSize ) );
1273 
1274  setFlags( flags() | QGraphicsItem::ItemIgnoresTransformations );
1275  setZValue( QgsLayout::ZSnapIndicator );
1276 }
1277 
1278 void QgsLayoutViewSnapMarker::paint( QPainter *p, const QStyleOptionGraphicsItem *, QWidget * )
1279 {
1280  QPen pen( QColor( 255, 0, 0 ) );
1281  pen.setWidth( 0 );
1282  p->setPen( pen );
1283  p->setBrush( Qt::NoBrush );
1284 
1285  double halfSize = mSize / 2.0;
1286  p->drawLine( QLineF( -halfSize, -halfSize, halfSize, halfSize ) );
1287  p->drawLine( QLineF( -halfSize, halfSize, halfSize, -halfSize ) );
1288 }
1289 
QgsLayoutView::visiblePageNumbers
QList< int > visiblePageNumbers() const
Returns a list of page numbers for pages which are currently visible in the view.
Definition: qgslayoutview.cpp:272
QgsLayout::deselectAll
void deselectAll()
Clears any selected items in the layout.
Definition: qgslayout.cpp:169
QgsLayoutView::hasItemsInClipboard
bool hasItemsInClipboard() const
Returns true if the current clipboard contains layout items.
Definition: qgslayoutview.cpp:459
qgslayoutviewtool.h
qgslayoutitemgroup.h
QgsLayoutView::setCurrentLayout
void setCurrentLayout(QgsLayout *layout)
Sets the current layout to edit in the view.
Definition: qgslayoutview.cpp:86
QgsLayoutView::zoomFull
void zoomFull()
Zooms the view to the full extent of the layout.
Definition: qgslayoutview.cpp:536
QgsLayout::undoStack
QgsLayoutUndoStack * undoStack()
Returns a pointer to the layout's undo stack, which manages undo/redo states for the layout and it's ...
Definition: qgslayout.cpp:686
QgsLayoutView::keyPressEvent
void keyPressEvent(QKeyEvent *event) override
Definition: qgslayoutview.cpp:1059
qgslayoutundostack.h
QgsLayoutItemPage
Item representing the paper in a layout.
Definition: qgslayoutitempage.h:55
QgsLayoutView::setPreviewModeEnabled
void setPreviewModeEnabled(bool enabled)
Sets whether a preview effect should be used to alter the view's appearance.
Definition: qgslayoutview.cpp:168
QgsLayoutView::setMenuProvider
void setMenuProvider(QgsLayoutViewMenuProvider *provider)
Sets a provider for context menus.
Definition: qgslayoutview.cpp:251
selectNextByZOrder
void selectNextByZOrder(QgsLayout *layout, bool above)
Definition: qgslayoutview.cpp:667
QgsSettings::value
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Definition: qgssettings.cpp:174
QgsLayoutView::menuProvider
QgsLayoutViewMenuProvider * menuProvider() const
Returns the provider for context menus.
Definition: qgslayoutview.cpp:256
QgsLayoutView::setSectionLabel
void setSectionLabel(const QString &label)
Sets a section label, to display above the first page shown in the view.
Definition: qgslayoutview.cpp:521
QgsReadWriteContext
The class is used as a container of context for various read/write operations on other objects.
Definition: qgsreadwritecontext.h:35
qgsrectangle.h
QgsUnitTypes::LayoutPixels
@ LayoutPixels
Pixels.
Definition: qgsunittypes.h:189
QgsLayoutViewToolTemporaryKeyZoom
Layout view tool for temporarily zooming a layout while a key is depressed.
Definition: qgslayoutviewtooltemporarykeyzoom.h:31
QgsLayout::setSelectedItem
void setSelectedItem(QgsLayoutItem *item)
Clears any selected items and sets item as the current selection.
Definition: qgslayout.cpp:159
QgsLayoutView::cursorPosChanged
void cursorPosChanged(QPointF layoutPoint)
Emitted when the mouse cursor coordinates change within the view.
QgsLayout::selectedLayoutItems
QList< QgsLayoutItem * > selectedLayoutItems(bool includeLockedItems=true)
Returns list of selected layout items.
Definition: qgslayout.cpp:142
QgsLayout::layoutItems
void layoutItems(QList< T * > &itemList) const
Returns a list of layout items of a specific type.
Definition: qgslayout.h:121
QgsLayout::raiseItem
bool raiseItem(QgsLayoutItem *item, bool deferUpdate=false)
Raises an item up the z-order.
Definition: qgslayout.cpp:186
QgsLayoutViewTool::FlagSnaps
@ FlagSnaps
Tool utilizes snapped coordinates.
Definition: qgslayoutviewtool.h:65
QgsLayoutViewToolTemporaryKeyPan
Layout view tool for temporarily panning a layout while a key is depressed.
Definition: qgslayoutviewtooltemporarykeypan.h:29
QgsLayoutView::ungroupSelectedItems
void ungroupSelectedItems()
Ungroups all selected items.
Definition: qgslayoutview.cpp:899
QgsLayoutMeasurement::length
double length() const
Returns the length of the measurement.
Definition: qgslayoutmeasurement.h:48
QgsLayoutView::invertSelection
void invertSelection()
Inverts the current selection, selecting deselected items and deselecting and selected items.
Definition: qgslayoutview.cpp:633
QgsLayoutView::paintEvent
void paintEvent(QPaintEvent *event) override
Definition: qgslayoutview.cpp:1143
qgsreadwritecontext.h
QgsRectangle::center
QgsPointXY center() const SIP_HOLDGIL
Returns the center point of the rectangle.
Definition: qgsrectangle.h:230
QgsLayoutView::keyReleaseEvent
void keyReleaseEvent(QKeyEvent *event) override
Definition: qgslayoutview.cpp:1108
QgsLayoutView::pasteItems
QList< QgsLayoutItem * > pasteItems(PasteMode mode)
Pastes items from clipboard, using the specified mode.
Definition: qgslayoutview.cpp:395
QgsLayoutView::PasteMode
PasteMode
Paste modes.
Definition: qgslayoutview.h:77
QgsLayoutAligner::alignItems
static void alignItems(QgsLayout *layout, const QList< QgsLayoutItem * > &items, Alignment alignment)
Aligns a set of items from a layout in place.
Definition: qgslayoutaligner.cpp:22
QgsLayoutUndoStack::endMacro
void endMacro()
Ends a macro command.
Definition: qgslayoutundostack.cpp:36
QgsLayoutView::setVerticalRuler
void setVerticalRuler(QgsLayoutRuler *ruler)
Sets a vertical ruler to synchronize with the view state.
Definition: qgslayoutview.cpp:237
QgsLayoutItem::UndoIncrementalMove
@ UndoIncrementalMove
Layout item incremental movement, e.g. as a result of a keypress.
Definition: qgslayoutitem.h:218
QgsLayoutView::PasteModeCenter
@ PasteModeCenter
Paste items in center of view.
Definition: qgslayoutview.h:79
QgsLayoutView::ClipboardOperation
ClipboardOperation
Clipboard operations.
Definition: qgslayoutview.h:70
qgslayoutview.h
qgslayoutmultiframe.h
QgsLayout::ungroupItems
QList< QgsLayoutItem * > ungroupItems(QgsLayoutItemGroup *group)
Ungroups items by removing them from an item group and removing the group from the layout.
Definition: qgslayout.cpp:764
qgslayoutviewtooltemporarymousepan.h
QgsLayoutAligner::distributeItems
static void distributeItems(QgsLayout *layout, const QList< QgsLayoutItem * > &items, Distribution distribution)
Distributes a set of items from a layout in place.
Definition: qgslayoutaligner.cpp:95
QgsLayoutView::visiblePages
QList< QgsLayoutItemPage * > visiblePages() const
Returns a list of page items which are currently visible in the view.
Definition: qgslayoutview.cpp:261
QgsLayoutView::deselectAll
void deselectAll()
Deselects all items in the view.
Definition: qgslayoutview.cpp:623
QgsSettings
This class is a composition of two QSettings instances:
Definition: qgssettings.h:62
QgsLayoutView::unsetTool
void unsetTool(QgsLayoutViewTool *tool)
Unsets the current view tool, if it matches the specified tool.
Definition: qgslayoutview.cpp:158
QgsLayoutView::selectNextItemBelow
void selectNextItemBelow()
Selects the next item below the existing selection, by item z order.
Definition: qgslayoutview.cpp:705
qgslayoutitemundocommand.h
QgsLayoutView::selectAll
void selectAll()
Selects all items in the view.
Definition: qgslayoutview.cpp:591
qgslayoutviewmouseevent.h
QgsLayoutView::zoomWidth
void zoomWidth()
Zooms the view to the full width of the layout.
Definition: qgslayoutview.cpp:546
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:42
QgsLayoutView::setHorizontalRuler
void setHorizontalRuler(QgsLayoutRuler *ruler)
Sets a horizontal ruler to synchronize with the view state.
Definition: qgslayoutview.cpp:223
QgsLayout::ZSmartGuide
@ ZSmartGuide
Z-value for smart (item bounds based) guides.
Definition: qgslayout.h:62
QgsLayoutViewToolTemporaryMousePan
Layout view tool for temporarily panning a layout while a mouse button is depressed.
Definition: qgslayoutviewtooltemporarymousepan.h:29
QgsLayoutView::moveSelectedItemsToTop
void moveSelectedItemsToTop()
Raises the selected items to the top of the z-order.
Definition: qgslayoutview.cpp:756
QgsLayoutView::deleteItems
void deleteItems(const QList< QgsLayoutItem * > &items)
Delete the specified items.
Definition: qgslayoutview.cpp:856
QgsLayoutItem::setSelected
virtual void setSelected(bool selected)
Sets whether the item should be selected.
Definition: qgslayoutitem.cpp:160
QgsLayoutView::deltaForKeyEvent
QPointF deltaForKeyEvent(QKeyEvent *event)
Returns the delta (in layout coordinates) by which to move items for the given key event.
Definition: qgslayoutview.cpp:472
QgsLayoutItemRegistry::LayoutGroup
@ LayoutGroup
Grouped item.
Definition: qgslayoutitemregistry.h:309
qgslayoutframe.h
QgsLayoutView::alignSelectedItems
void alignSelectedItems(QgsLayoutAligner::Alignment alignment)
Aligns all selected items using the specified alignment.
Definition: qgslayoutview.cpp:283
qgsapplication.h
QgsLayout::addItemsFromXml
QList< QgsLayoutItem * > addItemsFromXml(const QDomElement &parentElement, const QDomDocument &document, const QgsReadWriteContext &context, QPointF *position=nullptr, bool pasteInPlace=false)
Add items from an XML representation to the layout.
Definition: qgslayout.cpp:988
QgsLayoutView::scrollContentsBy
void scrollContentsBy(int dx, int dy) override
Definition: qgslayoutview.cpp:1129
QgsLayoutView::lockSelectedItems
void lockSelectedItems()
Locks any selected items, preventing them from being interacted with by mouse interactions.
Definition: qgslayoutview.cpp:802
QgsLayoutView::emitZoomLevelChanged
void emitZoomLevelChanged()
Emits the zoomLevelChanged() signal.
Definition: qgslayoutview.cpp:586
QgsLayoutPageCollection::pageNumberForPoint
int pageNumberForPoint(QPointF point) const
Returns the page number corresponding to a point in the layout (in layout units).
Definition: qgslayoutpagecollection.cpp:155
QgsPreviewEffect::PreviewMode
PreviewMode
Definition: qgsprevieweffect.h:37
QgsLayout::moveItemToTop
bool moveItemToTop(QgsLayoutItem *item, bool deferUpdate=false)
Raises an item up to the top of the z-order.
Definition: qgslayout.cpp:212
QgsLayoutView::zoomActual
void zoomActual()
Zooms to the actual size of the layout.
Definition: qgslayoutview.cpp:581
QgsLayout::moveItemToBottom
bool moveItemToBottom(QgsLayoutItem *item, bool deferUpdate=false)
Lowers an item down to the bottom of the z-order.
Definition: qgslayout.cpp:225
QgsLayoutView::previewModeEnabled
bool previewModeEnabled() const
Returns true if a preview effect is being used to alter the view's appearance.
Definition: qgslayoutview.cpp:173
QgsLayoutFrame
Base class for frame items, which form a layout multiframe item.
Definition: qgslayoutframe.h:32
QgsLayoutView::~QgsLayoutView
~QgsLayoutView() override
Definition: qgslayoutview.cpp:71
QgsLayoutView::setPreviewMode
void setPreviewMode(QgsPreviewEffect::PreviewMode mode)
Sets the preview mode which should be used to modify the view's appearance.
Definition: qgslayoutview.cpp:178
QgsLayoutView::zoomIn
void zoomIn()
Zooms in to the view by a preset amount.
Definition: qgslayoutview.cpp:571
QgsLayoutRuler
A custom ruler widget for use with QgsLayoutView, displaying the current zoom and position of the vis...
Definition: qgslayoutruler.h:39
QgsLayoutPageCollection::visiblePageNumbers
QList< int > visiblePageNumbers(const QRectF &region) const
Returns a list of the page numbers which are visible within the specified region (in layout coordinat...
Definition: qgslayoutpagecollection.cpp:487
MIN_VIEW_SCALE
#define MIN_VIEW_SCALE
Definition: qgslayoutview.cpp:45
QgsLayoutView::zoomOut
void zoomOut()
Zooms out of the view by a preset amount.
Definition: qgslayoutview.cpp:576
QgsLayoutView::deleteSelectedItems
void deleteSelectedItems()
Deletes all selected items.
Definition: qgslayoutview.cpp:848
qgslayoutviewtooltemporarykeypan.h
QgsLayoutItem::setLocked
void setLocked(bool locked)
Sets whether the item is locked, preventing mouse interactions with the item.
Definition: qgslayoutitem.cpp:200
QgsLayoutView::toolSet
void toolSet(QgsLayoutViewTool *tool)
Emitted when the current tool is changed.
QgsLayoutView::raiseSelectedItems
void raiseSelectedItems()
Raises the selected items up the z-order.
Definition: qgslayoutview.cpp:710
QgsLayoutPageCollection::changed
void changed()
Emitted when pages are added or removed from the collection.
qgslayoutruler.h
QgsLayoutView::moveSelectedItemsToBottom
void moveSelectedItemsToBottom()
Lowers the selected items to the bottom of the z-order.
Definition: qgslayoutview.cpp:779
QgsLayoutView::currentLayout
QgsLayout * currentLayout
Definition: qgslayoutview.h:63
QgsLayoutRuler::setLayoutView
void setLayoutView(QgsLayoutView *view)
Sets the current layout view to synchronize the ruler with.
Definition: qgslayoutruler.cpp:567
QgsLayoutView::setPaintingEnabled
void setPaintingEnabled(bool enabled)
Sets whether widget repainting should be allowed for the view.
Definition: qgslayoutview.cpp:514
QgsLayoutView::wheelEvent
void wheelEvent(QWheelEvent *event) override
Definition: qgslayoutview.cpp:1042
QgsProject::setDirty
void setDirty(bool b=true)
Flag the project as dirty (modified).
Definition: qgsproject.cpp:519
QgsLayoutViewTool::itemFocused
void itemFocused(QgsLayoutItem *item)
Emitted when an item is "focused" by the tool, i.e.
QgsLayoutView::setTool
void setTool(QgsLayoutViewTool *tool)
Sets the tool currently being used in the view.
Definition: qgslayoutview.cpp:132
QgsLayoutViewMenuProvider
Interface for a QgsLayoutView context menu.
Definition: qgslayoutview.h:600
QgsLayoutItem
Base class for graphical items within a QgsLayout.
Definition: qgslayoutitem.h:113
QgsLayoutView::dragEnterEvent
void dragEnterEvent(QDragEnterEvent *e) override
Definition: qgslayoutview.cpp:1135
QgsLayoutView::tool
QgsLayoutViewTool * tool
Definition: qgslayoutview.h:64
qgslayout.h
QgsLayoutView::mousePressEvent
void mousePressEvent(QMouseEvent *event) override
Definition: qgslayoutview.cpp:928
QgsLayoutView::lowerSelectedItems
void lowerSelectedItems()
Lowers the selected items down the z-order.
Definition: qgslayoutview.cpp:733
QgsLayoutItemGroup
A container for grouping several QgsLayoutItems.
Definition: qgslayoutitemgroup.h:29
QgsLayoutView::PasteModeInPlace
@ PasteModeInPlace
Paste items in place.
Definition: qgslayoutview.h:80
QgsLayoutView::previewMode
QgsPreviewEffect::PreviewMode previewMode() const
Returns the preview mode which may be used to modify the view's appearance.
Definition: qgslayoutview.cpp:183
QgsLayoutUndoStack::beginMacro
void beginMacro(const QString &commandText)
Starts a macro command, with the given descriptive commandText.
Definition: qgslayoutundostack.cpp:30
QgsPointXY
A class to represent a 2D point.
Definition: qgspointxy.h:44
QgsLayoutPageCollection::visiblePages
QList< QgsLayoutItemPage * > visiblePages(const QRectF &region) const
Returns a list of the pages which are visible within the specified region (in layout coordinates).
Definition: qgslayoutpagecollection.cpp:475
QgsLayoutAligner::Alignment
Alignment
Alignment options.
Definition: qgslayoutaligner.h:43
QgsLayout::groupItems
QgsLayoutItemGroup * groupItems(const QList< QgsLayoutItem * > &items)
Creates a new group from a list of layout items and adds the group to the layout.
Definition: qgslayout.cpp:738
QgsLayoutView::viewChanged
void viewChanged()
Updates associated rulers and other widgets after view extent or zoom has changed.
Definition: qgslayoutview.cpp:1171
QgsLayoutAligner::Distribution
Distribution
Distribution options.
Definition: qgslayoutaligner.h:54
QgsLayout::lowerItem
bool lowerItem(QgsLayoutItem *item, bool deferUpdate=false)
Lowers an item down the z-order.
Definition: qgslayout.cpp:199
QgsLayoutView::ClipboardCut
@ ClipboardCut
Cut items.
Definition: qgslayoutview.h:71
QgsLayoutView::copySelectedItems
void copySelectedItems(ClipboardOperation operation)
Cuts or copies the selected items, respecting the specified operation.
Definition: qgslayoutview.cpp:310
QgsLayoutView::distributeSelectedItems
void distributeSelectedItems(QgsLayoutAligner::Distribution distribution)
Distributes all selected items using the specified distribution.
Definition: qgslayoutview.cpp:292
QgsLayoutUndoStack::endCommand
void endCommand()
Saves final state of an object and pushes the active command to the undo history.
Definition: qgslayoutundostack.cpp:53
QgsLayoutView::itemFocused
void itemFocused(QgsLayoutItem *item)
Emitted when an item is "focused" in the view, i.e.
QgsLayout::pageCollection
QgsLayoutPageCollection * pageCollection()
Returns a pointer to the layout's page collection, which stores and manages page items in the layout.
Definition: qgslayout.cpp:459
QgsLayoutAligner::Resize
Resize
Resize options.
Definition: qgslayoutaligner.h:67
QgsLayoutView::willBeDeleted
void willBeDeleted()
Emitted in the destructor when the view is about to be deleted, but is still in a perfectly valid sta...
QgsLayout
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition: qgslayout.h:50
QgsLayoutView::zoomLevelChanged
void zoomLevelChanged()
Emitted whenever the zoom level of the view is changed.
QgsLayout::updateZValues
void updateZValues(bool addUndoCommands=true)
Resets the z-values of items based on their position in the internal z order list.
Definition: qgslayout.cpp:918
QgsLayout::selectedItemChanged
void selectedItemChanged(QgsLayoutItem *selected)
Emitted whenever the selected item changes.
QgsLayoutView::resizeEvent
void resizeEvent(QResizeEvent *event) override
Definition: qgslayoutview.cpp:1122
QgsLayoutView::mouseMoveEvent
void mouseMoveEvent(QMouseEvent *event) override
Definition: qgslayoutview.cpp:983
QgsLayoutViewTool
Abstract base class for all layout view tools.
Definition: qgslayoutviewtool.h:47
qgssettings.h
QgsLayoutUndoStack::beginCommand
void beginCommand(QgsLayoutUndoObjectInterface *object, const QString &commandText, int id=0)
Begins a new undo command for the specified object.
Definition: qgslayoutundostack.cpp:42
QgsLayout::ZSnapIndicator
@ ZSnapIndicator
Z-value for snapping indicator.
Definition: qgslayout.h:65
MAX_VIEW_SCALE
#define MAX_VIEW_SCALE
Definition: qgslayoutview.cpp:46
QgsLayout::guides
QgsLayoutGuideCollection & guides()
Returns a reference to the layout's guide collection, which manages page snap guides.
Definition: qgslayout.cpp:385
QgsLayoutView::setZoomLevel
void setZoomLevel(double level)
Sets the zoom level for the view, where a zoom level of 1.0 corresponds to 100%.
Definition: qgslayoutview.cpp:198
QgsLayoutView::copyItems
void copyItems(const QList< QgsLayoutItem * > &items, ClipboardOperation operation)
Cuts or copies the a list of items, respecting the specified operation.
Definition: qgslayoutview.cpp:315
qgslayoutpagecollection.h
QgsPreviewEffect::setMode
void setMode(PreviewMode mode)
Sets the mode for the preview effect, which controls how the effect modifies a widgets appearance.
Definition: qgsprevieweffect.cpp:30
QgsLayoutView::QgsLayoutView
QgsLayoutView(QWidget *parent=nullptr)
Constructor for QgsLayoutView.
Definition: qgslayoutview.cpp:48
QgsPreviewEffect
A graphics effect which can be applied to a widget to simulate various printing and color blindness m...
Definition: qgsprevieweffect.h:32
QgsUnitTypes::LayoutMillimeters
@ LayoutMillimeters
Millimeters.
Definition: qgsunittypes.h:182
qgslayoutmousehandles.h
QgsLayoutView::pushStatusMessage
void pushStatusMessage(const QString &message)
Pushes a new status bar message to the view.
Definition: qgslayoutview.cpp:1198
QgsLayoutAligner::resizeItems
static void resizeItems(QgsLayout *layout, const QList< QgsLayoutItem * > &items, Resize resize)
Resizes a set of items from a layout in place.
Definition: qgslayoutaligner.cpp:195
QgsLayout::project
QgsProject * project() const
The project associated with the layout.
Definition: qgslayout.cpp:132
QgsLayoutView::unlockAllItems
void unlockAllItems()
Unlocks all locked items in the layout.
Definition: qgslayoutview.cpp:818
QgsLayoutView::mouseReleaseEvent
void mouseReleaseEvent(QMouseEvent *event) override
Definition: qgslayoutview.cpp:967
QgsLayout::removeLayoutItem
void removeLayoutItem(QgsLayoutItem *item)
Removes an item from the layout.
Definition: qgslayout.cpp:556
QgsLayoutViewTool::activate
virtual void activate()
Called when tool is set as the currently active layout tool.
Definition: qgslayoutviewtool.cpp:120
QgsLayoutRuler::setSceneTransform
void setSceneTransform(const QTransform &transform)
Sets the current scene transform.
Definition: qgslayoutruler.cpp:561
QgsLayoutViewMouseEvent
A QgsLayoutViewMouseEvent is the result of a user interaction with the mouse on a QgsLayoutView.
Definition: qgslayoutviewmouseevent.h:36
QgsLayoutView::resizeSelectedItems
void resizeSelectedItems(QgsLayoutAligner::Resize resize)
Resizes all selected items using the specified resize mode.
Definition: qgslayoutview.cpp:301
QgsLayoutView::PasteModeCursor
@ PasteModeCursor
Paste items at cursor position.
Definition: qgslayoutview.h:78
qgslayoutmodel.h
QgsLayoutView::layoutSet
void layoutSet(QgsLayout *layout)
Emitted when a layout is set for the view.
qgslayoutreportsectionlabel.h
qgsproject.h
QgsLayout::itemsModel
QgsLayoutModel * itemsModel()
Returns the items model attached to the layout.
Definition: qgslayout.cpp:137
QgsLayoutItem::isLocked
bool isLocked() const
Returns true if the item is locked, and cannot be interacted with using the mouse.
Definition: qgslayoutitem.h:400
QgsLayout::convertFromLayoutUnits
QgsLayoutMeasurement convertFromLayoutUnits(double length, QgsUnitTypes::LayoutUnit unit) const
Converts a length measurement from the layout's native units to a specified target unit.
Definition: qgslayout.cpp:344
QgsLayoutView::mouseDoubleClickEvent
void mouseDoubleClickEvent(QMouseEvent *event) override
Definition: qgslayoutview.cpp:1026
qgslayoutviewtooltemporarykeyzoom.h
QgsLayoutView::pageChanged
void pageChanged(int page)
Emitted when the page visible in the view is changed.
QgsLayoutView::groupSelectedItems
void groupSelectedItems()
Groups all selected items.
Definition: qgslayoutview.cpp:874
QgsPreviewEffect::mode
PreviewMode mode() const
Returns the mode used for the preview effect.
Definition: qgsprevieweffect.h:60
QgsLayoutView::selectNextItemAbove
void selectNextItemAbove()
Selects the next item above the existing selection, by item z order.
Definition: qgslayoutview.cpp:700
QgsLayoutView::scaleSafe
void scaleSafe(double scale)
Scales the view in a safe way, by limiting the acceptable range of the scale applied.
Definition: qgslayoutview.cpp:188
QgsLayoutView::statusMessage
void statusMessage(const QString &message)
Emitted when the view has a message for display in a parent window's status bar.