QGIS API Documentation 3.99.0-Master (09f76ad7019)
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 <QString>
31
32#include "moc_qgslayoutpropertieswidget.cpp"
33
34using namespace Qt::StringLiterals;
35
37 : QgsPanelWidget( parent )
38 , mLayout( layout )
39{
40 Q_ASSERT( mLayout );
41
42 setupUi( this );
43 setPanelTitle( tr( "Layout Properties" ) );
44 blockSignals( true );
45
46 mVariableEditor->setMinimumHeight( mVariableEditor->fontMetrics().height() * 15 );
47
48 updateSnappingElements();
49
50 mGridSpacingUnitsCombo->linkToWidget( mGridResolutionSpinBox );
51 mGridOffsetUnitsComboBox->linkToWidget( mOffsetXSpinBox );
52 mGridOffsetUnitsComboBox->linkToWidget( mOffsetYSpinBox );
53
54 blockSignals( false );
55
56 connect( mSnapToleranceSpinBox, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ), this, &QgsLayoutPropertiesWidget::snapToleranceChanged );
57
58 connect( mGridOffsetUnitsComboBox, &QgsLayoutUnitsComboBox::unitChanged, this, &QgsLayoutPropertiesWidget::gridOffsetUnitsChanged );
59 connect( mGridSpacingUnitsCombo, &QgsLayoutUnitsComboBox::unitChanged, this, &QgsLayoutPropertiesWidget::gridResolutionUnitsChanged );
60 connect( mGridResolutionSpinBox, static_cast<void ( QgsDoubleSpinBox::* )( double )>( &QgsDoubleSpinBox::valueChanged ), this, &QgsLayoutPropertiesWidget::gridResolutionChanged );
61 connect( mOffsetXSpinBox, static_cast<void ( QgsDoubleSpinBox::* )( double )>( &QgsDoubleSpinBox::valueChanged ), this, &QgsLayoutPropertiesWidget::gridOffsetXChanged );
62 connect( mOffsetYSpinBox, static_cast<void ( QgsDoubleSpinBox::* )( double )>( &QgsDoubleSpinBox::valueChanged ), this, &QgsLayoutPropertiesWidget::gridOffsetYChanged );
63
64 const double leftMargin = mLayout->customProperty( u"resizeToContentsLeftMargin"_s ).toDouble();
65 const double topMargin = mLayout->customProperty( u"resizeToContentsTopMargin"_s ).toDouble();
66 const double bottomMargin = mLayout->customProperty( u"resizeToContentsBottomMargin"_s ).toDouble();
67 const double rightMargin = mLayout->customProperty( u"resizeToContentsRightMargin"_s ).toDouble();
68 const Qgis::LayoutUnit marginUnit = static_cast<Qgis::LayoutUnit>(
69 mLayout->customProperty( u"imageCropMarginUnit"_s, static_cast<int>( Qgis::LayoutUnit::Millimeters ) ).toInt()
70 );
71
72 const bool exportWorldFile = mLayout->customProperty( u"exportWorldFile"_s, false ).toBool();
73 mGenerateWorldFileCheckBox->setChecked( exportWorldFile );
74 connect( mGenerateWorldFileCheckBox, &QCheckBox::toggled, this, &QgsLayoutPropertiesWidget::worldFileToggled );
75
76 connect( mRasterizeCheckBox, &QCheckBox::toggled, this, &QgsLayoutPropertiesWidget::rasterizeToggled );
77 connect( mForceVectorCheckBox, &QCheckBox::toggled, this, &QgsLayoutPropertiesWidget::forceVectorToggled );
78
79 mTopMarginSpinBox->setValue( topMargin );
80 mMarginUnitsComboBox->linkToWidget( mTopMarginSpinBox );
81 mRightMarginSpinBox->setValue( rightMargin );
82 mMarginUnitsComboBox->linkToWidget( mRightMarginSpinBox );
83 mBottomMarginSpinBox->setValue( bottomMargin );
84 mMarginUnitsComboBox->linkToWidget( mBottomMarginSpinBox );
85 mLeftMarginSpinBox->setValue( leftMargin );
86 mMarginUnitsComboBox->linkToWidget( mLeftMarginSpinBox );
87 mMarginUnitsComboBox->setUnit( marginUnit );
88 mMarginUnitsComboBox->setConverter( &mLayout->renderContext().measurementConverter() );
89
90 connect( mTopMarginSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPropertiesWidget::resizeMarginsChanged );
91 connect( mRightMarginSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPropertiesWidget::resizeMarginsChanged );
92 connect( mBottomMarginSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPropertiesWidget::resizeMarginsChanged );
93 connect( mLeftMarginSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPropertiesWidget::resizeMarginsChanged );
94 connect( mResizePageButton, &QPushButton::clicked, this, &QgsLayoutPropertiesWidget::resizeToContents );
95
96 connect( mResolutionSpinBox, &QSpinBox::editingFinished, this, [this] { dpiChanged( mResolutionSpinBox->value() ); } );
97
98 mReferenceMapComboBox->setCurrentLayout( mLayout );
99 mReferenceMapComboBox->setItemType( QgsLayoutItemRegistry::LayoutMap );
100 connect( mReferenceMapComboBox, &QgsLayoutItemComboBox::itemChanged, this, &QgsLayoutPropertiesWidget::referenceMapChanged );
101
102 connect( mLayout, &QgsLayout::changed, this, &QgsLayoutPropertiesWidget::updateGui );
103
104 updateVariables();
105 connect( mVariableEditor, &QgsVariableEditorWidget::scopeChanged, this, &QgsLayoutPropertiesWidget::variablesChanged );
106 // listen out for variable edits
107 connect( QgsApplication::instance(), &QgsApplication::customVariablesChanged, this, &QgsLayoutPropertiesWidget::updateVariables );
108 connect( QgsProject::instance(), &QgsProject::customVariablesChanged, this, &QgsLayoutPropertiesWidget::updateVariables );
109 connect( QgsProject::instance(), &QgsProject::metadataChanged, this, &QgsLayoutPropertiesWidget::updateVariables );
110 connect( &mLayout->renderContext(), &QgsLayoutRenderContext::dpiChanged, this, &QgsLayoutPropertiesWidget::updateVariables );
111 connect( mLayout->pageCollection(), &QgsLayoutPageCollection::changed, this, &QgsLayoutPropertiesWidget::updateVariables );
112 connect( mLayout, &QgsLayout::variablesChanged, this, &QgsLayoutPropertiesWidget::updateVariables );
113
114 updateGui();
115}
116
118{
119 if ( QgsPrintLayout *printLayout = dynamic_cast<QgsPrintLayout *>( masterLayout ) )
120 {
121 connect( printLayout, &QgsPrintLayout::nameChanged, this, &QgsLayoutPropertiesWidget::updateVariables );
122 connect( printLayout->atlas(), &QgsLayoutAtlas::coverageLayerChanged, this, &QgsLayoutPropertiesWidget::updateVariables );
123 }
124}
125
127{
128 whileBlocking( mReferenceMapComboBox )->setItem( mLayout->referenceMap() );
129 whileBlocking( mResolutionSpinBox )->setValue( mLayout->renderContext().dpi() );
130
131 const bool rasterize = mLayout->customProperty( u"rasterize"_s, false ).toBool();
132 whileBlocking( mRasterizeCheckBox )->setChecked( rasterize );
133
134 const bool forceVectors = mLayout->customProperty( u"forceVector"_s, false ).toBool();
135 whileBlocking( mForceVectorCheckBox )->setChecked( forceVectors );
136
137 if ( rasterize )
138 {
139 mForceVectorCheckBox->setChecked( false );
140 mForceVectorCheckBox->setEnabled( false );
141 }
142 else
143 {
144 mForceVectorCheckBox->setEnabled( true );
145 }
146}
147
148void QgsLayoutPropertiesWidget::updateSnappingElements()
149{
150 mSnapToleranceSpinBox->setValue( mLayout->snapper().snapTolerance() );
151
152 mGridSpacingUnitsCombo->setUnit( mLayout->gridSettings().resolution().units() );
153 mGridResolutionSpinBox->setValue( mLayout->gridSettings().resolution().length() );
154
155 mGridOffsetUnitsComboBox->setUnit( mLayout->gridSettings().offset().units() );
156 mOffsetXSpinBox->setValue( mLayout->gridSettings().offset().x() );
157 mOffsetYSpinBox->setValue( mLayout->gridSettings().offset().y() );
158}
159
160void QgsLayoutPropertiesWidget::gridResolutionChanged( double d )
161{
162 QgsLayoutMeasurement m = mLayout->gridSettings().resolution();
163 m.setLength( d );
164 mLayout->gridSettings().setResolution( m );
165 mLayout->pageCollection()->redraw();
166}
167
168void QgsLayoutPropertiesWidget::gridResolutionUnitsChanged( Qgis::LayoutUnit unit )
169{
170 QgsLayoutMeasurement m = mLayout->gridSettings().resolution();
171 m.setUnits( unit );
172 mLayout->gridSettings().setResolution( m );
173 mLayout->pageCollection()->redraw();
174}
175
176void QgsLayoutPropertiesWidget::gridOffsetXChanged( double d )
177{
178 QgsLayoutPoint o = mLayout->gridSettings().offset();
179 o.setX( d );
180 mLayout->gridSettings().setOffset( o );
181 mLayout->pageCollection()->redraw();
182}
183
184void QgsLayoutPropertiesWidget::gridOffsetYChanged( double d )
185{
186 QgsLayoutPoint o = mLayout->gridSettings().offset();
187 o.setY( d );
188 mLayout->gridSettings().setOffset( o );
189 mLayout->pageCollection()->redraw();
190}
191
192void QgsLayoutPropertiesWidget::gridOffsetUnitsChanged( Qgis::LayoutUnit unit )
193{
194 QgsLayoutPoint o = mLayout->gridSettings().offset();
195 o.setUnits( unit );
196 mLayout->gridSettings().setOffset( o );
197 mLayout->pageCollection()->redraw();
198}
199
200void QgsLayoutPropertiesWidget::snapToleranceChanged( int tolerance )
201{
202 mLayout->snapper().setSnapTolerance( tolerance );
203}
204
205void QgsLayoutPropertiesWidget::resizeMarginsChanged()
206{
207 mLayout->setCustomProperty( u"resizeToContentsLeftMargin"_s, mLeftMarginSpinBox->value() );
208 mLayout->setCustomProperty( u"resizeToContentsTopMargin"_s, mTopMarginSpinBox->value() );
209 mLayout->setCustomProperty( u"resizeToContentsBottomMargin"_s, mBottomMarginSpinBox->value() );
210 mLayout->setCustomProperty( u"resizeToContentsRightMargin"_s, mRightMarginSpinBox->value() );
211 mLayout->setCustomProperty( u"imageCropMarginUnit"_s, static_cast<int>( mMarginUnitsComboBox->unit() ) );
212}
213
214void QgsLayoutPropertiesWidget::resizeToContents()
215{
216 mLayout->undoStack()->beginMacro( tr( "Resize to Contents" ) );
217
218 mLayout->pageCollection()->resizeToContents( QgsMargins( mLeftMarginSpinBox->value(), mTopMarginSpinBox->value(), mRightMarginSpinBox->value(), mBottomMarginSpinBox->value() ), mMarginUnitsComboBox->unit() );
219
220 mLayout->undoStack()->endMacro();
221}
222
223void QgsLayoutPropertiesWidget::referenceMapChanged( QgsLayoutItem *item )
224{
225 mLayout->undoStack()->beginCommand( mLayout, tr( "Set Reference Map" ) );
226 QgsLayoutItemMap *map = qobject_cast<QgsLayoutItemMap *>( item );
227 mLayout->setReferenceMap( map );
228 mLayout->undoStack()->endCommand();
229}
230
231void QgsLayoutPropertiesWidget::dpiChanged( int value )
232{
233 mLayout->undoStack()->beginCommand( mLayout, tr( "Set Default DPI" ), QgsLayout::UndoLayoutDpi );
234 mLayout->renderContext().setDpi( value );
235 mLayout->undoStack()->endCommand();
236
237 mLayout->refresh();
238}
239
240void QgsLayoutPropertiesWidget::worldFileToggled()
241{
242 mLayout->setCustomProperty( u"exportWorldFile"_s, mGenerateWorldFileCheckBox->isChecked() );
243}
244
245void QgsLayoutPropertiesWidget::rasterizeToggled()
246{
247 mLayout->setCustomProperty( u"rasterize"_s, mRasterizeCheckBox->isChecked() );
248
249 if ( mRasterizeCheckBox->isChecked() )
250 {
251 mForceVectorCheckBox->setChecked( false );
252 mForceVectorCheckBox->setEnabled( false );
253 }
254 else
255 {
256 mForceVectorCheckBox->setEnabled( true );
257 }
258}
259
260void QgsLayoutPropertiesWidget::forceVectorToggled()
261{
262 mLayout->setCustomProperty( u"forceVector"_s, mForceVectorCheckBox->isChecked() );
263}
264
265void QgsLayoutPropertiesWidget::variablesChanged()
266{
267 mBlockVariableUpdates = true;
268 QgsExpressionContextUtils::setLayoutVariables( mLayout, mVariableEditor->variablesInActiveScope() );
269 mBlockVariableUpdates = false;
270}
271
272void QgsLayoutPropertiesWidget::updateVariables()
273{
274 if ( mBlockVariableUpdates )
275 return;
276
277 QgsExpressionContext context;
281 mVariableEditor->setContext( &context );
282 mVariableEditor->setEditableScopeIndex( 2 );
283}
284
285void QgsLayoutPropertiesWidget::blockSignals( bool block )
286{
287 mGridResolutionSpinBox->blockSignals( block );
288 mOffsetXSpinBox->blockSignals( block );
289 mOffsetYSpinBox->blockSignals( block );
290 mSnapToleranceSpinBox->blockSignals( block );
291}
LayoutUnit
Layout measurement units.
Definition qgis.h:5310
@ Millimeters
Millimeters.
Definition qgis.h:5311
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:6839