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