QGIS API Documentation  3.20.0-Odense (decaadbb31)
qgslayoutpagepropertieswidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayoutpagepropertieswidget.cpp
3  ---------------------------------
4  Date : July 2017
5  Copyright : (C) 2017 Nyall Dawson
6  Email : nyall dot dawson at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 #include "qgsapplication.h"
18 #include "qgspagesizeregistry.h"
19 #include "qgslayoutitempage.h"
20 #include "qgslayout.h"
22 #include "qgslayoutundostack.h"
23 #include "qgsvectorlayer.h"
24 #include "qgsfillsymbol.h"
25 
27  : QgsLayoutItemBaseWidget( parent, layoutItem )
28  , mPage( static_cast< QgsLayoutItemPage *>( layoutItem ) )
29 {
30  setupUi( this );
31 
32  mPageOrientationComboBox->addItem( tr( "Portrait" ), QgsLayoutItemPage::Portrait );
33  mPageOrientationComboBox->addItem( tr( "Landscape" ), QgsLayoutItemPage::Landscape );
34 
35  const auto constEntries = QgsApplication::pageSizeRegistry()->entries();
36  for ( const QgsPageSize &size : constEntries )
37  {
38  mPageSizeComboBox->addItem( size.displayName, size.name );
39  }
40  mPageSizeComboBox->addItem( tr( "Custom" ) );
41 
42  mWidthSpin->setValue( mPage->pageSize().width() );
43  mHeightSpin->setValue( mPage->pageSize().height() );
44  mSizeUnitsComboBox->setUnit( mPage->pageSize().units() );
45  mExcludePageCheckBox->setChecked( mPage->excludeFromExports() );
46 
47  mPageOrientationComboBox->setCurrentIndex( mPageOrientationComboBox->findData( mPage->orientation() ) );
48 
49  mSizeUnitsComboBox->linkToWidget( mWidthSpin );
50  mSizeUnitsComboBox->linkToWidget( mHeightSpin );
51  mSizeUnitsComboBox->setConverter( &mPage->layout()->renderContext().measurementConverter() );
52 
53  mLockAspectRatio->setWidthSpinBox( mWidthSpin );
54  mLockAspectRatio->setHeightSpinBox( mHeightSpin );
55 
56  mSymbolButton->setSymbolType( Qgis::SymbolType::Fill );
57  mSymbolButton->setSymbol( mPage->pageStyleSymbol()->clone() );
58 
59  connect( mPageSizeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsLayoutPagePropertiesWidget::pageSizeChanged );
60  connect( mPageOrientationComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsLayoutPagePropertiesWidget::orientationChanged );
61 
62  connect( mWidthSpin, static_cast< void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPagePropertiesWidget::updatePageSize );
63  connect( mHeightSpin, static_cast< void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPagePropertiesWidget::updatePageSize );
64  connect( mWidthSpin, static_cast< void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPagePropertiesWidget::setToCustomSize );
65  connect( mHeightSpin, static_cast< void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPagePropertiesWidget::setToCustomSize );
66  connect( mExcludePageCheckBox, &QCheckBox::toggled, this, &QgsLayoutPagePropertiesWidget::excludeExportsToggled );
67 
68  connect( mSymbolButton, &QgsSymbolButton::changed, this, &QgsLayoutPagePropertiesWidget::symbolChanged );
74 
75  connect( mPaperSizeDDBtn, &QgsPropertyOverrideButton::changed, this, &QgsLayoutPagePropertiesWidget::refreshLayout );
76  connect( mWidthDDBtn, &QgsPropertyOverrideButton::changed, this, &QgsLayoutPagePropertiesWidget::refreshLayout );
77  connect( mHeightDDBtn, &QgsPropertyOverrideButton::changed, this, &QgsLayoutPagePropertiesWidget::refreshLayout );
78  connect( mOrientationDDBtn, &QgsPropertyOverrideButton::changed, this, &QgsLayoutPagePropertiesWidget::refreshLayout );
79 
80  mExcludePageDDBtn->registerEnabledWidget( mExcludePageCheckBox, false );
81 
82  mSymbolButton->registerExpressionContextGenerator( mPage );
83  mSymbolButton->setLayer( coverageLayer() );
84  if ( mPage->layout() )
85  {
87  }
88 
89  showCurrentPageSize();
90 }
91 
92 void QgsLayoutPagePropertiesWidget::pageSizeChanged( int )
93 {
94  mBlockPageUpdate = true;
95  if ( mPageSizeComboBox->currentData().toString().isEmpty() )
96  {
97  //custom size
98  mLockAspectRatio->setEnabled( true );
99  mSizeUnitsComboBox->setEnabled( true );
100  mPageOrientationComboBox->setEnabled( false );
101  }
102  else
103  {
104  mLockAspectRatio->setEnabled( false );
105  mLockAspectRatio->setLocked( false );
106  mSizeUnitsComboBox->setEnabled( false );
107  mPageOrientationComboBox->setEnabled( true );
108  QgsPageSize size = QgsApplication::pageSizeRegistry()->find( mPageSizeComboBox->currentData().toString() ).value( 0 );
109  QgsLayoutSize convertedSize = mConverter.convert( size.size, mSizeUnitsComboBox->unit() );
110  mSettingPresetSize = true;
111  switch ( mPageOrientationComboBox->currentData().toInt() )
112  {
114  mWidthSpin->setValue( convertedSize.height() );
115  mHeightSpin->setValue( convertedSize.width() );
116  break;
117 
119  mWidthSpin->setValue( convertedSize.width() );
120  mHeightSpin->setValue( convertedSize.height() );
121  break;
122  }
123  mSettingPresetSize = false;
124  }
125  mBlockPageUpdate = false;
126  updatePageSize();
127 }
128 
129 void QgsLayoutPagePropertiesWidget::orientationChanged( int )
130 {
131  if ( mPageSizeComboBox->currentData().toString().isEmpty() )
132  return;
133 
134  double width = mWidthSpin->value();
135  double height = mHeightSpin->value();
136  switch ( mPageOrientationComboBox->currentData().toInt() )
137  {
139  if ( width < height )
140  {
141  whileBlocking( mWidthSpin )->setValue( height );
142  whileBlocking( mHeightSpin )->setValue( width );
143  }
144  break;
145 
147  if ( width > height )
148  {
149  whileBlocking( mWidthSpin )->setValue( height );
150  whileBlocking( mHeightSpin )->setValue( width );
151  }
152  break;
153  }
154 
155  updatePageSize();
156 }
157 
158 void QgsLayoutPagePropertiesWidget::updatePageSize()
159 {
160  if ( mBlockPageUpdate )
161  return;
162 
163  mPage->layout()->undoStack()->beginMacro( tr( "Change Page Size" ) );
165  mPage->layout()->undoStack()->beginCommand( mPage, tr( "Change Page Size" ), 1 + mPage->layout()->pageCollection()->pageNumber( mPage ) );
166  mPage->setPageSize( QgsLayoutSize( mWidthSpin->value(), mHeightSpin->value(), mSizeUnitsComboBox->unit() ) );
167  mPage->layout()->undoStack()->endCommand();
168  mPage->layout()->pageCollection()->reflow();
169  mPage->layout()->pageCollection()->endPageSizeChange();
170  mPage->layout()->undoStack()->endMacro();
171 
172  refreshLayout();
173  emit pageOrientationChanged();
174 }
175 
176 void QgsLayoutPagePropertiesWidget::setToCustomSize()
177 {
178  if ( mSettingPresetSize )
179  return;
180  whileBlocking( mPageSizeComboBox )->setCurrentIndex( mPageSizeComboBox->count() - 1 );
181  mPageOrientationComboBox->setEnabled( false );
182 }
183 
184 void QgsLayoutPagePropertiesWidget::symbolChanged()
185 {
186  mPage->layout()->undoStack()->beginCommand( mPage->layout()->pageCollection(), tr( "Change Page Background" ), QgsLayoutItemPage::UndoPageSymbol );
187  mPage->setPageStyleSymbol( static_cast< QgsFillSymbol * >( mSymbolButton->symbol() )->clone() );
188  mPage->layout()->undoStack()->endCommand();
189 }
190 
191 void QgsLayoutPagePropertiesWidget::excludeExportsToggled( bool checked )
192 {
193  mPage->beginCommand( !checked ? tr( "Include Page in Exports" ) : tr( "Exclude Page from Exports" ) );
194  mPage->setExcludeFromExports( checked );
195  mPage->endCommand();
196 }
197 
198 void QgsLayoutPagePropertiesWidget::refreshLayout()
199 {
200  mPage->layout()->refresh();
201 }
202 
203 void QgsLayoutPagePropertiesWidget::showCurrentPageSize()
204 {
205  QgsLayoutSize paperSize = mPage->pageSize();
206  QString pageSize = QgsApplication::pageSizeRegistry()->find( paperSize );
207  if ( !pageSize.isEmpty() )
208  {
209  whileBlocking( mPageSizeComboBox )->setCurrentIndex( mPageSizeComboBox->findData( pageSize ) );
210  mLockAspectRatio->setEnabled( false );
211  mLockAspectRatio->setLocked( false );
212  mSizeUnitsComboBox->setEnabled( false );
213  mPageOrientationComboBox->setEnabled( true );
214  }
215  else
216  {
217  // custom
218  whileBlocking( mPageSizeComboBox )->setCurrentIndex( mPageSizeComboBox->count() - 1 );
219  mLockAspectRatio->setEnabled( true );
220  mSizeUnitsComboBox->setEnabled( true );
221  mPageOrientationComboBox->setEnabled( false );
222  }
223 }
@ Fill
Fill symbol.
static QgsPageSizeRegistry * pageSizeRegistry()
Returns the application's page size registry, used for managing layout page sizes.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
Definition: qgsfillsymbol.h:30
QgsFillSymbol * clone() const override
Returns a deep copy of this symbol.
A base class for property widgets for layout items.
QgsVectorLayer * coverageLayer() const
Returns the current layout context coverage layer (if set).
void registerDataDefinedButton(QgsPropertyOverrideButton *button, QgsLayoutObject::DataDefinedProperty property)
Registers a data defined button, setting up its initial value, connections and description.
Item representing the paper in a layout.
const QgsFillSymbol * pageStyleSymbol() const
Returns the symbol to use for drawing the page background.
void setPageSize(const QgsLayoutSize &size)
Sets the size of the page.
QgsLayoutSize pageSize() const
Returns the size of the page.
Orientation orientation() const
Returns the page orientation.
void setPageStyleSymbol(QgsFillSymbol *symbol)
Sets the symbol to use for drawing the page background.
@ Landscape
Landscape orientation.
@ Portrait
Portrait orientation.
@ UndoPageSymbol
Layout page symbol change.
Base class for graphical items within a QgsLayout.
bool excludeFromExports() const
Returns whether the item should be excluded from layout exports and prints.
void beginCommand(const QString &commandText, UndoCommand command=UndoNone)
Starts new undo command for this item.
void endCommand()
Completes the current item command and push it onto the layout's undo stack.
void setExcludeFromExports(bool exclude)
Sets whether the item should be excluded from layout exports and prints.
QgsLayoutMeasurement convert(QgsLayoutMeasurement measurement, QgsUnitTypes::LayoutUnit targetUnits) const
Converts a measurement from one unit to another.
const QgsLayout * layout() const
Returns the layout the object is attached to.
@ PaperOrientation
Paper orientation.
@ ItemWidth
Width of item.
@ ItemHeight
Height of item.
@ ExcludeFromExports
Exclude item from exports.
@ PresetPaperSize
Preset paper size for composition.
void reflow()
Forces the page collection to reflow the arrangement of pages, e.g.
void endPageSizeChange()
Should be called after changing any page item sizes, and preceded by a call to beginPageSizeChange().
int pageNumber(QgsLayoutItemPage *page) const
Returns the page number for the specified page, or -1 if the page is not contained in the collection.
void beginPageSizeChange()
Should be called before changing any page item sizes, and followed by a call to endPageSizeChange().
QgsLayoutPagePropertiesWidget(QWidget *parent, QgsLayoutItem *page)
Constructor for QgsLayoutPagePropertiesWidget.
void pageOrientationChanged()
Emitted when page orientation changes.
const QgsLayoutMeasurementConverter & measurementConverter() const
Returns the layout measurement converter to be used in the layout.
void layerChanged(QgsVectorLayer *layer)
Emitted when the context's layer is changed.
This class provides a method of storing sizes, consisting of a width and height, for use in QGIS layo...
Definition: qgslayoutsize.h:41
QgsUnitTypes::LayoutUnit units() const
Returns the units for the size.
double height() const
Returns the height of the size.
Definition: qgslayoutsize.h:90
double width() const
Returns the width of the size.
Definition: qgslayoutsize.h:76
void endCommand()
Saves final state of an object and pushes the active command to the undo history.
void beginMacro(const QString &commandText)
Starts a macro command, with the given descriptive commandText.
void beginCommand(QgsLayoutUndoObjectInterface *object, const QString &commandText, int id=0)
Begins a new undo command for the specified object.
void endMacro()
Ends a macro command.
QgsLayoutRenderContext & renderContext()
Returns a reference to the layout's render context, which stores information relating to the current ...
Definition: qgslayout.cpp:359
QgsLayoutPageCollection * pageCollection()
Returns a pointer to the layout's page collection, which stores and manages page items in the layout.
Definition: qgslayout.cpp:459
void refresh()
Forces the layout, and all items contained within it, to refresh.
Definition: qgslayout.cpp:804
QgsLayoutReportContext & reportContext()
Returns a reference to the layout's report context, which stores information relating to the current ...
Definition: qgslayout.cpp:369
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
QList< QgsPageSize > entries() const
Returns a list of page sizes in the registry.
QList< QgsPageSize > find(const QString &name) const
Finds matching page sizes from the registry, using a case insensitive match on the page size name.
A named page size for layouts.
QgsLayoutSize size
Page size.
void changed()
Emitted when property definition changes.
void setLayer(QgsVectorLayer *layer)
Sets a layer to associate with the widget.
void changed()
Emitted when the symbol's settings are changed.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:537