QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
qgslayoutpropertieswidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgslayoutpropertieswidget.cpp
3 -----------------------------
4 begin : July 2017
5 copyright : (C) 2017 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************/
8/***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
18
20#include "qgslayout.h"
21#include "qgslayoutatlas.h"
22#include "qgslayoutitemmap.h"
25#include "qgslayoutsnapper.h"
26#include "qgslayoutundostack.h"
27#include "qgsmargins.h"
28#include "qgsprintlayout.h"
29
30#include "moc_qgslayoutpropertieswidget.cpp"
31
33 : QgsPanelWidget( parent )
34 , mLayout( layout )
35{
36 Q_ASSERT( mLayout );
37
38 setupUi( this );
39 setPanelTitle( tr( "Layout Properties" ) );
40 blockSignals( true );
41
42 mVariableEditor->setMinimumHeight( mVariableEditor->fontMetrics().height() * 15 );
43
44 updateSnappingElements();
45
46 mGridSpacingUnitsCombo->linkToWidget( mGridResolutionSpinBox );
47 mGridOffsetUnitsComboBox->linkToWidget( mOffsetXSpinBox );
48 mGridOffsetUnitsComboBox->linkToWidget( mOffsetYSpinBox );
49
50 blockSignals( false );
51
52 connect( mSnapToleranceSpinBox, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ), this, &QgsLayoutPropertiesWidget::snapToleranceChanged );
53
54 connect( mGridOffsetUnitsComboBox, &QgsLayoutUnitsComboBox::unitChanged, this, &QgsLayoutPropertiesWidget::gridOffsetUnitsChanged );
55 connect( mGridSpacingUnitsCombo, &QgsLayoutUnitsComboBox::unitChanged, this, &QgsLayoutPropertiesWidget::gridResolutionUnitsChanged );
56 connect( mGridResolutionSpinBox, static_cast<void ( QgsDoubleSpinBox::* )( double )>( &QgsDoubleSpinBox::valueChanged ), this, &QgsLayoutPropertiesWidget::gridResolutionChanged );
57 connect( mOffsetXSpinBox, static_cast<void ( QgsDoubleSpinBox::* )( double )>( &QgsDoubleSpinBox::valueChanged ), this, &QgsLayoutPropertiesWidget::gridOffsetXChanged );
58 connect( mOffsetYSpinBox, static_cast<void ( QgsDoubleSpinBox::* )( double )>( &QgsDoubleSpinBox::valueChanged ), this, &QgsLayoutPropertiesWidget::gridOffsetYChanged );
59
60 const double leftMargin = mLayout->customProperty( QStringLiteral( "resizeToContentsLeftMargin" ) ).toDouble();
61 const double topMargin = mLayout->customProperty( QStringLiteral( "resizeToContentsTopMargin" ) ).toDouble();
62 const double bottomMargin = mLayout->customProperty( QStringLiteral( "resizeToContentsBottomMargin" ) ).toDouble();
63 const double rightMargin = mLayout->customProperty( QStringLiteral( "resizeToContentsRightMargin" ) ).toDouble();
64 const Qgis::LayoutUnit marginUnit = static_cast<Qgis::LayoutUnit>(
65 mLayout->customProperty( QStringLiteral( "imageCropMarginUnit" ), static_cast<int>( Qgis::LayoutUnit::Millimeters ) ).toInt()
66 );
67
68 const bool exportWorldFile = mLayout->customProperty( QStringLiteral( "exportWorldFile" ), false ).toBool();
69 mGenerateWorldFileCheckBox->setChecked( exportWorldFile );
70 connect( mGenerateWorldFileCheckBox, &QCheckBox::toggled, this, &QgsLayoutPropertiesWidget::worldFileToggled );
71
72 connect( mRasterizeCheckBox, &QCheckBox::toggled, this, &QgsLayoutPropertiesWidget::rasterizeToggled );
73 connect( mForceVectorCheckBox, &QCheckBox::toggled, this, &QgsLayoutPropertiesWidget::forceVectorToggled );
74
75 mTopMarginSpinBox->setValue( topMargin );
76 mMarginUnitsComboBox->linkToWidget( mTopMarginSpinBox );
77 mRightMarginSpinBox->setValue( rightMargin );
78 mMarginUnitsComboBox->linkToWidget( mRightMarginSpinBox );
79 mBottomMarginSpinBox->setValue( bottomMargin );
80 mMarginUnitsComboBox->linkToWidget( mBottomMarginSpinBox );
81 mLeftMarginSpinBox->setValue( leftMargin );
82 mMarginUnitsComboBox->linkToWidget( mLeftMarginSpinBox );
83 mMarginUnitsComboBox->setUnit( marginUnit );
84 mMarginUnitsComboBox->setConverter( &mLayout->renderContext().measurementConverter() );
85
86 connect( mTopMarginSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPropertiesWidget::resizeMarginsChanged );
87 connect( mRightMarginSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPropertiesWidget::resizeMarginsChanged );
88 connect( mBottomMarginSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPropertiesWidget::resizeMarginsChanged );
89 connect( mLeftMarginSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPropertiesWidget::resizeMarginsChanged );
90 connect( mResizePageButton, &QPushButton::clicked, this, &QgsLayoutPropertiesWidget::resizeToContents );
91
92 connect( mResolutionSpinBox, &QSpinBox::editingFinished, this, [this] { dpiChanged( mResolutionSpinBox->value() ); } );
93
94 mReferenceMapComboBox->setCurrentLayout( mLayout );
95 mReferenceMapComboBox->setItemType( QgsLayoutItemRegistry::LayoutMap );
96 connect( mReferenceMapComboBox, &QgsLayoutItemComboBox::itemChanged, this, &QgsLayoutPropertiesWidget::referenceMapChanged );
97
99
100 updateVariables();
101 connect( mVariableEditor, &QgsVariableEditorWidget::scopeChanged, this, &QgsLayoutPropertiesWidget::variablesChanged );
102 // listen out for variable edits
103 connect( QgsApplication::instance(), &QgsApplication::customVariablesChanged, this, &QgsLayoutPropertiesWidget::updateVariables );
104 connect( QgsProject::instance(), &QgsProject::customVariablesChanged, this, &QgsLayoutPropertiesWidget::updateVariables );
105 connect( QgsProject::instance(), &QgsProject::metadataChanged, this, &QgsLayoutPropertiesWidget::updateVariables );
106 connect( &mLayout->renderContext(), &QgsLayoutRenderContext::dpiChanged, this, &QgsLayoutPropertiesWidget::updateVariables );
107 connect( mLayout->pageCollection(), &QgsLayoutPageCollection::changed, this, &QgsLayoutPropertiesWidget::updateVariables );
108 connect( mLayout, &QgsLayout::variablesChanged, this, &QgsLayoutPropertiesWidget::updateVariables );
109
110 updateGui();
111}
112
114{
115 if ( QgsPrintLayout *printLayout = dynamic_cast<QgsPrintLayout *>( masterLayout ) )
116 {
117 connect( printLayout, &QgsPrintLayout::nameChanged, this, &QgsLayoutPropertiesWidget::updateVariables );
118 connect( printLayout->atlas(), &QgsLayoutAtlas::coverageLayerChanged, this, &QgsLayoutPropertiesWidget::updateVariables );
119 }
120}
121
123{
124 whileBlocking( mReferenceMapComboBox )->setItem( mLayout->referenceMap() );
125 whileBlocking( mResolutionSpinBox )->setValue( mLayout->renderContext().dpi() );
126
127 const bool rasterize = mLayout->customProperty( QStringLiteral( "rasterize" ), false ).toBool();
128 whileBlocking( mRasterizeCheckBox )->setChecked( rasterize );
129
130 const bool forceVectors = mLayout->customProperty( QStringLiteral( "forceVector" ), false ).toBool();
131 whileBlocking( mForceVectorCheckBox )->setChecked( forceVectors );
132
133 if ( rasterize )
134 {
135 mForceVectorCheckBox->setChecked( false );
136 mForceVectorCheckBox->setEnabled( false );
137 }
138 else
139 {
140 mForceVectorCheckBox->setEnabled( true );
141 }
142}
143
144void QgsLayoutPropertiesWidget::updateSnappingElements()
145{
146 mSnapToleranceSpinBox->setValue( mLayout->snapper().snapTolerance() );
147
148 mGridSpacingUnitsCombo->setUnit( mLayout->gridSettings().resolution().units() );
149 mGridResolutionSpinBox->setValue( mLayout->gridSettings().resolution().length() );
150
151 mGridOffsetUnitsComboBox->setUnit( mLayout->gridSettings().offset().units() );
152 mOffsetXSpinBox->setValue( mLayout->gridSettings().offset().x() );
153 mOffsetYSpinBox->setValue( mLayout->gridSettings().offset().y() );
154}
155
156void QgsLayoutPropertiesWidget::gridResolutionChanged( double d )
157{
158 QgsLayoutMeasurement m = mLayout->gridSettings().resolution();
159 m.setLength( d );
160 mLayout->gridSettings().setResolution( m );
161 mLayout->pageCollection()->redraw();
162}
163
164void QgsLayoutPropertiesWidget::gridResolutionUnitsChanged( Qgis::LayoutUnit unit )
165{
166 QgsLayoutMeasurement m = mLayout->gridSettings().resolution();
167 m.setUnits( unit );
168 mLayout->gridSettings().setResolution( m );
169 mLayout->pageCollection()->redraw();
170}
171
172void QgsLayoutPropertiesWidget::gridOffsetXChanged( double d )
173{
174 QgsLayoutPoint o = mLayout->gridSettings().offset();
175 o.setX( d );
176 mLayout->gridSettings().setOffset( o );
177 mLayout->pageCollection()->redraw();
178}
179
180void QgsLayoutPropertiesWidget::gridOffsetYChanged( double d )
181{
182 QgsLayoutPoint o = mLayout->gridSettings().offset();
183 o.setY( d );
184 mLayout->gridSettings().setOffset( o );
185 mLayout->pageCollection()->redraw();
186}
187
188void QgsLayoutPropertiesWidget::gridOffsetUnitsChanged( Qgis::LayoutUnit unit )
189{
190 QgsLayoutPoint o = mLayout->gridSettings().offset();
191 o.setUnits( unit );
192 mLayout->gridSettings().setOffset( o );
193 mLayout->pageCollection()->redraw();
194}
195
196void QgsLayoutPropertiesWidget::snapToleranceChanged( int tolerance )
197{
198 mLayout->snapper().setSnapTolerance( tolerance );
199}
200
201void QgsLayoutPropertiesWidget::resizeMarginsChanged()
202{
203 mLayout->setCustomProperty( QStringLiteral( "resizeToContentsLeftMargin" ), mLeftMarginSpinBox->value() );
204 mLayout->setCustomProperty( QStringLiteral( "resizeToContentsTopMargin" ), mTopMarginSpinBox->value() );
205 mLayout->setCustomProperty( QStringLiteral( "resizeToContentsBottomMargin" ), mBottomMarginSpinBox->value() );
206 mLayout->setCustomProperty( QStringLiteral( "resizeToContentsRightMargin" ), mRightMarginSpinBox->value() );
207 mLayout->setCustomProperty( QStringLiteral( "imageCropMarginUnit" ), static_cast<int>( mMarginUnitsComboBox->unit() ) );
208}
209
210void QgsLayoutPropertiesWidget::resizeToContents()
211{
212 mLayout->undoStack()->beginMacro( tr( "Resize to Contents" ) );
213
214 mLayout->pageCollection()->resizeToContents( QgsMargins( mLeftMarginSpinBox->value(), mTopMarginSpinBox->value(), mRightMarginSpinBox->value(), mBottomMarginSpinBox->value() ), mMarginUnitsComboBox->unit() );
215
216 mLayout->undoStack()->endMacro();
217}
218
219void QgsLayoutPropertiesWidget::referenceMapChanged( QgsLayoutItem *item )
220{
221 mLayout->undoStack()->beginCommand( mLayout, tr( "Set Reference Map" ) );
222 QgsLayoutItemMap *map = qobject_cast<QgsLayoutItemMap *>( item );
223 mLayout->setReferenceMap( map );
224 mLayout->undoStack()->endCommand();
225}
226
227void QgsLayoutPropertiesWidget::dpiChanged( int value )
228{
229 mLayout->undoStack()->beginCommand( mLayout, tr( "Set Default DPI" ), QgsLayout::UndoLayoutDpi );
230 mLayout->renderContext().setDpi( value );
231 mLayout->undoStack()->endCommand();
232
233 mLayout->refresh();
234}
235
236void QgsLayoutPropertiesWidget::worldFileToggled()
237{
238 mLayout->setCustomProperty( QStringLiteral( "exportWorldFile" ), mGenerateWorldFileCheckBox->isChecked() );
239}
240
241void QgsLayoutPropertiesWidget::rasterizeToggled()
242{
243 mLayout->setCustomProperty( QStringLiteral( "rasterize" ), mRasterizeCheckBox->isChecked() );
244
245 if ( mRasterizeCheckBox->isChecked() )
246 {
247 mForceVectorCheckBox->setChecked( false );
248 mForceVectorCheckBox->setEnabled( false );
249 }
250 else
251 {
252 mForceVectorCheckBox->setEnabled( true );
253 }
254}
255
256void QgsLayoutPropertiesWidget::forceVectorToggled()
257{
258 mLayout->setCustomProperty( QStringLiteral( "forceVector" ), mForceVectorCheckBox->isChecked() );
259}
260
261void QgsLayoutPropertiesWidget::variablesChanged()
262{
263 mBlockVariableUpdates = true;
264 QgsExpressionContextUtils::setLayoutVariables( mLayout, mVariableEditor->variablesInActiveScope() );
265 mBlockVariableUpdates = false;
266}
267
268void QgsLayoutPropertiesWidget::updateVariables()
269{
270 if ( mBlockVariableUpdates )
271 return;
272
273 QgsExpressionContext context;
277 mVariableEditor->setContext( &context );
278 mVariableEditor->setEditableScopeIndex( 2 );
279}
280
281void QgsLayoutPropertiesWidget::blockSignals( bool block )
282{
283 mGridResolutionSpinBox->blockSignals( block );
284 mOffsetXSpinBox->blockSignals( block );
285 mOffsetYSpinBox->blockSignals( block );
286 mSnapToleranceSpinBox->blockSignals( block );
287}
LayoutUnit
Layout measurement units.
Definition qgis.h:5203
@ Millimeters
Millimeters.
Definition qgis.h:5204
void customVariablesChanged()
Emitted whenever a custom global variable changes.
static QgsApplication * instance()
Returns the singleton instance of the QgsApplication.
The QgsSpinBox is a spin box with a clear button that will set the value to the defined clear value.
static QgsExpressionContextScope * layoutScope(const QgsLayout *layout)
Creates a new scope which contains variables and functions relating to a QgsLayout layout.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static void setLayoutVariables(QgsLayout *layout, const QVariantMap &variables)
Sets all layout context variables.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
void coverageLayerChanged(QgsVectorLayer *layer)
Emitted when the coverage layer for the atlas changes.
QgsLayoutMeasurement resolution() const
Returns the page/snap grid resolution.
QgsLayoutPoint offset() const
Returns the offset of the page/snap grid.
void itemChanged(QgsLayoutItem *item)
Emitted whenever the currently selected item changes.
Base class for graphical items within a QgsLayout.
void setLength(const double length)
Sets the length of the measurement.
Qgis::LayoutUnit units() const
Returns the units for the measurement.
void setUnits(const Qgis::LayoutUnit units)
Sets the units for the measurement.
double length() const
Returns the length of the measurement.
void changed()
Emitted when pages are added or removed from the collection.
double x() const
Returns x coordinate of point.
void setX(const double x)
Sets the x coordinate of point.
void setUnits(const Qgis::LayoutUnit units)
Sets the units for the point.
double y() const
Returns y coordinate of point.
Qgis::LayoutUnit units() const
Returns the units for the point.
void setY(const double y)
Sets y coordinate of point.
void setMasterLayout(QgsMasterLayoutInterface *masterLayout)
Sets the master layout.
void updateGui()
Refreshes the gui to reflect the current layout settings.
QgsLayoutPropertiesWidget(QWidget *parent, QgsLayout *layout)
constructor
void dpiChanged()
Emitted when the context's DPI is changed.
int snapTolerance() const
Returns the snap tolerance (in pixels) to use when snapping.
void unitChanged(Qgis::LayoutUnit unit)
Emitted when the unit is changed.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition qgslayout.h:50
QgsLayoutSnapper & snapper()
Returns a reference to the layout's snapper, which stores handles layout snap grids and lines and sna...
Definition qgslayout.h:408
void variablesChanged()
Emitted whenever the expression variables stored in the layout have been changed.
void changed()
Emitted when properties of the layout change.
QgsLayoutGridSettings & gridSettings()
Returns a reference to the layout's grid settings, which stores settings relating to grid appearance,...
Definition qgslayout.h:420
@ UndoLayoutDpi
Change layout default DPI.
Definition qgslayout.h:71
Interface for master layout type objects, such as print layouts and reports.
QgsPanelWidget(QWidget *parent=nullptr)
Base class for any widget that can be shown as an inline panel.
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
Print layout, a QgsLayout subclass for static or atlas-based layouts.
void nameChanged(const QString &name)
Emitted when the layout's name is changed.
static QgsProject * instance()
Returns the QgsProject singleton instance.
void metadataChanged()
Emitted when the project's metadata is changed.
void customVariablesChanged()
Emitted whenever the expression variables stored in the project have been changed.
void scopeChanged()
Emitted when the user has modified a scope using the widget.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition qgis.h:6511