30#include <QDoubleValidator>
33#include <QImageReader>
36#include <QProgressDialog>
38#include <QSvgRenderer>
40#include "moc_qgslayoutpicturewidget.cpp"
42using namespace Qt::StringLiterals;
50 mSvgSelectorWidget->setAllowParameters(
true );
51 mSvgSelectorWidget->sourceLineEdit()->setPropertyOverrideToolButtonVisible(
true );
52 mSvgSelectorWidget->sourceLineEdit()->setLastPathSettingsKey( u
"/UI/lastSVGMarkerDir"_s );
71 connect( mPictureRotationSpinBox,
static_cast<void ( QDoubleSpinBox::* )(
double )
>( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutPictureWidget::mPictureRotationSpinBox_valueChanged );
72 connect( mRotationFromComposerMapCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutPictureWidget::mRotationFromComposerMapCheckBox_stateChanged );
73 connect( mResizeModeComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsLayoutPictureWidget::mResizeModeComboBox_currentIndexChanged );
74 connect( mAnchorPointComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsLayoutPictureWidget::mAnchorPointComboBox_currentIndexChanged );
77 connect( mStrokeWidthSpinBox,
static_cast<void ( QDoubleSpinBox::* )(
double )
>( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutPictureWidget::mStrokeWidthSpinBox_valueChanged );
78 connect( mPictureRotationOffsetSpinBox,
static_cast<void ( QDoubleSpinBox::* )(
double )
>( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutPictureWidget::mPictureRotationOffsetSpinBox_valueChanged );
79 connect( mNorthTypeComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsLayoutPictureWidget::mNorthTypeComboBox_currentIndexChanged );
83 connect( mRadioSVG, &QRadioButton::toggled,
this, &QgsLayoutPictureWidget::modeChanged );
84 connect( mRadioRaster, &QRadioButton::toggled,
this, &QgsLayoutPictureWidget::modeChanged );
86 mSvgSelectorWidget->sourceLineEdit()->setLastPathSettingsKey( u
"/UI/lastComposerPictureDir"_s );
90 mFillColorButton->setAllowOpacity(
true );
91 mFillColorButton->setColorDialogTitle( tr(
"Select Fill Color" ) );
92 mFillColorButton->setContext( u
"composer"_s );
93 mStrokeColorButton->setAllowOpacity(
true );
94 mStrokeColorButton->setColorDialogTitle( tr(
"Select Stroke Color" ) );
95 mStrokeColorButton->setContext( u
"composer"_s );
97 mFillColorDDBtn->registerLinkedWidget( mFillColorButton );
98 mStrokeColorDDBtn->registerLinkedWidget( mStrokeColorButton );
100 mNorthTypeComboBox->blockSignals(
true );
103 mNorthTypeComboBox->blockSignals(
false );
104 mPictureRotationOffsetSpinBox->setClearValue( 0.0 );
105 mPictureRotationSpinBox->setClearValue( 0.0 );
109 mainLayout->addWidget( mItemPropertiesWidget );
111 if ( mPicture->layout() )
113 mComposerMapComboBox->setCurrentLayout( mPicture->layout() );
118 setGuiElementValues();
132 if ( mItemPropertiesWidget )
133 mItemPropertiesWidget->setMasterLayout( masterLayout );
136void QgsLayoutPictureWidget::mPictureRotationSpinBox_valueChanged(
double d )
141 mPicture->setPictureRotation( d );
142 mPicture->endCommand();
146void QgsLayoutPictureWidget::mResizeModeComboBox_currentIndexChanged(
int )
153 mPicture->beginCommand( tr(
"Change Resize Mode" ) );
155 mPicture->endCommand();
163 mAnchorPointComboBox->setEnabled(
true );
167 mAnchorPointComboBox->setEnabled(
false );
171void QgsLayoutPictureWidget::mAnchorPointComboBox_currentIndexChanged(
int )
178 mPicture->beginCommand( tr(
"Change Placement" ) );
180 mPicture->endCommand();
194 mPicture = qobject_cast<QgsLayoutItemPicture *>( item );
195 mItemPropertiesWidget->setItem( mPicture );
203 setGuiElementValues();
208void QgsLayoutPictureWidget::mRotationFromComposerMapCheckBox_stateChanged(
int state )
215 mPicture->beginCommand( tr(
"Toggle Rotation Sync" ) );
216 if ( state == Qt::Unchecked )
218 mPicture->setLinkedMap(
nullptr );
219 mPictureRotationSpinBox->setEnabled(
true );
220 mComposerMapComboBox->setEnabled(
false );
221 mNorthTypeComboBox->setEnabled(
false );
222 mPictureRotationOffsetSpinBox->setEnabled(
false );
223 mPicture->setPictureRotation( mPictureRotationSpinBox->value() );
227 QgsLayoutItemMap *map = qobject_cast<QgsLayoutItemMap *>( mComposerMapComboBox->currentItem() );
228 mPicture->setLinkedMap( map );
229 mPictureRotationSpinBox->setEnabled(
false );
230 mNorthTypeComboBox->setEnabled(
true );
231 mPictureRotationOffsetSpinBox->setEnabled(
true );
232 mComposerMapComboBox->setEnabled(
true );
234 mPicture->endCommand();
237void QgsLayoutPictureWidget::mapChanged(
QgsLayoutItem *item )
245 const QgsLayout *layout = mPicture->layout();
251 QgsLayoutItemMap *map = qobject_cast<QgsLayoutItemMap *>( item );
257 mPicture->beginCommand( tr(
"Change Rotation Map" ) );
258 mPicture->setLinkedMap( map );
260 mPicture->endCommand();
263void QgsLayoutPictureWidget::setPicRotationSpinValue(
double r )
265 mPictureRotationSpinBox->blockSignals(
true );
266 mPictureRotationSpinBox->setValue( r );
267 mPictureRotationSpinBox->blockSignals(
false );
270void QgsLayoutPictureWidget::setGuiElementValues()
275 mPictureRotationSpinBox->blockSignals(
true );
276 mComposerMapComboBox->blockSignals(
true );
277 mRotationFromComposerMapCheckBox->blockSignals(
true );
278 mNorthTypeComboBox->blockSignals(
true );
279 mPictureRotationOffsetSpinBox->blockSignals(
true );
280 mResizeModeComboBox->blockSignals(
true );
281 mAnchorPointComboBox->blockSignals(
true );
282 mFillColorButton->blockSignals(
true );
283 mStrokeColorButton->blockSignals(
true );
284 mStrokeWidthSpinBox->blockSignals(
true );
286 mPictureRotationSpinBox->setValue( mPicture->pictureRotation() );
288 mComposerMapComboBox->setItem( mPicture->linkedMap() );
290 if ( mPicture->linkedMap() )
292 mRotationFromComposerMapCheckBox->setCheckState( Qt::Checked );
293 mPictureRotationSpinBox->setEnabled(
false );
294 mComposerMapComboBox->setEnabled(
true );
295 mNorthTypeComboBox->setEnabled(
true );
296 mPictureRotationOffsetSpinBox->setEnabled(
true );
300 mRotationFromComposerMapCheckBox->setCheckState( Qt::Unchecked );
301 mPictureRotationSpinBox->setEnabled(
true );
302 mComposerMapComboBox->setEnabled(
false );
303 mNorthTypeComboBox->setEnabled(
false );
304 mPictureRotationOffsetSpinBox->setEnabled(
false );
306 mNorthTypeComboBox->setCurrentIndex( mNorthTypeComboBox->findData( mPicture->northMode() ) );
307 mPictureRotationOffsetSpinBox->setValue( mPicture->northOffset() );
309 mResizeModeComboBox->setCurrentIndex( mResizeModeComboBox->findData( mPicture->resizeMode() ) );
313 mAnchorPointComboBox->setCurrentIndex( mAnchorPointComboBox->findData( mPicture->pictureAnchor() ) );
317 mAnchorPointComboBox->setEnabled(
true );
321 mAnchorPointComboBox->setEnabled(
false );
324 switch ( mPicture->originalMode() )
328 mRadioSVG->setChecked(
true );
331 mRadioRaster->setChecked(
true );
335 mSvgSelectorWidget->setSvgPath( mPicture->picturePath() );
336 mSvgSelectorWidget->setSvgParameters( mPicture->svgDynamicParameters() );
338 updateSvgParamGui(
false );
339 mFillColorButton->setColor( mPicture->svgFillColor() );
340 mStrokeColorButton->setColor( mPicture->svgStrokeColor() );
341 mStrokeWidthSpinBox->setValue( mPicture->svgStrokeWidth() );
343 mRotationFromComposerMapCheckBox->blockSignals(
false );
344 mPictureRotationSpinBox->blockSignals(
false );
345 mComposerMapComboBox->blockSignals(
false );
346 mNorthTypeComboBox->blockSignals(
false );
347 mPictureRotationOffsetSpinBox->blockSignals(
false );
348 mResizeModeComboBox->blockSignals(
false );
349 mAnchorPointComboBox->blockSignals(
false );
350 mFillColorButton->blockSignals(
false );
351 mStrokeColorButton->blockSignals(
false );
352 mStrokeWidthSpinBox->blockSignals(
false );
358void QgsLayoutPictureWidget::updateSvgParamGui(
bool resetValues )
363 const QString picturePath = mPicture->picturePath();
366 bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
367 QColor defaultFill, defaultStroke;
368 double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
369 bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
370 QgsApplication::svgCache()->
containsParams( picturePath, hasFillParam, hasDefaultFillColor, defaultFill, hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity, hasStrokeParam, hasDefaultStrokeColor, defaultStroke, hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth, hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
374 QColor fill = mFillColorButton->color();
375 const double newOpacity = hasFillOpacityParam ? fill.alphaF() : 1.0;
376 if ( hasDefaultFillColor )
380 fill.setAlphaF( hasDefaultFillOpacity ? defaultFillOpacity : newOpacity );
381 mFillColorButton->setColor( fill );
383 mFillColorButton->setEnabled( hasFillParam );
384 mFillColorDDBtn->setEnabled( hasFillParam );
385 mFillColorButton->setAllowOpacity( hasFillOpacityParam );
388 QColor stroke = mStrokeColorButton->color();
389 const double newOpacity = hasStrokeOpacityParam ? stroke.alphaF() : 1.0;
390 if ( hasDefaultStrokeColor )
392 stroke = defaultStroke;
394 stroke.setAlphaF( hasDefaultStrokeOpacity ? defaultStrokeOpacity : newOpacity );
395 mStrokeColorButton->setColor( stroke );
397 mStrokeColorButton->setEnabled( hasStrokeParam );
398 mStrokeColorDDBtn->setEnabled( hasStrokeParam );
399 mStrokeColorButton->setAllowOpacity( hasStrokeOpacityParam );
400 if ( hasDefaultStrokeWidth && resetValues )
402 mStrokeWidthSpinBox->setValue( defaultStrokeWidth );
404 mStrokeWidthSpinBox->setEnabled( hasStrokeWidthParam );
405 mStrokeWidthDDBtn->setEnabled( hasStrokeWidthParam );
408void QgsLayoutPictureWidget::mFillColorButton_colorChanged(
const QColor &color )
411 mPicture->setSvgFillColor( color );
412 mPicture->endCommand();
416void QgsLayoutPictureWidget::mStrokeColorButton_colorChanged(
const QColor &color )
419 mPicture->setSvgStrokeColor( color );
420 mPicture->endCommand();
424void QgsLayoutPictureWidget::mStrokeWidthSpinBox_valueChanged(
double d )
427 mPicture->setSvgStrokeWidth( d );
428 mPicture->endCommand();
432void QgsLayoutPictureWidget::mPictureRotationOffsetSpinBox_valueChanged(
double d )
435 mPicture->setNorthOffset( d );
436 mPicture->endCommand();
440void QgsLayoutPictureWidget::mNorthTypeComboBox_currentIndexChanged(
int index )
442 mPicture->beginCommand( tr(
"Change Picture North Mode" ) );
444 mPicture->endCommand();
448void QgsLayoutPictureWidget::modeChanged(
bool checked )
453 const bool svg = mRadioSVG->isChecked();
461 mSvgSelectorWidget->setBrowserVisible( svg );
462 mSvgSelectorWidget->setAllowParameters( svg );
463 mSVGParamsGroupBox->setVisible( svg );
465 if ( mPicture && mPicture->mode() != newFormat )
467 mPicture->beginCommand( tr(
"Change Picture Type" ) );
468 mPicture->setMode( newFormat );
469 mPicture->endCommand();
473void QgsLayoutPictureWidget::sourceChanged(
const QString &source )
477 mPicture->beginCommand( tr(
"Change Picture" ) );
480 mPicture->endCommand();
485void QgsLayoutPictureWidget::setSvgDynamicParameters(
const QMap<QString, QgsProperty> ¶meters )
487 mPicture->beginCommand( tr(
"Set SVG parameters" ) );
488 mPicture->setSvgDynamicParameters( parameters );
490 mPicture->endCommand();
PictureFormat
Picture formats.
@ Unknown
Invalid or unknown image type.
static QgsSvgCache * svgCache()
Returns the application's SVG cache, used for caching SVG images and handling parameter replacement w...
void itemChanged(QgsLayoutItem *item)
Emitted whenever the currently selected item changes.
A layout item subclass that displays SVG files or raster format images (jpg, png, ....
void pictureRotationChanged(double newRotation)
Emitted on picture rotation change.
NorthMode
Method for syncing rotation to a map's North direction.
@ GridNorth
Align to grid north.
@ TrueNorth
Align to true north.
ResizeMode
Controls how pictures are scaled within the item's frame.
@ FrameToImageSize
Sets size of frame to match original size of image without scaling.
@ ZoomResizeFrame
Enlarges image to fit frame, then resizes frame to fit resultant image.
@ Clip
Draws image at original size and clips any portion which falls outside frame.
@ Stretch
Stretches image to fit frame, ignores aspect ratio.
@ Zoom
Enlarges image to fit frame while maintaining aspect ratio of picture.
@ LayoutPicture
Picture item.
Base class for graphical items within a QgsLayout.
@ UndoPictureStrokeWidth
Picture stroke width.
@ UndoPictureRotation
Picture rotation.
@ UndoPictureFillColor
Picture fill color.
@ UndoPictureNorthOffset
Picture north offset.
@ UndoPictureStrokeColor
Picture stroke color.
ReferencePoint
Fixed position reference point.
@ LowerMiddle
Lower center of item.
@ MiddleLeft
Middle left of item.
@ UpperRight
Upper right corner of item.
@ LowerLeft
Lower left corner of item.
@ UpperLeft
Upper left corner of item.
@ UpperMiddle
Upper center of item.
@ MiddleRight
Middle right of item.
@ LowerRight
Lower right corner of item.
int type() const override
Returns a unique graphics item type identifier.
void changed()
Emitted when the object's properties change.
@ PictureSvgStrokeColor
SVG stroke color.
@ PictureSvgBackgroundColor
SVG background color.
@ PictureSource
Picture source url.
@ PictureSvgStrokeWidth
SVG stroke width.
Interface for master layout type objects, such as print layouts and reports.
void containsParams(const QString &path, bool &hasFillParam, QColor &defaultFillColor, bool &hasStrokeParam, QColor &defaultStrokeColor, bool &hasStrokeWidthParam, double &defaultStrokeWidth, bool blocking=false) const
Tests if an SVG file contains parameters for fill, stroke color, stroke width.