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