QGIS API Documentation 4.3.0-Master (0cfde48c85b)
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->setOpaqueColorString( tr( "Opaque Stroke" ) );
76 mArrowHeadStrokeColorButton->setShowNoColor( true );
77 mArrowHeadFillColorButton->setColorDialogTitle( tr( "Select Arrow Head Fill Color" ) );
78 mArrowHeadFillColorButton->setAllowOpacity( true );
79 mArrowHeadFillColorButton->setContext( u"composer"_s );
80 mArrowHeadFillColorButton->setNoColorString( tr( "Transparent Fill" ) );
81 mArrowHeadFillColorButton->setOpaqueColorString( tr( "Opaque Fill" ) );
82 mArrowHeadFillColorButton->setShowNoColor( true );
83
84 //add widget for general composer item properties
85 mItemPropertiesWidget = new QgsLayoutItemPropertiesWidget( this, polyline );
86 //shapes don't use background or frame, since the symbol style is set through a QgsSymbolSelectorWidget
87 mItemPropertiesWidget->showBackgroundGroup( false );
88 mItemPropertiesWidget->showFrameGroup( false );
89 mainLayout->addWidget( mItemPropertiesWidget );
90
91 mLineStyleButton->setSymbolType( Qgis::SymbolType::Line );
92 connect( mLineStyleButton, &QgsSymbolButton::changed, this, &QgsLayoutPolylineWidget::symbolChanged );
93
94 if ( mPolyline )
95 {
96 connect( mPolyline, &QgsLayoutObject::changed, this, &QgsLayoutPolylineWidget::setGuiElementValues );
97 mLineStyleButton->registerExpressionContextGenerator( mPolyline );
98 }
99 setGuiElementValues();
100
101 mLineStyleButton->registerExpressionContextGenerator( mPolyline );
102 mLineStyleButton->setLayer( coverageLayer() );
103 if ( mPolyline->layout() )
104 {
105 connect( &mPolyline->layout()->reportContext(), &QgsLayoutReportContext::layerChanged, mLineStyleButton, &QgsSymbolButton::setLayer );
106 }
107}
108
110{
111 if ( mItemPropertiesWidget )
112 mItemPropertiesWidget->setMasterLayout( masterLayout );
113}
114
116{
118 return false;
119
120 if ( mPolyline )
121 {
122 disconnect( mPolyline, &QgsLayoutObject::changed, this, &QgsLayoutPolylineWidget::setGuiElementValues );
123 }
124
125 mPolyline = qobject_cast<QgsLayoutItemPolyline *>( item );
126 mItemPropertiesWidget->setItem( mPolyline );
127
128 if ( mPolyline )
129 {
130 connect( mPolyline, &QgsLayoutObject::changed, this, &QgsLayoutPolylineWidget::setGuiElementValues );
131 mLineStyleButton->registerExpressionContextGenerator( mPolyline );
132 }
133
134 setGuiElementValues();
135
136 return true;
137}
138
139
140void QgsLayoutPolylineWidget::setGuiElementValues()
141{
142 if ( !mPolyline )
143 return;
144
145 whileBlocking( mLineStyleButton )->setSymbol( mPolyline->symbol()->clone() );
146
147 whileBlocking( mArrowHeadFillColorButton )->setColor( mPolyline->arrowHeadFillColor() );
148 whileBlocking( mArrowHeadStrokeColorButton )->setColor( mPolyline->arrowHeadStrokeColor() );
149 whileBlocking( mStrokeWidthSpinBox )->setValue( mPolyline->arrowHeadStrokeWidth() );
150 whileBlocking( mArrowHeadWidthSpinBox )->setValue( mPolyline->arrowHeadWidth() );
151
152 mRadioStartNoMarker->blockSignals( true );
153 mRadioStartArrow->blockSignals( true );
154 mRadioStartSVG->blockSignals( true );
155 mRadioEndArrow->blockSignals( true );
156 mRadioEndNoMarker->blockSignals( true );
157 mRadioEndSvg->blockSignals( true );
158 switch ( mPolyline->startMarker() )
159 {
161 mRadioStartNoMarker->setChecked( true );
162 break;
164 mRadioStartArrow->setChecked( true );
165 break;
167 mRadioStartSVG->setChecked( true );
168 enableStartSvgInputElements( true );
169 break;
170 }
171 switch ( mPolyline->endMarker() )
172 {
174 mRadioEndNoMarker->setChecked( true );
175 break;
177 mRadioEndArrow->setChecked( true );
178 break;
180 mRadioEndSvg->setChecked( true );
181 enableEndSvgInputElements( true );
182 break;
183 }
184 mRadioStartNoMarker->blockSignals( false );
185 mRadioStartArrow->blockSignals( false );
186 mRadioStartSVG->blockSignals( false );
187 mRadioEndArrow->blockSignals( false );
188 mRadioEndNoMarker->blockSignals( false );
189 mRadioEndSvg->blockSignals( false );
190
191 mStartMarkerLineEdit->setText( mPolyline->startSvgMarkerPath() );
192 mEndMarkerLineEdit->setText( mPolyline->endSvgMarkerPath() );
193}
194
195void QgsLayoutPolylineWidget::symbolChanged()
196{
197 if ( !mPolyline )
198 return;
199
200 mPolyline->layout()->undoStack()->beginCommand( mPolyline, tr( "Change Shape Style" ), QgsLayoutItem::UndoShapeStyle );
201 mPolyline->setSymbol( mLineStyleButton->clonedSymbol<QgsLineSymbol>() );
202 mPolyline->layout()->undoStack()->endCommand();
203}
204
205void QgsLayoutPolylineWidget::arrowStrokeWidthChanged( double d )
206{
207 if ( !mPolyline )
208 return;
209
210 mPolyline->beginCommand( tr( "Change Arrow Head" ), QgsLayoutItem::UndoArrowStrokeWidth );
211 mPolyline->setArrowHeadStrokeWidth( d );
212 mPolyline->endCommand();
213}
214
215void QgsLayoutPolylineWidget::arrowHeadWidthChanged( double d )
216{
217 if ( !mPolyline )
218 return;
219
220 mPolyline->beginCommand( tr( "Change Arrow Width" ), QgsLayoutItem::UndoArrowHeadWidth );
221 mPolyline->setArrowHeadWidth( d );
222 mPolyline->endCommand();
223}
224
225
226void QgsLayoutPolylineWidget::arrowHeadFillColorChanged( const QColor &newColor )
227{
228 if ( !mPolyline )
229 return;
230
231 mPolyline->beginCommand( tr( "Change Arrow Fill Color" ), QgsLayoutItem::UndoArrowHeadFillColor );
232 mPolyline->setArrowHeadFillColor( newColor );
233 mPolyline->endCommand();
234}
235
236
237void QgsLayoutPolylineWidget::arrowHeadStrokeColorChanged( const QColor &newColor )
238{
239 if ( !mPolyline )
240 return;
241
242 mPolyline->beginCommand( tr( "Change Arrow Stroke Color" ), QgsLayoutItem::UndoArrowHeadStrokeColor );
243 mPolyline->setArrowHeadStrokeColor( newColor );
244 mPolyline->endCommand();
245}
246
247
248void QgsLayoutPolylineWidget::startArrowHeadToggled( bool toggled )
249{
250 if ( !mPolyline || !toggled )
251 return;
252
253 mPolyline->beginCommand( tr( "Set Arrow Marker" ) );
254 mPolyline->setStartMarker( QgsLayoutItemPolyline::ArrowHead );
255 mPolyline->endCommand();
256}
257
258void QgsLayoutPolylineWidget::endArrowHeadToggled( bool toggled )
259{
260 if ( !mPolyline || !toggled )
261 return;
262
263 mPolyline->beginCommand( tr( "Set Arrow Marker" ) );
264 mPolyline->setEndMarker( QgsLayoutItemPolyline::ArrowHead );
265 mPolyline->endCommand();
266}
267
268void QgsLayoutPolylineWidget::startNoMarkerToggled( bool toggled )
269{
270 if ( !mPolyline || !toggled )
271 return;
272
273 mPolyline->beginCommand( tr( "Set Line Marker" ) );
274 mPolyline->setStartMarker( QgsLayoutItemPolyline::NoMarker );
275 mPolyline->endCommand();
276}
277
278void QgsLayoutPolylineWidget::endNoMarkerToggled( bool toggled )
279{
280 if ( !mPolyline || !toggled )
281 return;
282
283 mPolyline->beginCommand( tr( "Set Line Marker" ) );
284 mPolyline->setEndMarker( QgsLayoutItemPolyline::NoMarker );
285 mPolyline->endCommand();
286}
287
288void QgsLayoutPolylineWidget::startSvgMarkerToggled( bool toggled )
289{
290 enableStartSvgInputElements( toggled );
291 if ( !mPolyline || !toggled )
292 return;
293
294 mPolyline->beginCommand( tr( "Set SVG Marker" ) );
295 mPolyline->setStartMarker( QgsLayoutItemPolyline::SvgMarker );
296 mPolyline->endCommand();
297}
298
299void QgsLayoutPolylineWidget::endSvgMarkerToggled( bool toggled )
300{
301 enableEndSvgInputElements( toggled );
302 if ( !mPolyline || !toggled )
303 return;
304
305 mPolyline->beginCommand( tr( "Set SVG Marker" ) );
306 mPolyline->setEndMarker( QgsLayoutItemPolyline::SvgMarker );
307 mPolyline->endCommand();
308}
309
310void QgsLayoutPolylineWidget::enableStartSvgInputElements( bool enable )
311{
312 mStartMarkerLineEdit->setEnabled( enable );
313 mStartMarkerToolButton->setEnabled( enable );
314}
315
316void QgsLayoutPolylineWidget::enableEndSvgInputElements( bool enable )
317{
318 mEndMarkerLineEdit->setEnabled( enable );
319 mEndMarkerToolButton->setEnabled( enable );
320}
321
322void QgsLayoutPolylineWidget::mStartMarkerLineEdit_textChanged( const QString &text )
323{
324 if ( !mPolyline )
325 return;
326
327 mPolyline->beginCommand( tr( "Change Start Marker File" ) );
328 const QFileInfo fi( text );
329 if ( fi.exists() && fi.isFile() )
330 {
331 mPolyline->setStartSvgMarkerPath( text );
332 }
333 else
334 {
335 mPolyline->setStartSvgMarkerPath( QString() );
336 }
337 mPolyline->endCommand();
338}
339
340void QgsLayoutPolylineWidget::mEndMarkerLineEdit_textChanged( const QString &text )
341{
342 if ( !mPolyline )
343 return;
344
345 mPolyline->beginCommand( tr( "Change End Marker File" ) );
346 const QFileInfo fi( text );
347 if ( fi.exists() && fi.isFile() )
348 {
349 mPolyline->setEndSvgMarkerPath( text );
350 }
351 else
352 {
353 mPolyline->setEndSvgMarkerPath( QString() );
354 }
355 mPolyline->endCommand();
356}
357
358void QgsLayoutPolylineWidget::mStartMarkerToolButton_clicked()
359{
360 QgsSettings s;
361 QString openDir;
362
363 if ( !mStartMarkerLineEdit->text().isEmpty() )
364 {
365 const QFileInfo fi( mStartMarkerLineEdit->text() );
366 openDir = fi.dir().absolutePath();
367 }
368
369 if ( openDir.isEmpty() )
370 {
371 openDir = s.value( u"/UI/lastComposerMarkerDir"_s, QDir::homePath() ).toString();
372 }
373
374 const QString svgFileName = QFileDialog::getOpenFileName( this, tr( "Start marker svg file" ), openDir );
375 if ( !svgFileName.isNull() )
376 {
377 const QFileInfo fileInfo( svgFileName );
378 s.setValue( u"/UI/lastComposerMarkerDir"_s, fileInfo.absolutePath() );
379 mPolyline->beginCommand( tr( "Change Start Marker File" ) );
380 mStartMarkerLineEdit->setText( svgFileName );
381 mPolyline->endCommand();
382 }
383}
384
385void QgsLayoutPolylineWidget::mEndMarkerToolButton_clicked()
386{
387 QgsSettings s;
388 QString openDir;
389
390 if ( !mEndMarkerLineEdit->text().isEmpty() )
391 {
392 const QFileInfo fi( mEndMarkerLineEdit->text() );
393 openDir = fi.dir().absolutePath();
394 }
395
396 if ( openDir.isEmpty() )
397 {
398 openDir = s.value( u"/UI/lastComposerMarkerDir"_s, QDir::homePath() ).toString();
399 }
400
401 const QString svgFileName = QFileDialog::getOpenFileName( this, tr( "End marker svg file" ), openDir );
402 if ( !svgFileName.isNull() )
403 {
404 const QFileInfo fileInfo( svgFileName );
405 s.setValue( u"/UI/lastComposerMarkerDir"_s, fileInfo.absolutePath() );
406 mPolyline->beginCommand( tr( "Change End Marker File" ) );
407 mEndMarkerLineEdit->setText( svgFileName );
408 mPolyline->endCommand();
409 }
410}
@ Line
Line symbol.
Definition qgis.h:673
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:7619