QGIS API Documentation  3.9.0-Master (224899f119)
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  }
368  }
369  QDomNodeList multiFrameNodes = doc.elementsByTagName( QStringLiteral( "LayoutMultiFrame" ) );
370  for ( int i = 0; i < multiFrameNodes.count(); ++i )
371  {
372  QDomNode multiFrameNode = multiFrameNodes.at( i );
373  if ( multiFrameNode.isElement() )
374  {
375  multiFrameNode.toElement().removeAttribute( QStringLiteral( "uuid" ) );
376  QDomNodeList frameNodes = multiFrameNode.toElement().elementsByTagName( QStringLiteral( "childFrame" ) );
377  for ( int j = 0; j < frameNodes.count(); ++j )
378  {
379  QDomNode itemNode = frameNodes.at( j );
380  if ( itemNode.isElement() )
381  {
382  itemNode.toElement().removeAttribute( QStringLiteral( "uuid" ) );
383  }
384  }
385  }
386  }
387 
388  QMimeData *mimeData = new QMimeData;
389  mimeData->setData( QStringLiteral( "text/xml" ), doc.toByteArray() );
390  QClipboard *clipboard = QApplication::clipboard();
391  clipboard->setMimeData( mimeData );
392 }
393 
394 QList< QgsLayoutItem * > QgsLayoutView::pasteItems( QgsLayoutView::PasteMode mode )
395 {
396  if ( !currentLayout() )
397  return QList< QgsLayoutItem * >();
398 
399  QList< QgsLayoutItem * > pastedItems;
400  QDomDocument doc;
401  QClipboard *clipboard = QApplication::clipboard();
402  if ( doc.setContent( clipboard->mimeData()->data( QStringLiteral( "text/xml" ) ) ) )
403  {
404  QDomElement docElem = doc.documentElement();
405  if ( docElem.tagName() == QLatin1String( "LayoutItemClipboard" ) )
406  {
407  QPointF pt;
408  switch ( mode )
409  {
410  case PasteModeCursor:
411  case PasteModeInPlace:
412  {
413  // place items at cursor position
414  pt = mapToScene( mapFromGlobal( QCursor::pos() ) );
415  break;
416  }
417  case PasteModeCenter:
418  {
419  // place items in center of viewport
420  pt = mapToScene( viewport()->rect().center() );
421  break;
422  }
423  }
424  bool pasteInPlace = ( mode == PasteModeInPlace );
425  currentLayout()->undoStack()->beginMacro( tr( "Paste Items" ) );
426  currentLayout()->undoStack()->beginCommand( currentLayout(), tr( "Paste Items" ) );
427  pastedItems = currentLayout()->addItemsFromXml( docElem, doc, QgsReadWriteContext(), &pt, pasteInPlace );
430  }
431  }
432  return pastedItems;
433 }
434 
435 QList<QgsLayoutItem *> QgsLayoutView::pasteItems( QPointF layoutPoint )
436 {
437  if ( !currentLayout() )
438  return QList<QgsLayoutItem *>();
439 
440  QList< QgsLayoutItem * > pastedItems;
441  QDomDocument doc;
442  QClipboard *clipboard = QApplication::clipboard();
443  if ( doc.setContent( clipboard->mimeData()->data( QStringLiteral( "text/xml" ) ) ) )
444  {
445  QDomElement docElem = doc.documentElement();
446  if ( docElem.tagName() == QLatin1String( "LayoutItemClipboard" ) )
447  {
448  currentLayout()->undoStack()->beginMacro( tr( "Paste Items" ) );
449  currentLayout()->undoStack()->beginCommand( currentLayout(), tr( "Paste Items" ) );
450  pastedItems = currentLayout()->addItemsFromXml( docElem, doc, QgsReadWriteContext(), &layoutPoint, false );
453  }
454  }
455  return pastedItems;
456 }
457 
459 {
460  QDomDocument doc;
461  QClipboard *clipboard = QApplication::clipboard();
462  if ( doc.setContent( clipboard->mimeData()->data( QStringLiteral( "text/xml" ) ) ) )
463  {
464  QDomElement docElem = doc.documentElement();
465  if ( docElem.tagName() == QLatin1String( "LayoutItemClipboard" ) )
466  return true;
467  }
468  return false;
469 }
470 
471 QPointF QgsLayoutView::deltaForKeyEvent( QKeyEvent *event )
472 {
473  // increment used for cursor key item movement
474  double increment = 1.0;
475  if ( event->modifiers() & Qt::ShiftModifier )
476  {
477  //holding shift while pressing cursor keys results in a big step
478  increment = 10.0;
479  }
480  else if ( event->modifiers() & Qt::AltModifier )
481  {
482  //holding alt while pressing cursor keys results in a 1 pixel step
483  double viewScale = transform().m11();
484  if ( viewScale > 0 )
485  {
486  increment = 1 / viewScale;
487  }
488  }
489 
490  double deltaX = 0;
491  double deltaY = 0;
492  switch ( event->key() )
493  {
494  case Qt::Key_Left:
495  deltaX = -increment;
496  break;
497  case Qt::Key_Right:
498  deltaX = increment;
499  break;
500  case Qt::Key_Up:
501  deltaY = -increment;
502  break;
503  case Qt::Key_Down:
504  deltaY = increment;
505  break;
506  default:
507  break;
508  }
509 
510  return QPointF( deltaX, deltaY );
511 }
512 
514 {
515  mPaintingEnabled = enabled;
516  if ( enabled )
517  update();
518 }
519 
520 void QgsLayoutView::setSectionLabel( const QString &label )
521 {
522  if ( !currentLayout() )
523  return;
524 
525  if ( !mSectionLabel )
526  {
527  mSectionLabel = new QgsLayoutReportSectionLabel( currentLayout(), this );
528  currentLayout()->addItem( mSectionLabel );
529  mSectionLabel->setRect( 0, -200, 1000, 200 );
530  mSectionLabel->setZValue( -1 );
531  }
532  mSectionLabel->setLabel( label );
533 }
534 
536 {
537  if ( !scene() )
538  return;
539 
540  fitInView( scene()->sceneRect(), Qt::KeepAspectRatio );
541  viewChanged();
542  emit zoomLevelChanged();
543 }
544 
546 {
547  if ( !scene() )
548  return;
549 
550  //get current visible part of scene
551  QRect viewportRect( 0, 0, viewport()->width(), viewport()->height() );
552  QRectF visibleRect = mapToScene( viewportRect ).boundingRect();
553 
554  double verticalCenter = ( visibleRect.top() + visibleRect.bottom() ) / 2.0;
555  // expand out visible rect to include left/right edges of scene
556  // centered on current visible vertical center
557  // note that we can't have a 0 height rect - fitInView doesn't handle that
558  // so we just set a very small height instead.
559  const double tinyHeight = 0.01;
560  QRectF targetRect( scene()->sceneRect().left(),
561  verticalCenter - tinyHeight,
562  scene()->sceneRect().width(),
563  tinyHeight * 2 );
564 
565  fitInView( targetRect, Qt::KeepAspectRatio );
566  emit zoomLevelChanged();
567  viewChanged();
568 }
569 
571 {
572  scaleSafe( 2 );
573 }
574 
576 {
577  scaleSafe( 0.5 );
578 }
579 
581 {
582  setZoomLevel( 1.0 );
583 }
584 
586 {
587  emit zoomLevelChanged();
588 }
589 
591 {
592  if ( !currentLayout() )
593  {
594  return;
595  }
596 
597  //select all items in layout
598  QgsLayoutItem *focusedItem = nullptr;
599  const QList<QGraphicsItem *> itemList = currentLayout()->items();
600  for ( QGraphicsItem *graphicsItem : itemList )
601  {
602  QgsLayoutItem *item = dynamic_cast<QgsLayoutItem *>( graphicsItem );
603  QgsLayoutItemPage *paperItem = dynamic_cast<QgsLayoutItemPage *>( graphicsItem );
604  if ( item && !paperItem )
605  {
606  if ( !item->isLocked() )
607  {
608  item->setSelected( true );
609  if ( !focusedItem )
610  focusedItem = item;
611  }
612  else
613  {
614  //deselect all locked items
615  item->setSelected( false );
616  }
617  }
618  }
619  emit itemFocused( focusedItem );
620 }
621 
623 {
624  if ( !currentLayout() )
625  {
626  return;
627  }
628 
630 }
631 
633 {
634  if ( !currentLayout() )
635  {
636  return;
637  }
638 
639  QgsLayoutItem *focusedItem = nullptr;
640  //check all items in layout
641  const QList<QGraphicsItem *> itemList = currentLayout()->items();
642  for ( QGraphicsItem *graphicsItem : itemList )
643  {
644  QgsLayoutItem *item = dynamic_cast<QgsLayoutItem *>( graphicsItem );
645  QgsLayoutItemPage *paperItem = dynamic_cast<QgsLayoutItemPage *>( graphicsItem );
646  if ( item && !paperItem )
647  {
648  //flip selected state for items (and deselect any locked items)
649  if ( item->isSelected() || item->isLocked() )
650  {
651  item->setSelected( false );
652  }
653  else
654  {
655  item->setSelected( true );
656  if ( !focusedItem )
657  focusedItem = item;
658  }
659  }
660  }
661  if ( focusedItem )
662  emit itemFocused( focusedItem );
663 }
664 
665 
666 void selectNextByZOrder( QgsLayout *layout, bool above )
667 {
668  if ( !layout )
669  return;
670 
671  QgsLayoutItem *previousSelectedItem = nullptr;
672  const QList<QgsLayoutItem *> selectedItems = layout->selectedLayoutItems();
673  if ( !selectedItems.isEmpty() )
674  {
675  previousSelectedItem = selectedItems.at( 0 );
676  }
677 
678  if ( !previousSelectedItem )
679  {
680  return;
681  }
682 
683  //select item with target z value
684  QgsLayoutItem *selectedItem = nullptr;
685  if ( !above )
686  selectedItem = layout->itemsModel()->findItemBelow( previousSelectedItem );
687  else
688  selectedItem = layout->itemsModel()->findItemAbove( previousSelectedItem );
689 
690  if ( !selectedItem )
691  {
692  return;
693  }
694 
695  //OK, found a good target item
696  layout->setSelectedItem( selectedItem );
697 }
698 
700 {
702 }
703 
705 {
706  selectNextByZOrder( currentLayout(), false );
707 }
708 
710 {
711  if ( !currentLayout() )
712  return;
713 
714  const QList<QgsLayoutItem *> selectedItems = currentLayout()->selectedLayoutItems();
715  bool itemsRaised = false;
716  for ( QgsLayoutItem *item : selectedItems )
717  {
718  itemsRaised = itemsRaised | currentLayout()->raiseItem( item, true );
719  }
720 
721  if ( !itemsRaised )
722  {
723  //no change
724  return;
725  }
726 
727  //update all positions
729  currentLayout()->update();
730 }
731 
733 {
734  if ( !currentLayout() )
735  return;
736 
737  const QList<QgsLayoutItem *> selectedItems = currentLayout()->selectedLayoutItems();
738  bool itemsLowered = false;
739  for ( QgsLayoutItem *item : selectedItems )
740  {
741  itemsLowered = itemsLowered | currentLayout()->lowerItem( item, true );
742  }
743 
744  if ( !itemsLowered )
745  {
746  //no change
747  return;
748  }
749 
750  //update all positions
752  currentLayout()->update();
753 }
754 
756 {
757  if ( !currentLayout() )
758  return;
759 
760  const QList<QgsLayoutItem *> selectedItems = currentLayout()->selectedLayoutItems();
761  bool itemsRaised = false;
762  for ( QgsLayoutItem *item : selectedItems )
763  {
764  itemsRaised = itemsRaised | currentLayout()->moveItemToTop( item, true );
765  }
766 
767  if ( !itemsRaised )
768  {
769  //no change
770  return;
771  }
772 
773  //update all positions
775  currentLayout()->update();
776 }
777 
779 {
780  if ( !currentLayout() )
781  return;
782 
783  const QList<QgsLayoutItem *> selectedItems = currentLayout()->selectedLayoutItems();
784  bool itemsLowered = false;
785  for ( QgsLayoutItem *item : selectedItems )
786  {
787  itemsLowered = itemsLowered | currentLayout()->moveItemToBottom( item, true );
788  }
789 
790  if ( !itemsLowered )
791  {
792  //no change
793  return;
794  }
795 
796  //update all positions
798  currentLayout()->update();
799 }
800 
802 {
803  if ( !currentLayout() )
804  return;
805 
806  currentLayout()->undoStack()->beginMacro( tr( "Lock Items" ) );
807  const QList<QgsLayoutItem *> selectionList = currentLayout()->selectedLayoutItems();
808  for ( QgsLayoutItem *item : selectionList )
809  {
810  item->setLocked( true );
811  }
812 
815 }
816 
818 {
819  if ( !currentLayout() )
820  return;
821 
822  //unlock all items in layout
823  currentLayout()->undoStack()->beginMacro( tr( "Unlock Items" ) );
824 
825  //first, clear the selection
827 
828  QgsLayoutItem *focusItem = nullptr;
829 
830  const QList<QGraphicsItem *> itemList = currentLayout()->items();
831  for ( QGraphicsItem *graphicItem : itemList )
832  {
833  QgsLayoutItem *item = dynamic_cast<QgsLayoutItem *>( graphicItem );
834  if ( item && item->isLocked() )
835  {
836  focusItem = item;
837  item->setLocked( false );
838  //select unlocked items, same behavior as illustrator
839  item->setSelected( true );
840  }
841  }
843 
844  emit itemFocused( focusItem );
845 }
846 
848 {
849  if ( !currentLayout() )
850  return;
851 
852  deleteItems( currentLayout()->selectedLayoutItems() );
853 }
854 
855 void QgsLayoutView::deleteItems( const QList<QgsLayoutItem *> &items )
856 {
857  if ( !currentLayout() )
858  return;
859 
860  if ( items.empty() )
861  return;
862 
863  currentLayout()->undoStack()->beginMacro( tr( "Delete Items" ) );
864  //delete selected items
865  for ( QgsLayoutItem *item : items )
866  {
867  currentLayout()->removeLayoutItem( item );
868  }
870  currentLayout()->project()->setDirty( true );
871 }
872 
874 {
875  if ( !currentLayout() )
876  {
877  return;
878  }
879 
880  //group selected items
881  const QList<QgsLayoutItem *> selectionList = currentLayout()->selectedLayoutItems();
882  QgsLayoutItemGroup *itemGroup = currentLayout()->groupItems( selectionList );
883 
884  if ( !itemGroup )
885  {
886  //group could not be created
887  return;
888  }
889 
890  for ( QgsLayoutItem *item : selectionList )
891  {
892  item->setSelected( false );
893  }
894 
895  currentLayout()->setSelectedItem( itemGroup );
896 }
897 
899 {
900  if ( !currentLayout() )
901  {
902  return;
903  }
904 
905  QList< QgsLayoutItem * > ungroupedItems;
906  //hunt through selection for any groups, and ungroup them
907  const QList<QgsLayoutItem *> selectionList = currentLayout()->selectedLayoutItems();
908  for ( QgsLayoutItem *item : selectionList )
909  {
910  if ( item->type() == QgsLayoutItemRegistry::LayoutGroup )
911  {
912  QgsLayoutItemGroup *itemGroup = static_cast<QgsLayoutItemGroup *>( item );
913  ungroupedItems.append( currentLayout()->ungroupItems( itemGroup ) );
914  }
915  }
916 
917  if ( !ungroupedItems.empty() )
918  {
919  for ( QgsLayoutItem *item : qgis::as_const( ungroupedItems ) )
920  {
921  item->setSelected( true );
922  }
923  emit itemFocused( ungroupedItems.at( 0 ) );
924  }
925 }
926 
927 void QgsLayoutView::mousePressEvent( QMouseEvent *event )
928 {
929  if ( !currentLayout() )
930  return;
931 
932  if ( mSnapMarker )
933  mSnapMarker->setVisible( false );
934 
935  if ( mTool )
936  {
937  std::unique_ptr<QgsLayoutViewMouseEvent> me( new QgsLayoutViewMouseEvent( this, event, mTool->flags() & QgsLayoutViewTool::FlagSnaps ) );
938  mTool->layoutPressEvent( me.get() );
939  event->setAccepted( me->isAccepted() );
940  }
941 
942  if ( !mTool || !event->isAccepted() )
943  {
944  if ( event->button() == Qt::MidButton )
945  {
946  // Pan layout with middle mouse button
947  setTool( mMidMouseButtonPanTool );
948  event->accept();
949  }
950  else if ( event->button() == Qt::RightButton && mMenuProvider )
951  {
952  QMenu *menu = mMenuProvider->createContextMenu( this, currentLayout(), mapToScene( event->pos() ) );
953  if ( menu )
954  {
955  menu->exec( event->globalPos() );
956  delete menu;
957  }
958  }
959  else
960  {
961  QGraphicsView::mousePressEvent( event );
962  }
963  }
964 }
965 
966 void QgsLayoutView::mouseReleaseEvent( QMouseEvent *event )
967 {
968  if ( !currentLayout() )
969  return;
970 
971  if ( mTool )
972  {
973  std::unique_ptr<QgsLayoutViewMouseEvent> me( new QgsLayoutViewMouseEvent( this, event, mTool->flags() & QgsLayoutViewTool::FlagSnaps ) );
974  mTool->layoutReleaseEvent( me.get() );
975  event->setAccepted( me->isAccepted() );
976  }
977 
978  if ( !mTool || !event->isAccepted() )
979  QGraphicsView::mouseReleaseEvent( event );
980 }
981 
982 void QgsLayoutView::mouseMoveEvent( QMouseEvent *event )
983 {
984  if ( !currentLayout() )
985  return;
986 
987  mMouseCurrentXY = event->pos();
988 
989  QPointF cursorPos = mapToScene( mMouseCurrentXY );
990  if ( mTool )
991  {
992  std::unique_ptr<QgsLayoutViewMouseEvent> me( new QgsLayoutViewMouseEvent( this, event, false ) );
993  if ( mTool->flags() & QgsLayoutViewTool::FlagSnaps )
994  {
995  me->snapPoint( mHorizontalSnapLine, mVerticalSnapLine, mTool->ignoredSnapItems() );
996  }
997  if ( mTool->flags() & QgsLayoutViewTool::FlagSnaps )
998  {
999  //draw snapping point indicator
1000  if ( me->isSnapped() )
1001  {
1002  cursorPos = me->snappedPoint();
1003  if ( mSnapMarker )
1004  {
1005  mSnapMarker->setPos( me->snappedPoint() );
1006  mSnapMarker->setVisible( true );
1007  }
1008  }
1009  else if ( mSnapMarker )
1010  {
1011  mSnapMarker->setVisible( false );
1012  }
1013  }
1014  mTool->layoutMoveEvent( me.get() );
1015  event->setAccepted( me->isAccepted() );
1016  }
1017 
1018  //update cursor position in status bar
1019  emit cursorPosChanged( cursorPos );
1020 
1021  if ( !mTool || !event->isAccepted() )
1022  QGraphicsView::mouseMoveEvent( event );
1023 }
1024 
1025 void QgsLayoutView::mouseDoubleClickEvent( QMouseEvent *event )
1026 {
1027  if ( !currentLayout() )
1028  return;
1029 
1030  if ( mTool )
1031  {
1032  std::unique_ptr<QgsLayoutViewMouseEvent> me( new QgsLayoutViewMouseEvent( this, event, mTool->flags() & QgsLayoutViewTool::FlagSnaps ) );
1033  mTool->layoutDoubleClickEvent( me.get() );
1034  event->setAccepted( me->isAccepted() );
1035  }
1036 
1037  if ( !mTool || !event->isAccepted() )
1038  QGraphicsView::mouseDoubleClickEvent( event );
1039 }
1040 
1041 void QgsLayoutView::wheelEvent( QWheelEvent *event )
1042 {
1043  if ( !currentLayout() )
1044  return;
1045 
1046  if ( mTool )
1047  {
1048  mTool->wheelEvent( event );
1049  }
1050 
1051  if ( !mTool || !event->isAccepted() )
1052  {
1053  event->accept();
1054  wheelZoom( event );
1055  }
1056 }
1057 
1058 void QgsLayoutView::keyPressEvent( QKeyEvent *event )
1059 {
1060  if ( !currentLayout() )
1061  return;
1062 
1063  if ( mTool )
1064  {
1065  mTool->keyPressEvent( event );
1066  }
1067 
1068  if ( mTool && event->isAccepted() )
1069  return;
1070 
1071  if ( event->key() == Qt::Key_Space && ! event->isAutoRepeat() )
1072  {
1073  if ( !( event->modifiers() & Qt::ControlModifier ) )
1074  {
1075  // Pan layout with space bar
1076  setTool( mSpacePanTool );
1077  }
1078  else
1079  {
1080  //ctrl+space pressed, so switch to temporary keyboard based zoom tool
1081  setTool( mSpaceZoomTool );
1082  }
1083  event->accept();
1084  }
1085  else if ( event->key() == Qt::Key_Left
1086  || event->key() == Qt::Key_Right
1087  || event->key() == Qt::Key_Up
1088  || event->key() == Qt::Key_Down )
1089  {
1090  QgsLayout *l = currentLayout();
1091  const QList<QgsLayoutItem *> layoutItemList = l->selectedLayoutItems();
1092 
1093  QPointF delta = deltaForKeyEvent( event );
1094 
1095  l->undoStack()->beginMacro( tr( "Move Item" ) );
1096  for ( QgsLayoutItem *item : layoutItemList )
1097  {
1098  l->undoStack()->beginCommand( item, tr( "Move Item" ), QgsLayoutItem::UndoIncrementalMove );
1099  item->attemptMoveBy( delta.x(), delta.y() );
1100  l->undoStack()->endCommand();
1101  }
1102  l->undoStack()->endMacro();
1103  event->accept();
1104  }
1105 }
1106 
1107 void QgsLayoutView::keyReleaseEvent( QKeyEvent *event )
1108 {
1109  if ( !currentLayout() )
1110  return;
1111 
1112  if ( mTool )
1113  {
1114  mTool->keyReleaseEvent( event );
1115  }
1116 
1117  if ( !mTool || !event->isAccepted() )
1118  QGraphicsView::keyReleaseEvent( event );
1119 }
1120 
1121 void QgsLayoutView::resizeEvent( QResizeEvent *event )
1122 {
1123  QGraphicsView::resizeEvent( event );
1124  emit zoomLevelChanged();
1125  viewChanged();
1126 }
1127 
1128 void QgsLayoutView::scrollContentsBy( int dx, int dy )
1129 {
1130  QGraphicsView::scrollContentsBy( dx, dy );
1131  viewChanged();
1132 }
1133 
1134 void QgsLayoutView::dragEnterEvent( QDragEnterEvent *e )
1135 {
1136  // By default graphics view delegates the drag events to graphics items.
1137  // But we do not want that and by ignoring the drag enter we let the
1138  // parent (e.g. QgsLayoutDesignerDialog) to handle drops of files.
1139  e->ignore();
1140 }
1141 
1142 void QgsLayoutView::paintEvent( QPaintEvent *event )
1143 {
1144  if ( mPaintingEnabled )
1145  {
1146  QGraphicsView::paintEvent( event );
1147  event->accept();
1148  }
1149  else
1150  {
1151  event->ignore();
1152  }
1153 }
1154 
1155 void QgsLayoutView::invalidateCachedRenders()
1156 {
1157  if ( !currentLayout() )
1158  return;
1159 
1160  //redraw cached map items
1161  QList< QgsLayoutItem *> items;
1162  currentLayout()->layoutItems( items );
1163 
1164  for ( QgsLayoutItem *item : qgis::as_const( items ) )
1165  {
1166  item->invalidateCache();
1167  }
1168 }
1169 
1171 {
1172  if ( mHorizontalRuler )
1173  {
1174  mHorizontalRuler->setSceneTransform( viewportTransform() );
1175  }
1176  if ( mVerticalRuler )
1177  {
1178  mVerticalRuler->setSceneTransform( viewportTransform() );
1179  }
1180 
1181  // determine page at center of view
1182  QRect viewportRect( 0, 0, viewport()->width(), viewport()->height() );
1183  QRectF visibleRect = mapToScene( viewportRect ).boundingRect();
1184  QPointF centerVisible = visibleRect.center();
1185 
1186  if ( currentLayout() && currentLayout()->pageCollection() )
1187  {
1188  int newPage = currentLayout()->pageCollection()->pageNumberForPoint( centerVisible );
1189  if ( newPage != mCurrentPage )
1190  {
1191  mCurrentPage = newPage;
1192  emit pageChanged( mCurrentPage );
1193  }
1194  }
1195 }
1196 
1197 void QgsLayoutView::pushStatusMessage( const QString &message )
1198 {
1199  emit statusMessage( message );
1200 }
1201 
1202 void QgsLayoutView::wheelZoom( QWheelEvent *event )
1203 {
1204  //get mouse wheel zoom behavior settings
1205  QgsSettings settings;
1206  double zoomFactor = settings.value( QStringLiteral( "qgis/zoom_factor" ), 2 ).toDouble();
1207 
1208  // "Normal" mouse have an angle delta of 120, precision mouses provide data faster, in smaller steps
1209  zoomFactor = 1.0 + ( zoomFactor - 1.0 ) / 120.0 * std::fabs( event->angleDelta().y() );
1210 
1211  if ( event->modifiers() & Qt::ControlModifier )
1212  {
1213  //holding ctrl while wheel zooming results in a finer zoom
1214  zoomFactor = 1.0 + ( zoomFactor - 1.0 ) / 20.0;
1215  }
1216 
1217  //calculate zoom scale factor
1218  bool zoomIn = event->angleDelta().y() > 0;
1219  double scaleFactor = ( zoomIn ? 1 / zoomFactor : zoomFactor );
1220 
1221  //get current visible part of scene
1222  QRect viewportRect( 0, 0, viewport()->width(), viewport()->height() );
1223  QgsRectangle visibleRect = QgsRectangle( mapToScene( viewportRect ).boundingRect() );
1224 
1225  //transform the mouse pos to scene coordinates
1226  QPointF scenePoint = mapToScene( event->pos() );
1227 
1228  //adjust view center
1229  QgsPointXY oldCenter( visibleRect.center() );
1230  QgsPointXY newCenter( scenePoint.x() + ( ( oldCenter.x() - scenePoint.x() ) * scaleFactor ),
1231  scenePoint.y() + ( ( oldCenter.y() - scenePoint.y() ) * scaleFactor ) );
1232  centerOn( newCenter.x(), newCenter.y() );
1233 
1234  //zoom layout
1235  if ( zoomIn )
1236  {
1237  scaleSafe( zoomFactor );
1238  }
1239  else
1240  {
1241  scaleSafe( 1 / zoomFactor );
1242  }
1243 }
1244 
1245 QGraphicsLineItem *QgsLayoutView::createSnapLine() const
1246 {
1247  std::unique_ptr< QGraphicsLineItem> item( new QGraphicsLineItem( nullptr ) );
1248  QPen pen = QPen( QColor( Qt::blue ) );
1249  pen.setStyle( Qt::DotLine );
1250  pen.setWidthF( 0.0 );
1251  item->setPen( pen );
1252  item->setZValue( QgsLayout::ZSmartGuide );
1253  return item.release();
1254 }
1255 
1256 //
1257 // QgsLayoutViewSnapMarker
1258 //
1259 
1261 QgsLayoutViewSnapMarker::QgsLayoutViewSnapMarker()
1262  : QGraphicsRectItem( QRectF( 0, 0, 0, 0 ) )
1263 {
1264  QFont f;
1265  QFontMetrics fm( f );
1266  mSize = fm.width( QStringLiteral( "X" ) );
1267  setPen( QPen( Qt::transparent, mSize ) );
1268 
1269  setFlags( flags() | QGraphicsItem::ItemIgnoresTransformations );
1270  setZValue( QgsLayout::ZSnapIndicator );
1271 }
1272 
1273 void QgsLayoutViewSnapMarker::paint( QPainter *p, const QStyleOptionGraphicsItem *, QWidget * )
1274 {
1275  QPen pen( QColor( 255, 0, 0 ) );
1276  pen.setWidth( 0 );
1277  p->setPen( pen );
1278  p->setBrush( Qt::NoBrush );
1279 
1280  double halfSize = mSize / 2.0;
1281  p->drawLine( QLineF( -halfSize, -halfSize, halfSize, halfSize ) );
1282  p->drawLine( QLineF( -halfSize, halfSize, halfSize, -halfSize ) );
1283 }
1284 
Paste items in place.
Definition: qgslayoutview.h:80
void setDirty(bool b=true)
Flag the project as dirty (modified).
Definition: qgsproject.cpp:471
void pushStatusMessage(const QString &message)
Pushes a new status bar message to the view.
A custom ruler widget for use with QgsLayoutView, displaying the current zoom and position of the vis...
The class is used as a container of context for various read/write operations on other objects...
void selectAll()
Selects all items in the view.
void selectNextItemBelow()
Selects the next item below the existing selection, by item z order.
A rectangle specified with double values.
Definition: qgsrectangle.h:41
void setSelectedItem(QgsLayoutItem *item)
Clears any selected items and sets item as the current selection.
Definition: qgslayout.cpp:158
bool raiseItem(QgsLayoutItem *item, bool deferUpdate=false)
Raises an item up the z-order.
Definition: qgslayout.cpp:185
void keyPressEvent(QKeyEvent *event) override
QgsLayoutGuideCollection & guides()
Returns a reference to the layout&#39;s guide collection, which manages page snap guides.
Definition: qgslayout.cpp:384
QList< QgsLayoutItem *> pasteItems(PasteMode mode)
Pastes items from clipboard, using the specified mode.
void zoomIn()
Zooms in to the view by a preset amount.
QgsLayout * currentLayout()
Returns the current layout associated with the view.
Base class for graphical items within a QgsLayout.
QgsPreviewEffect::PreviewMode previewMode() const
Returns the preview mode which may be used to modify the view&#39;s appearance.
void toolSet(QgsLayoutViewTool *tool)
Emitted when the current tool is changed.
void moveSelectedItemsToTop()
Raises the selected items to the top of the z-order.
void distributeSelectedItems(QgsLayoutAligner::Distribution distribution)
Distributes all selected items using the specified distribution.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:58
int pageNumberForPoint(QPointF point) const
Returns the page number corresponding to a point in the layout (in layout units). ...
QgsLayoutUndoStack * undoStack()
Returns a pointer to the layout&#39;s undo stack, which manages undo/redo states for the layout and it&#39;s ...
Definition: qgslayout.cpp:685
void layoutSet(QgsLayout *layout)
Emitted when a layout is set for the view.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Layout view tool for temporarily panning a layout while a mouse button is depressed.
virtual void activate()
Called when tool is set as the currently active layout tool.
void selectNextByZOrder(QgsLayout *layout, bool above)
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:737
Paste items in center of view.
Definition: qgslayoutview.h:79
A class to represent a 2D point.
Definition: qgspointxy.h:43
PasteMode
Paste modes.
Definition: qgslayoutview.h:76
void setTool(QgsLayoutViewTool *tool)
Sets the tool currently being used in the view.
void resizeSelectedItems(QgsLayoutAligner::Resize resize)
Resizes all selected items using the specified resize mode.
#define MIN_VIEW_SCALE
A container for grouping several QgsLayoutItems.
Paste items at cursor position.
Definition: qgslayoutview.h:78
void setMenuProvider(QgsLayoutViewMenuProvider *provider)
Sets a provider for context menus.
void zoomActual()
Zooms to the actual size of the layout.
void scrollContentsBy(int dx, int dy) override
void zoomFull()
Zooms the view to the full extent of the layout.
Z-value for snapping indicator.
Definition: qgslayout.h:65
void mouseMoveEvent(QMouseEvent *event) override
void alignSelectedItems(QgsLayoutAligner::Alignment alignment)
Aligns all selected items using the specified alignment.
virtual void setSelected(bool selected)
Sets whether the item should be selected.
void mousePressEvent(QMouseEvent *event) override
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:982
Layout view tool for temporarily zooming a layout while a key is depressed.
void changed()
Emitted when pages are added or removed from the collection.
QPointF deltaForKeyEvent(QKeyEvent *event)
Returns the delta (in layout coordinates) by which to move items for the given key event...
void pageChanged(int page)
Emitted when the page visible in the view is changed.
void paintEvent(QPaintEvent *event) override
QList< int > visiblePageNumbers(const QRectF &region) const
Returns a list of the page numbers which are visible within the specified region (in layout coordinat...
static void alignItems(QgsLayout *layout, const QList< QgsLayoutItem * > &items, Alignment alignment)
Aligns a set of items from a layout in place.
void itemFocused(QgsLayoutItem *item)
Emitted when an item is "focused" by the tool, i.e.
ClipboardOperation
Clipboard operations.
Definition: qgslayoutview.h:69
void setCurrentLayout(QgsLayout *layout)
Sets the current layout to edit in the view.
A graphics effect which can be applied to a widget to simulate various printing and color blindness m...
bool previewModeEnabled() const
Returns true if a preview effect is being used to alter the view&#39;s appearance.
void setHorizontalRuler(QgsLayoutRuler *ruler)
Sets a horizontal ruler to synchronize with the view state.
void cursorPosChanged(QPointF layoutPoint)
Emitted when the mouse cursor coordinates change within the view.
void layoutItems(QList< T *> &itemList) const
Returns a list of layout items of a specific type.
Definition: qgslayout.h:121
void setPaintingEnabled(bool enabled)
Sets whether widget repainting should be allowed for the view.
void deselectAll()
Clears any selected items in the layout.
Definition: qgslayout.cpp:168
Z-value for smart (item bounds based) guides.
Definition: qgslayout.h:62
void updateZValues(bool addUndoCommands=true)
Resets the z-values of items based on their position in the internal z order list.
Definition: qgslayout.cpp:925
void statusMessage(const QString &message)
Emitted when the view has a message for display in a parent window&#39;s status bar.
void zoomWidth()
Zooms the view to the full width of the layout.
QList< QgsLayoutItemPage *> visiblePages(const QRectF &region) const
Returns a list of the pages which are visible within the specified region (in layout coordinates)...
void endCommand()
Saves final state of an object and pushes the active command to the undo history. ...
QgsLayoutViewMenuProvider * menuProvider() const
Returns the provider for context menus.
void setLocked(bool locked)
Sets whether the item is locked, preventing mouse interactions with the item.
Distribution
Distribution options.
void mouseReleaseEvent(QMouseEvent *event) override
void wheelEvent(QWheelEvent *event) override
void raiseSelectedItems()
Raises the selected items up the z-order.
QgsLayoutPageCollection * pageCollection()
Returns a pointer to the layout&#39;s page collection, which stores and manages page items in the layout...
Definition: qgslayout.cpp:458
QList< QgsLayoutItem * > selectedLayoutItems(bool includeLockedItems=true)
Returns list of selected layout items.
Definition: qgslayout.cpp:141
void selectedItemChanged(QgsLayoutItem *selected)
Emitted whenever the selected item changes.
static void distributeItems(QgsLayout *layout, const QList< QgsLayoutItem * > &items, Distribution distribution)
Distributes a set of items from a layout in place.
~QgsLayoutView() override
QgsLayoutViewTool * tool()
Returns the currently active tool for the view.
void setSceneTransform(const QTransform &transform)
Sets the current scene transform.
QList< QgsLayoutItemPage *> visiblePages() const
Returns a list of page items which are currently visible in the view.
void copyItems(const QList< QgsLayoutItem * > &items, ClipboardOperation operation)
Cuts or copies the a list of items, respecting the specified operation.
void resizeEvent(QResizeEvent *event) override
void lowerSelectedItems()
Lowers the selected items down the z-order.
QgsLayoutView(QWidget *parent=nullptr)
Constructor for QgsLayoutView.
void copySelectedItems(ClipboardOperation operation)
Cuts or copies the selected items, respecting the specified operation.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition: qgslayout.h:49
void setMode(PreviewMode mode)
Sets the mode for the preview effect, which controls how the effect modifies a widgets appearance...
void beginMacro(const QString &commandText)
Starts a macro command, with the given descriptive commandText.
void lockSelectedItems()
Locks any selected items, preventing them from being interacted with by mouse interactions.
void setLayoutView(QgsLayoutView *view)
Sets the current layout view to synchronize the ruler with.
A QgsLayoutViewMouseEvent is the result of a user interaction with the mouse on a QgsLayoutView...
void dragEnterEvent(QDragEnterEvent *e) override
void zoomOut()
Zooms out of the view by a preset amount.
PreviewMode mode() const
Returns the mode used for the preview effect.
bool lowerItem(QgsLayoutItem *item, bool deferUpdate=false)
Lowers an item down the z-order.
Definition: qgslayout.cpp:198
void invertSelection()
Inverts the current selection, selecting deselected items and deselecting and selected items...
void beginCommand(QgsLayoutUndoObjectInterface *object, const QString &commandText, int id=0)
Begins a new undo command for the specified object.
void unlockAllItems()
Unlocks all locked items in the layout.
QList< int > visiblePageNumbers() const
Returns a list of page numbers for pages which are currently visible in the view. ...
QgsLayoutModel * itemsModel()
Returns the items model attached to the layout.
Definition: qgslayout.cpp:136
void unsetTool(QgsLayoutViewTool *tool)
Unsets the current view tool, if it matches the specified tool.
bool moveItemToBottom(QgsLayoutItem *item, bool deferUpdate=false)
Lowers an item down to the bottom of the z-order.
Definition: qgslayout.cpp:224
void groupSelectedItems()
Groups all selected items.
double length() const
Returns the length of the measurement.
#define MAX_VIEW_SCALE
void moveSelectedItemsToBottom()
Lowers the selected items to the bottom of the z-order.
void removeLayoutItem(QgsLayoutItem *item)
Removes an item from the layout.
Definition: qgslayout.cpp:555
void scaleSafe(double scale)
Scales the view in a safe way, by limiting the acceptable range of the scale applied.
void itemFocused(QgsLayoutItem *item)
Emitted when an item is "focused" in the view, i.e.
void keyReleaseEvent(QKeyEvent *event) override
void zoomLevelChanged()
Emitted whenever the zoom level of the view is changed.
void mouseDoubleClickEvent(QMouseEvent *event) override
void deleteItems(const QList< QgsLayoutItem * > &items)
Delete the specified items.
void update()
Updates the position (and visibility) of all guide line items.
void setVerticalRuler(QgsLayoutRuler *ruler)
Sets a vertical ruler to synchronize with the view state.
QgsLayoutMeasurement convertFromLayoutUnits(double length, QgsUnitTypes::LayoutUnit unit) const
Converts a length measurement from the layout&#39;s native units to a specified target unit...
Definition: qgslayout.cpp:343
Alignment
Alignment options.
QgsProject * project() const
The project associated with the layout.
Definition: qgslayout.cpp:131
void viewChanged()
Updates associated rulers and other widgets after view extent or zoom has changed.
void selectNextItemAbove()
Selects the next item above the existing selection, by item z order.
Layout item incremental movement, e.g. as a result of a keypress.
bool isLocked() const
Returns true if the item is locked, and cannot be interacted with using the mouse.
Interface for a QgsLayoutView context menu.
void setSectionLabel(const QString &label)
Sets a section label, to display above the first page shown in the view.
Abstract base class for all layout view tools.
void setZoomLevel(double level)
Sets the zoom level for the view, where a zoom level of 1.0 corresponds to 100%.
QgsPointXY center() const
Returns the center point of the rectangle.
Definition: qgsrectangle.h:230
Resize
Resize options.
void endMacro()
Ends a macro command.
void ungroupSelectedItems()
Ungroups all selected items.
bool moveItemToTop(QgsLayoutItem *item, bool deferUpdate=false)
Raises an item up to the top of the z-order.
Definition: qgslayout.cpp:211
static void resizeItems(QgsLayout *layout, const QList< QgsLayoutItem * > &items, Resize resize)
Resizes a set of items from a layout in place.
void deleteSelectedItems()
Deletes all selected items.
Base class for frame items, which form a layout multiframe item.
bool hasItemsInClipboard() const
Returns true if the current clipboard contains layout items.
void setPreviewMode(QgsPreviewEffect::PreviewMode mode)
Sets the preview mode which should be used to modify the view&#39;s appearance.
Tool utilizes snapped coordinates.
void willBeDeleted()
Emitted in the destructor when the view is about to be deleted, but is still in a perfectly valid sta...
Item representing the paper in a layout.
void setPreviewModeEnabled(bool enabled)
Sets whether a preview effect should be used to alter the view&#39;s appearance.
Layout view tool for temporarily panning a layout while a key is depressed.
void emitZoomLevelChanged()
Emits the zoomLevelChanged() signal.
void deselectAll()
Deselects all items in the view.