QGIS API Documentation 3.41.0-Master (af5edcb665c)
Loading...
Searching...
No Matches
qgslayoutpolylinewidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgslayoutpolylinewidget.cpp
3 begin : March 2016
4 copyright : (C) 2016 Paul Blottiere, Oslandia
5 email : paul dot blottiere at oslandia dot com
6 ***************************************************************************/
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#include "moc_qgslayoutpolylinewidget.cpp"
20#include "qgslayout.h"
21#include "qgslayoutundostack.h"
22#include "qgsvectorlayer.h"
23#include "qgslinesymbol.h"
25
26#include <QButtonGroup>
27#include <QFileDialog>
28
30 : QgsLayoutItemBaseWidget( nullptr, polyline )
31 , mPolyline( polyline )
32{
33 setupUi( this );
34 setPanelTitle( tr( "Polyline Properties" ) );
35
36 connect( mStrokeWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPolylineWidget::arrowStrokeWidthChanged );
37 connect( mArrowHeadWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPolylineWidget::arrowHeadWidthChanged );
38 connect( mArrowHeadFillColorButton, &QgsColorButton::colorChanged, this, &QgsLayoutPolylineWidget::arrowHeadFillColorChanged );
39 connect( mArrowHeadStrokeColorButton, &QgsColorButton::colorChanged, this, &QgsLayoutPolylineWidget::arrowHeadStrokeColorChanged );
40 connect( mRadioStartArrow, &QRadioButton::toggled, this, &QgsLayoutPolylineWidget::startArrowHeadToggled );
41 connect( mRadioStartNoMarker, &QRadioButton::toggled, this, &QgsLayoutPolylineWidget::startNoMarkerToggled );
42 connect( mRadioStartSVG, &QRadioButton::toggled, this, &QgsLayoutPolylineWidget::startSvgMarkerToggled );
43 connect( mRadioEndArrow, &QRadioButton::toggled, this, &QgsLayoutPolylineWidget::endArrowHeadToggled );
44 connect( mRadioEndNoMarker, &QRadioButton::toggled, this, &QgsLayoutPolylineWidget::endNoMarkerToggled );
45 connect( mRadioEndSvg, &QRadioButton::toggled, this, &QgsLayoutPolylineWidget::endSvgMarkerToggled );
46 connect( mStartMarkerLineEdit, &QLineEdit::textChanged, this, &QgsLayoutPolylineWidget::mStartMarkerLineEdit_textChanged );
47 connect( mEndMarkerLineEdit, &QLineEdit::textChanged, this, &QgsLayoutPolylineWidget::mEndMarkerLineEdit_textChanged );
48 connect( mStartMarkerToolButton, &QToolButton::clicked, this, &QgsLayoutPolylineWidget::mStartMarkerToolButton_clicked );
49 connect( mEndMarkerToolButton, &QToolButton::clicked, this, &QgsLayoutPolylineWidget::mEndMarkerToolButton_clicked );
50 setPanelTitle( tr( "Arrow Properties" ) );
51 QButtonGroup *startMarkerGroup = new QButtonGroup( this );
52 startMarkerGroup->addButton( mRadioStartNoMarker );
53 startMarkerGroup->addButton( mRadioStartArrow );
54 startMarkerGroup->addButton( mRadioStartSVG );
55 startMarkerGroup->setExclusive( true );
56 QButtonGroup *endMarkerGroup = new QButtonGroup( this );
57 endMarkerGroup->addButton( mRadioEndNoMarker );
58 endMarkerGroup->addButton( mRadioEndArrow );
59 endMarkerGroup->addButton( mRadioEndSvg );
60 endMarkerGroup->setExclusive( true );
61
62 //disable the svg related gui elements by default
63 enableStartSvgInputElements( false );
64 enableEndSvgInputElements( false );
65
66 mArrowHeadStrokeColorButton->setColorDialogTitle( tr( "Select Arrow Head Stroke Color" ) );
67 mArrowHeadStrokeColorButton->setAllowOpacity( true );
68 mArrowHeadStrokeColorButton->setContext( QStringLiteral( "composer" ) );
69 mArrowHeadStrokeColorButton->setNoColorString( tr( "Transparent Stroke" ) );
70 mArrowHeadStrokeColorButton->setShowNoColor( true );
71 mArrowHeadFillColorButton->setColorDialogTitle( tr( "Select Arrow Head Fill Color" ) );
72 mArrowHeadFillColorButton->setAllowOpacity( true );
73 mArrowHeadFillColorButton->setContext( QStringLiteral( "composer" ) );
74 mArrowHeadFillColorButton->setNoColorString( tr( "Transparent Fill" ) );
75 mArrowHeadFillColorButton->setShowNoColor( true );
76
77 //add widget for general composer item properties
78 mItemPropertiesWidget = new QgsLayoutItemPropertiesWidget( this, polyline );
79 //shapes don't use background or frame, since the symbol style is set through a QgsSymbolSelectorWidget
80 mItemPropertiesWidget->showBackgroundGroup( false );
81 mItemPropertiesWidget->showFrameGroup( false );
82 mainLayout->addWidget( mItemPropertiesWidget );
83
84 mLineStyleButton->setSymbolType( Qgis::SymbolType::Line );
85 connect( mLineStyleButton, &QgsSymbolButton::changed, this, &QgsLayoutPolylineWidget::symbolChanged );
86
87 if ( mPolyline )
88 {
89 connect( mPolyline, &QgsLayoutObject::changed, this, &QgsLayoutPolylineWidget::setGuiElementValues );
90 mLineStyleButton->registerExpressionContextGenerator( mPolyline );
91 }
92 setGuiElementValues();
93
94 mLineStyleButton->registerExpressionContextGenerator( mPolyline );
95 mLineStyleButton->setLayer( coverageLayer() );
96 if ( mPolyline->layout() )
97 {
98 connect( &mPolyline->layout()->reportContext(), &QgsLayoutReportContext::layerChanged, mLineStyleButton, &QgsSymbolButton::setLayer );
99 }
100}
101
103{
104 if ( mItemPropertiesWidget )
105 mItemPropertiesWidget->setMasterLayout( masterLayout );
106}
107
109{
111 return false;
112
113 if ( mPolyline )
114 {
115 disconnect( mPolyline, &QgsLayoutObject::changed, this, &QgsLayoutPolylineWidget::setGuiElementValues );
116 }
117
118 mPolyline = qobject_cast<QgsLayoutItemPolyline *>( item );
119 mItemPropertiesWidget->setItem( mPolyline );
120
121 if ( mPolyline )
122 {
123 connect( mPolyline, &QgsLayoutObject::changed, this, &QgsLayoutPolylineWidget::setGuiElementValues );
124 mLineStyleButton->registerExpressionContextGenerator( mPolyline );
125 }
126
127 setGuiElementValues();
128
129 return true;
130}
131
132
133void QgsLayoutPolylineWidget::setGuiElementValues()
134{
135 if ( !mPolyline )
136 return;
137
138 whileBlocking( mLineStyleButton )->setSymbol( mPolyline->symbol()->clone() );
139
140 whileBlocking( mArrowHeadFillColorButton )->setColor( mPolyline->arrowHeadFillColor() );
141 whileBlocking( mArrowHeadStrokeColorButton )->setColor( mPolyline->arrowHeadStrokeColor() );
142 whileBlocking( mStrokeWidthSpinBox )->setValue( mPolyline->arrowHeadStrokeWidth() );
143 whileBlocking( mArrowHeadWidthSpinBox )->setValue( mPolyline->arrowHeadWidth() );
144
145 mRadioStartNoMarker->blockSignals( true );
146 mRadioStartArrow->blockSignals( true );
147 mRadioStartSVG->blockSignals( true );
148 mRadioEndArrow->blockSignals( true );
149 mRadioEndNoMarker->blockSignals( true );
150 mRadioEndSvg->blockSignals( true );
151 switch ( mPolyline->startMarker() )
152 {
154 mRadioStartNoMarker->setChecked( true );
155 break;
157 mRadioStartArrow->setChecked( true );
158 break;
160 mRadioStartSVG->setChecked( true );
161 enableStartSvgInputElements( true );
162 break;
163 }
164 switch ( mPolyline->endMarker() )
165 {
167 mRadioEndNoMarker->setChecked( true );
168 break;
170 mRadioEndArrow->setChecked( true );
171 break;
173 mRadioEndSvg->setChecked( true );
174 enableEndSvgInputElements( true );
175 break;
176 }
177 mRadioStartNoMarker->blockSignals( false );
178 mRadioStartArrow->blockSignals( false );
179 mRadioStartSVG->blockSignals( false );
180 mRadioEndArrow->blockSignals( false );
181 mRadioEndNoMarker->blockSignals( false );
182 mRadioEndSvg->blockSignals( false );
183
184 mStartMarkerLineEdit->setText( mPolyline->startSvgMarkerPath() );
185 mEndMarkerLineEdit->setText( mPolyline->endSvgMarkerPath() );
186}
187
188void QgsLayoutPolylineWidget::symbolChanged()
189{
190 if ( !mPolyline )
191 return;
192
193 mPolyline->layout()->undoStack()->beginCommand( mPolyline, tr( "Change Shape Style" ), QgsLayoutItem::UndoShapeStyle );
194 mPolyline->setSymbol( mLineStyleButton->clonedSymbol<QgsLineSymbol>() );
195 mPolyline->layout()->undoStack()->endCommand();
196}
197
198void QgsLayoutPolylineWidget::arrowStrokeWidthChanged( double d )
199{
200 if ( !mPolyline )
201 return;
202
203 mPolyline->beginCommand( tr( "Change Arrow Head" ), QgsLayoutItem::UndoArrowStrokeWidth );
204 mPolyline->setArrowHeadStrokeWidth( d );
205 mPolyline->endCommand();
206}
207
208void QgsLayoutPolylineWidget::arrowHeadWidthChanged( double d )
209{
210 if ( !mPolyline )
211 return;
212
213 mPolyline->beginCommand( tr( "Change Arrow Width" ), QgsLayoutItem::UndoArrowHeadWidth );
214 mPolyline->setArrowHeadWidth( d );
215 mPolyline->endCommand();
216}
217
218
219void QgsLayoutPolylineWidget::arrowHeadFillColorChanged( const QColor &newColor )
220{
221 if ( !mPolyline )
222 return;
223
224 mPolyline->beginCommand( tr( "Change Arrow Fill Color" ), QgsLayoutItem::UndoArrowHeadFillColor );
225 mPolyline->setArrowHeadFillColor( newColor );
226 mPolyline->endCommand();
227}
228
229
230void QgsLayoutPolylineWidget::arrowHeadStrokeColorChanged( const QColor &newColor )
231{
232 if ( !mPolyline )
233 return;
234
235 mPolyline->beginCommand( tr( "Change Arrow Stroke Color" ), QgsLayoutItem::UndoArrowHeadStrokeColor );
236 mPolyline->setArrowHeadStrokeColor( newColor );
237 mPolyline->endCommand();
238}
239
240
241void QgsLayoutPolylineWidget::startArrowHeadToggled( bool toggled )
242{
243 if ( !mPolyline || !toggled )
244 return;
245
246 mPolyline->beginCommand( tr( "Set Arrow Marker" ) );
247 mPolyline->setStartMarker( QgsLayoutItemPolyline::ArrowHead );
248 mPolyline->endCommand();
249}
250
251void QgsLayoutPolylineWidget::endArrowHeadToggled( bool toggled )
252{
253 if ( !mPolyline || !toggled )
254 return;
255
256 mPolyline->beginCommand( tr( "Set Arrow Marker" ) );
257 mPolyline->setEndMarker( QgsLayoutItemPolyline::ArrowHead );
258 mPolyline->endCommand();
259}
260
261void QgsLayoutPolylineWidget::startNoMarkerToggled( bool toggled )
262{
263 if ( !mPolyline || !toggled )
264 return;
265
266 mPolyline->beginCommand( tr( "Set Line Marker" ) );
267 mPolyline->setStartMarker( QgsLayoutItemPolyline::NoMarker );
268 mPolyline->endCommand();
269}
270
271void QgsLayoutPolylineWidget::endNoMarkerToggled( bool toggled )
272{
273 if ( !mPolyline || !toggled )
274 return;
275
276 mPolyline->beginCommand( tr( "Set Line Marker" ) );
277 mPolyline->setEndMarker( QgsLayoutItemPolyline::NoMarker );
278 mPolyline->endCommand();
279}
280
281void QgsLayoutPolylineWidget::startSvgMarkerToggled( bool toggled )
282{
283 enableStartSvgInputElements( toggled );
284 if ( !mPolyline || !toggled )
285 return;
286
287 mPolyline->beginCommand( tr( "Set SVG Marker" ) );
288 mPolyline->setStartMarker( QgsLayoutItemPolyline::SvgMarker );
289 mPolyline->endCommand();
290}
291
292void QgsLayoutPolylineWidget::endSvgMarkerToggled( bool toggled )
293{
294 enableEndSvgInputElements( toggled );
295 if ( !mPolyline || !toggled )
296 return;
297
298 mPolyline->beginCommand( tr( "Set SVG Marker" ) );
299 mPolyline->setEndMarker( QgsLayoutItemPolyline::SvgMarker );
300 mPolyline->endCommand();
301}
302
303void QgsLayoutPolylineWidget::enableStartSvgInputElements( bool enable )
304{
305 mStartMarkerLineEdit->setEnabled( enable );
306 mStartMarkerToolButton->setEnabled( enable );
307}
308
309void QgsLayoutPolylineWidget::enableEndSvgInputElements( bool enable )
310{
311 mEndMarkerLineEdit->setEnabled( enable );
312 mEndMarkerToolButton->setEnabled( enable );
313}
314
315void QgsLayoutPolylineWidget::mStartMarkerLineEdit_textChanged( const QString &text )
316{
317 if ( !mPolyline )
318 return;
319
320 mPolyline->beginCommand( tr( "Change Start Marker File" ) );
321 const QFileInfo fi( text );
322 if ( fi.exists() && fi.isFile() )
323 {
324 mPolyline->setStartSvgMarkerPath( text );
325 }
326 else
327 {
328 mPolyline->setStartSvgMarkerPath( QString() );
329 }
330 mPolyline->endCommand();
331}
332
333void QgsLayoutPolylineWidget::mEndMarkerLineEdit_textChanged( const QString &text )
334{
335 if ( !mPolyline )
336 return;
337
338 mPolyline->beginCommand( tr( "Change End Marker File" ) );
339 const QFileInfo fi( text );
340 if ( fi.exists() && fi.isFile() )
341 {
342 mPolyline->setEndSvgMarkerPath( text );
343 }
344 else
345 {
346 mPolyline->setEndSvgMarkerPath( QString() );
347 }
348 mPolyline->endCommand();
349}
350
351void QgsLayoutPolylineWidget::mStartMarkerToolButton_clicked()
352{
353 QgsSettings s;
354 QString openDir;
355
356 if ( !mStartMarkerLineEdit->text().isEmpty() )
357 {
358 const QFileInfo fi( mStartMarkerLineEdit->text() );
359 openDir = fi.dir().absolutePath();
360 }
361
362 if ( openDir.isEmpty() )
363 {
364 openDir = s.value( QStringLiteral( "/UI/lastComposerMarkerDir" ), QDir::homePath() ).toString();
365 }
366
367 const QString svgFileName = QFileDialog::getOpenFileName( this, tr( "Start marker svg file" ), openDir );
368 if ( !svgFileName.isNull() )
369 {
370 const QFileInfo fileInfo( svgFileName );
371 s.setValue( QStringLiteral( "/UI/lastComposerMarkerDir" ), fileInfo.absolutePath() );
372 mPolyline->beginCommand( tr( "Change Start Marker File" ) );
373 mStartMarkerLineEdit->setText( svgFileName );
374 mPolyline->endCommand();
375 }
376}
377
378void QgsLayoutPolylineWidget::mEndMarkerToolButton_clicked()
379{
380 QgsSettings s;
381 QString openDir;
382
383 if ( !mEndMarkerLineEdit->text().isEmpty() )
384 {
385 const QFileInfo fi( mEndMarkerLineEdit->text() );
386 openDir = fi.dir().absolutePath();
387 }
388
389 if ( openDir.isEmpty() )
390 {
391 openDir = s.value( QStringLiteral( "/UI/lastComposerMarkerDir" ), QDir::homePath() ).toString();
392 }
393
394 const QString svgFileName = QFileDialog::getOpenFileName( this, tr( "End marker svg file" ), openDir );
395 if ( !svgFileName.isNull() )
396 {
397 const QFileInfo fileInfo( svgFileName );
398 s.setValue( QStringLiteral( "/UI/lastComposerMarkerDir" ), fileInfo.absolutePath() );
399 mPolyline->beginCommand( tr( "Change End Marker File" ) );
400 mEndMarkerLineEdit->setText( svgFileName );
401 mPolyline->endCommand();
402 }
403}
@ Line
Line symbol.
void colorChanged(const QColor &color)
Emitted whenever a new color is set for the button.
A base class for property widgets for layout items.
QgsVectorLayer * coverageLayer() const
Returns the current layout context coverage layer (if set).
Layout item for node based polyline shapes.
@ ArrowHead
Show arrow marker.
@ NoMarker
Don't show marker.
A widget for controlling the common properties of layout items (e.g.
void setMasterLayout(QgsMasterLayoutInterface *masterLayout)
Sets the master layout associated with the item.
void showFrameGroup(bool showGroup)
Determines if the frame of the group box shall be shown.
void setItem(QgsLayoutItem *item)
Sets the layout item.
void showBackgroundGroup(bool showGroup)
Determines if the background of the group box shall be shown.
@ LayoutPolyline
Polyline shape item.
Base class for graphical items within a QgsLayout.
@ UndoArrowHeadStrokeColor
Arrow head stroke color.
@ UndoArrowHeadFillColor
Arrow head fill color.
@ UndoArrowHeadWidth
Arrow head width.
@ UndoArrowStrokeWidth
Arrow stroke width.
@ UndoShapeStyle
Shape symbol style.
int type() const override
Returns a unique graphics item type identifier.
void changed()
Emitted when the object's properties change.
bool setNewItem(QgsLayoutItem *item) override
Attempts to update the widget to show the properties for the specified item.
QgsLayoutPolylineWidget(QgsLayoutItemPolyline *polyline)
constructor
void setMasterLayout(QgsMasterLayoutInterface *masterLayout) override
Sets the master layout associated with the item.
void layerChanged(QgsVectorLayer *layer)
Emitted when the context's layer is changed.
A line symbol type, for rendering LineString and MultiLineString geometries.
Interface for master layout type objects, such as print layouts and reports.
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
This class is a composition of two QSettings instances:
Definition qgssettings.h:64
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
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:5970