QGIS API Documentation 3.99.0-Master (d270888f95f)
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
19#include "qgslayout.h"
22#include "qgslayoutundostack.h"
23#include "qgslinesymbol.h"
24#include "qgsvectorlayer.h"
25
26#include <QButtonGroup>
27#include <QFileDialog>
28#include <QString>
29
30#include "moc_qgslayoutpolylinewidget.cpp"
31
32using namespace Qt::StringLiterals;
33
35 : QgsLayoutItemBaseWidget( nullptr, polyline )
36 , mPolyline( polyline )
37{
38 setupUi( this );
39 setPanelTitle( tr( "Polyline Properties" ) );
40
41 connect( mStrokeWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPolylineWidget::arrowStrokeWidthChanged );
42 connect( mArrowHeadWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPolylineWidget::arrowHeadWidthChanged );
43 connect( mArrowHeadFillColorButton, &QgsColorButton::colorChanged, this, &QgsLayoutPolylineWidget::arrowHeadFillColorChanged );
44 connect( mArrowHeadStrokeColorButton, &QgsColorButton::colorChanged, this, &QgsLayoutPolylineWidget::arrowHeadStrokeColorChanged );
45 connect( mRadioStartArrow, &QRadioButton::toggled, this, &QgsLayoutPolylineWidget::startArrowHeadToggled );
46 connect( mRadioStartNoMarker, &QRadioButton::toggled, this, &QgsLayoutPolylineWidget::startNoMarkerToggled );
47 connect( mRadioStartSVG, &QRadioButton::toggled, this, &QgsLayoutPolylineWidget::startSvgMarkerToggled );
48 connect( mRadioEndArrow, &QRadioButton::toggled, this, &QgsLayoutPolylineWidget::endArrowHeadToggled );
49 connect( mRadioEndNoMarker, &QRadioButton::toggled, this, &QgsLayoutPolylineWidget::endNoMarkerToggled );
50 connect( mRadioEndSvg, &QRadioButton::toggled, this, &QgsLayoutPolylineWidget::endSvgMarkerToggled );
51 connect( mStartMarkerLineEdit, &QLineEdit::textChanged, this, &QgsLayoutPolylineWidget::mStartMarkerLineEdit_textChanged );
52 connect( mEndMarkerLineEdit, &QLineEdit::textChanged, this, &QgsLayoutPolylineWidget::mEndMarkerLineEdit_textChanged );
53 connect( mStartMarkerToolButton, &QToolButton::clicked, this, &QgsLayoutPolylineWidget::mStartMarkerToolButton_clicked );
54 connect( mEndMarkerToolButton, &QToolButton::clicked, this, &QgsLayoutPolylineWidget::mEndMarkerToolButton_clicked );
55 setPanelTitle( tr( "Arrow Properties" ) );
56 QButtonGroup *startMarkerGroup = new QButtonGroup( this );
57 startMarkerGroup->addButton( mRadioStartNoMarker );
58 startMarkerGroup->addButton( mRadioStartArrow );
59 startMarkerGroup->addButton( mRadioStartSVG );
60 startMarkerGroup->setExclusive( true );
61 QButtonGroup *endMarkerGroup = new QButtonGroup( this );
62 endMarkerGroup->addButton( mRadioEndNoMarker );
63 endMarkerGroup->addButton( mRadioEndArrow );
64 endMarkerGroup->addButton( mRadioEndSvg );
65 endMarkerGroup->setExclusive( true );
66
67 //disable the svg related gui elements by default
68 enableStartSvgInputElements( false );
69 enableEndSvgInputElements( false );
70
71 mArrowHeadStrokeColorButton->setColorDialogTitle( tr( "Select Arrow Head Stroke Color" ) );
72 mArrowHeadStrokeColorButton->setAllowOpacity( true );
73 mArrowHeadStrokeColorButton->setContext( u"composer"_s );
74 mArrowHeadStrokeColorButton->setNoColorString( tr( "Transparent Stroke" ) );
75 mArrowHeadStrokeColorButton->setShowNoColor( true );
76 mArrowHeadFillColorButton->setColorDialogTitle( tr( "Select Arrow Head Fill Color" ) );
77 mArrowHeadFillColorButton->setAllowOpacity( true );
78 mArrowHeadFillColorButton->setContext( u"composer"_s );
79 mArrowHeadFillColorButton->setNoColorString( tr( "Transparent Fill" ) );
80 mArrowHeadFillColorButton->setShowNoColor( true );
81
82 //add widget for general composer item properties
83 mItemPropertiesWidget = new QgsLayoutItemPropertiesWidget( this, polyline );
84 //shapes don't use background or frame, since the symbol style is set through a QgsSymbolSelectorWidget
85 mItemPropertiesWidget->showBackgroundGroup( false );
86 mItemPropertiesWidget->showFrameGroup( false );
87 mainLayout->addWidget( mItemPropertiesWidget );
88
89 mLineStyleButton->setSymbolType( Qgis::SymbolType::Line );
90 connect( mLineStyleButton, &QgsSymbolButton::changed, this, &QgsLayoutPolylineWidget::symbolChanged );
91
92 if ( mPolyline )
93 {
94 connect( mPolyline, &QgsLayoutObject::changed, this, &QgsLayoutPolylineWidget::setGuiElementValues );
95 mLineStyleButton->registerExpressionContextGenerator( mPolyline );
96 }
97 setGuiElementValues();
98
99 mLineStyleButton->registerExpressionContextGenerator( mPolyline );
100 mLineStyleButton->setLayer( coverageLayer() );
101 if ( mPolyline->layout() )
102 {
103 connect( &mPolyline->layout()->reportContext(), &QgsLayoutReportContext::layerChanged, mLineStyleButton, &QgsSymbolButton::setLayer );
104 }
105}
106
108{
109 if ( mItemPropertiesWidget )
110 mItemPropertiesWidget->setMasterLayout( masterLayout );
111}
112
114{
116 return false;
117
118 if ( mPolyline )
119 {
120 disconnect( mPolyline, &QgsLayoutObject::changed, this, &QgsLayoutPolylineWidget::setGuiElementValues );
121 }
122
123 mPolyline = qobject_cast<QgsLayoutItemPolyline *>( item );
124 mItemPropertiesWidget->setItem( mPolyline );
125
126 if ( mPolyline )
127 {
128 connect( mPolyline, &QgsLayoutObject::changed, this, &QgsLayoutPolylineWidget::setGuiElementValues );
129 mLineStyleButton->registerExpressionContextGenerator( mPolyline );
130 }
131
132 setGuiElementValues();
133
134 return true;
135}
136
137
138void QgsLayoutPolylineWidget::setGuiElementValues()
139{
140 if ( !mPolyline )
141 return;
142
143 whileBlocking( mLineStyleButton )->setSymbol( mPolyline->symbol()->clone() );
144
145 whileBlocking( mArrowHeadFillColorButton )->setColor( mPolyline->arrowHeadFillColor() );
146 whileBlocking( mArrowHeadStrokeColorButton )->setColor( mPolyline->arrowHeadStrokeColor() );
147 whileBlocking( mStrokeWidthSpinBox )->setValue( mPolyline->arrowHeadStrokeWidth() );
148 whileBlocking( mArrowHeadWidthSpinBox )->setValue( mPolyline->arrowHeadWidth() );
149
150 mRadioStartNoMarker->blockSignals( true );
151 mRadioStartArrow->blockSignals( true );
152 mRadioStartSVG->blockSignals( true );
153 mRadioEndArrow->blockSignals( true );
154 mRadioEndNoMarker->blockSignals( true );
155 mRadioEndSvg->blockSignals( true );
156 switch ( mPolyline->startMarker() )
157 {
159 mRadioStartNoMarker->setChecked( true );
160 break;
162 mRadioStartArrow->setChecked( true );
163 break;
165 mRadioStartSVG->setChecked( true );
166 enableStartSvgInputElements( true );
167 break;
168 }
169 switch ( mPolyline->endMarker() )
170 {
172 mRadioEndNoMarker->setChecked( true );
173 break;
175 mRadioEndArrow->setChecked( true );
176 break;
178 mRadioEndSvg->setChecked( true );
179 enableEndSvgInputElements( true );
180 break;
181 }
182 mRadioStartNoMarker->blockSignals( false );
183 mRadioStartArrow->blockSignals( false );
184 mRadioStartSVG->blockSignals( false );
185 mRadioEndArrow->blockSignals( false );
186 mRadioEndNoMarker->blockSignals( false );
187 mRadioEndSvg->blockSignals( false );
188
189 mStartMarkerLineEdit->setText( mPolyline->startSvgMarkerPath() );
190 mEndMarkerLineEdit->setText( mPolyline->endSvgMarkerPath() );
191}
192
193void QgsLayoutPolylineWidget::symbolChanged()
194{
195 if ( !mPolyline )
196 return;
197
198 mPolyline->layout()->undoStack()->beginCommand( mPolyline, tr( "Change Shape Style" ), QgsLayoutItem::UndoShapeStyle );
199 mPolyline->setSymbol( mLineStyleButton->clonedSymbol<QgsLineSymbol>() );
200 mPolyline->layout()->undoStack()->endCommand();
201}
202
203void QgsLayoutPolylineWidget::arrowStrokeWidthChanged( double d )
204{
205 if ( !mPolyline )
206 return;
207
208 mPolyline->beginCommand( tr( "Change Arrow Head" ), QgsLayoutItem::UndoArrowStrokeWidth );
209 mPolyline->setArrowHeadStrokeWidth( d );
210 mPolyline->endCommand();
211}
212
213void QgsLayoutPolylineWidget::arrowHeadWidthChanged( double d )
214{
215 if ( !mPolyline )
216 return;
217
218 mPolyline->beginCommand( tr( "Change Arrow Width" ), QgsLayoutItem::UndoArrowHeadWidth );
219 mPolyline->setArrowHeadWidth( d );
220 mPolyline->endCommand();
221}
222
223
224void QgsLayoutPolylineWidget::arrowHeadFillColorChanged( const QColor &newColor )
225{
226 if ( !mPolyline )
227 return;
228
229 mPolyline->beginCommand( tr( "Change Arrow Fill Color" ), QgsLayoutItem::UndoArrowHeadFillColor );
230 mPolyline->setArrowHeadFillColor( newColor );
231 mPolyline->endCommand();
232}
233
234
235void QgsLayoutPolylineWidget::arrowHeadStrokeColorChanged( const QColor &newColor )
236{
237 if ( !mPolyline )
238 return;
239
240 mPolyline->beginCommand( tr( "Change Arrow Stroke Color" ), QgsLayoutItem::UndoArrowHeadStrokeColor );
241 mPolyline->setArrowHeadStrokeColor( newColor );
242 mPolyline->endCommand();
243}
244
245
246void QgsLayoutPolylineWidget::startArrowHeadToggled( bool toggled )
247{
248 if ( !mPolyline || !toggled )
249 return;
250
251 mPolyline->beginCommand( tr( "Set Arrow Marker" ) );
252 mPolyline->setStartMarker( QgsLayoutItemPolyline::ArrowHead );
253 mPolyline->endCommand();
254}
255
256void QgsLayoutPolylineWidget::endArrowHeadToggled( bool toggled )
257{
258 if ( !mPolyline || !toggled )
259 return;
260
261 mPolyline->beginCommand( tr( "Set Arrow Marker" ) );
262 mPolyline->setEndMarker( QgsLayoutItemPolyline::ArrowHead );
263 mPolyline->endCommand();
264}
265
266void QgsLayoutPolylineWidget::startNoMarkerToggled( bool toggled )
267{
268 if ( !mPolyline || !toggled )
269 return;
270
271 mPolyline->beginCommand( tr( "Set Line Marker" ) );
272 mPolyline->setStartMarker( QgsLayoutItemPolyline::NoMarker );
273 mPolyline->endCommand();
274}
275
276void QgsLayoutPolylineWidget::endNoMarkerToggled( bool toggled )
277{
278 if ( !mPolyline || !toggled )
279 return;
280
281 mPolyline->beginCommand( tr( "Set Line Marker" ) );
282 mPolyline->setEndMarker( QgsLayoutItemPolyline::NoMarker );
283 mPolyline->endCommand();
284}
285
286void QgsLayoutPolylineWidget::startSvgMarkerToggled( bool toggled )
287{
288 enableStartSvgInputElements( toggled );
289 if ( !mPolyline || !toggled )
290 return;
291
292 mPolyline->beginCommand( tr( "Set SVG Marker" ) );
293 mPolyline->setStartMarker( QgsLayoutItemPolyline::SvgMarker );
294 mPolyline->endCommand();
295}
296
297void QgsLayoutPolylineWidget::endSvgMarkerToggled( bool toggled )
298{
299 enableEndSvgInputElements( toggled );
300 if ( !mPolyline || !toggled )
301 return;
302
303 mPolyline->beginCommand( tr( "Set SVG Marker" ) );
304 mPolyline->setEndMarker( QgsLayoutItemPolyline::SvgMarker );
305 mPolyline->endCommand();
306}
307
308void QgsLayoutPolylineWidget::enableStartSvgInputElements( bool enable )
309{
310 mStartMarkerLineEdit->setEnabled( enable );
311 mStartMarkerToolButton->setEnabled( enable );
312}
313
314void QgsLayoutPolylineWidget::enableEndSvgInputElements( bool enable )
315{
316 mEndMarkerLineEdit->setEnabled( enable );
317 mEndMarkerToolButton->setEnabled( enable );
318}
319
320void QgsLayoutPolylineWidget::mStartMarkerLineEdit_textChanged( const QString &text )
321{
322 if ( !mPolyline )
323 return;
324
325 mPolyline->beginCommand( tr( "Change Start Marker File" ) );
326 const QFileInfo fi( text );
327 if ( fi.exists() && fi.isFile() )
328 {
329 mPolyline->setStartSvgMarkerPath( text );
330 }
331 else
332 {
333 mPolyline->setStartSvgMarkerPath( QString() );
334 }
335 mPolyline->endCommand();
336}
337
338void QgsLayoutPolylineWidget::mEndMarkerLineEdit_textChanged( const QString &text )
339{
340 if ( !mPolyline )
341 return;
342
343 mPolyline->beginCommand( tr( "Change End Marker File" ) );
344 const QFileInfo fi( text );
345 if ( fi.exists() && fi.isFile() )
346 {
347 mPolyline->setEndSvgMarkerPath( text );
348 }
349 else
350 {
351 mPolyline->setEndSvgMarkerPath( QString() );
352 }
353 mPolyline->endCommand();
354}
355
356void QgsLayoutPolylineWidget::mStartMarkerToolButton_clicked()
357{
358 QgsSettings s;
359 QString openDir;
360
361 if ( !mStartMarkerLineEdit->text().isEmpty() )
362 {
363 const QFileInfo fi( mStartMarkerLineEdit->text() );
364 openDir = fi.dir().absolutePath();
365 }
366
367 if ( openDir.isEmpty() )
368 {
369 openDir = s.value( u"/UI/lastComposerMarkerDir"_s, QDir::homePath() ).toString();
370 }
371
372 const QString svgFileName = QFileDialog::getOpenFileName( this, tr( "Start marker svg file" ), openDir );
373 if ( !svgFileName.isNull() )
374 {
375 const QFileInfo fileInfo( svgFileName );
376 s.setValue( u"/UI/lastComposerMarkerDir"_s, fileInfo.absolutePath() );
377 mPolyline->beginCommand( tr( "Change Start Marker File" ) );
378 mStartMarkerLineEdit->setText( svgFileName );
379 mPolyline->endCommand();
380 }
381}
382
383void QgsLayoutPolylineWidget::mEndMarkerToolButton_clicked()
384{
385 QgsSettings s;
386 QString openDir;
387
388 if ( !mEndMarkerLineEdit->text().isEmpty() )
389 {
390 const QFileInfo fi( mEndMarkerLineEdit->text() );
391 openDir = fi.dir().absolutePath();
392 }
393
394 if ( openDir.isEmpty() )
395 {
396 openDir = s.value( u"/UI/lastComposerMarkerDir"_s, QDir::homePath() ).toString();
397 }
398
399 const QString svgFileName = QFileDialog::getOpenFileName( this, tr( "End marker svg file" ), openDir );
400 if ( !svgFileName.isNull() )
401 {
402 const QFileInfo fileInfo( svgFileName );
403 s.setValue( u"/UI/lastComposerMarkerDir"_s, fileInfo.absolutePath() );
404 mPolyline->beginCommand( tr( "Change End Marker File" ) );
405 mEndMarkerLineEdit->setText( svgFileName );
406 mPolyline->endCommand();
407 }
408}
@ Line
Line symbol.
Definition qgis.h:631
void colorChanged(const QColor &color)
Emitted whenever a new color is set for the button.
QgsVectorLayer * coverageLayer() const
Returns the current layout context coverage layer (if set).
QgsLayoutItemBaseWidget(QWidget *parent SIP_TRANSFERTHIS, QgsLayoutObject *layoutObject)
Constructor for QgsLayoutItemBaseWidget, linked with the specified layoutObject.
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.
@ 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.
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.
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:6804