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 mClipItemComboBox->setCurrentLayout( picture->
layout() );
74 connect( mPictureRotationSpinBox,
static_cast<void ( QDoubleSpinBox::* )(
double )
>( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutPictureWidget::mPictureRotationSpinBox_valueChanged );
75 connect( mRotationFromComposerMapCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutPictureWidget::mRotationFromComposerMapCheckBox_stateChanged );
76 connect( mResizeModeComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsLayoutPictureWidget::mResizeModeComboBox_currentIndexChanged );
77 connect( mAnchorPointComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsLayoutPictureWidget::mAnchorPointComboBox_currentIndexChanged );
80 connect( mStrokeWidthSpinBox,
static_cast<void ( QDoubleSpinBox::* )(
double )
>( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutPictureWidget::mStrokeWidthSpinBox_valueChanged );
81 connect( mPictureRotationOffsetSpinBox,
static_cast<void ( QDoubleSpinBox::* )(
double )
>( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutPictureWidget::mPictureRotationOffsetSpinBox_valueChanged );
82 connect( mNorthTypeComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsLayoutPictureWidget::mNorthTypeComboBox_currentIndexChanged );
86 connect( mRadioSVG, &QRadioButton::toggled,
this, &QgsLayoutPictureWidget::modeChanged );
87 connect( mRadioRaster, &QRadioButton::toggled,
this, &QgsLayoutPictureWidget::modeChanged );
89 connect( mClipToItemCheckBox, &QGroupBox::toggled,
this, [
this](
bool active ) {
90 mPicture->beginCommand( tr(
"Toggle Picture Clipping" ) );
91 mPicture->setClipToItem( active );
92 mPicture->endCommand();
96 mPicture->beginCommand( tr(
"Change Picture Clipping Item" ) );
97 mPicture->setClippingItem( item );
98 mPicture->endCommand();
101 mSvgSelectorWidget->sourceLineEdit()->setLastPathSettingsKey( u
"/UI/lastComposerPictureDir"_s );
105 mFillColorButton->setAllowOpacity(
true );
106 mFillColorButton->setColorDialogTitle( tr(
"Select Fill Color" ) );
107 mFillColorButton->setContext( u
"composer"_s );
108 mStrokeColorButton->setAllowOpacity(
true );
109 mStrokeColorButton->setColorDialogTitle( tr(
"Select Stroke Color" ) );
110 mStrokeColorButton->setContext( u
"composer"_s );
112 mFillColorDDBtn->registerLinkedWidget( mFillColorButton );
113 mStrokeColorDDBtn->registerLinkedWidget( mStrokeColorButton );
115 mNorthTypeComboBox->blockSignals(
true );
118 mNorthTypeComboBox->blockSignals(
false );
119 mPictureRotationOffsetSpinBox->setClearValue( 0.0 );
120 mPictureRotationSpinBox->setClearValue( 0.0 );
124 mainLayout->addWidget( mItemPropertiesWidget );
126 if ( mPicture->layout() )
128 mComposerMapComboBox->setCurrentLayout( mPicture->layout() );
133 setGuiElementValues();
147 if ( mItemPropertiesWidget )
148 mItemPropertiesWidget->setMasterLayout( masterLayout );
151void QgsLayoutPictureWidget::mPictureRotationSpinBox_valueChanged(
double d )
156 mPicture->setPictureRotation( d );
157 mPicture->endCommand();
161void QgsLayoutPictureWidget::mResizeModeComboBox_currentIndexChanged(
int )
168 mPicture->beginCommand( tr(
"Change Resize Mode" ) );
170 mPicture->endCommand();
178 mAnchorPointComboBox->setEnabled(
true );
182 mAnchorPointComboBox->setEnabled(
false );
186void QgsLayoutPictureWidget::mAnchorPointComboBox_currentIndexChanged(
int )
193 mPicture->beginCommand( tr(
"Change Placement" ) );
195 mPicture->endCommand();
209 mPicture = qobject_cast<QgsLayoutItemPicture *>( item );
210 mItemPropertiesWidget->setItem( mPicture );
218 setGuiElementValues();
223void QgsLayoutPictureWidget::mRotationFromComposerMapCheckBox_stateChanged(
int state )
230 mPicture->beginCommand( tr(
"Toggle Rotation Sync" ) );
231 if ( state == Qt::Unchecked )
233 mPicture->setLinkedMap(
nullptr );
234 mPictureRotationSpinBox->setEnabled(
true );
235 mComposerMapComboBox->setEnabled(
false );
236 mNorthTypeComboBox->setEnabled(
false );
237 mPictureRotationOffsetSpinBox->setEnabled(
false );
238 mPicture->setPictureRotation( mPictureRotationSpinBox->value() );
242 QgsLayoutItemMap *map = qobject_cast<QgsLayoutItemMap *>( mComposerMapComboBox->currentItem() );
243 mPicture->setLinkedMap( map );
244 mPictureRotationSpinBox->setEnabled(
false );
245 mNorthTypeComboBox->setEnabled(
true );
246 mPictureRotationOffsetSpinBox->setEnabled(
true );
247 mComposerMapComboBox->setEnabled(
true );
249 mPicture->endCommand();
252void QgsLayoutPictureWidget::mapChanged(
QgsLayoutItem *item )
260 const QgsLayout *layout = mPicture->layout();
266 QgsLayoutItemMap *map = qobject_cast<QgsLayoutItemMap *>( item );
272 mPicture->beginCommand( tr(
"Change Rotation Map" ) );
273 mPicture->setLinkedMap( map );
275 mPicture->endCommand();
278void QgsLayoutPictureWidget::setPicRotationSpinValue(
double r )
280 mPictureRotationSpinBox->blockSignals(
true );
281 mPictureRotationSpinBox->setValue( r );
282 mPictureRotationSpinBox->blockSignals(
false );
285void QgsLayoutPictureWidget::setGuiElementValues()
290 mPictureRotationSpinBox->blockSignals(
true );
291 mComposerMapComboBox->blockSignals(
true );
292 mRotationFromComposerMapCheckBox->blockSignals(
true );
293 mNorthTypeComboBox->blockSignals(
true );
294 mPictureRotationOffsetSpinBox->blockSignals(
true );
295 mResizeModeComboBox->blockSignals(
true );
296 mAnchorPointComboBox->blockSignals(
true );
297 mFillColorButton->blockSignals(
true );
298 mStrokeColorButton->blockSignals(
true );
299 mStrokeWidthSpinBox->blockSignals(
true );
300 mClipToItemCheckBox->blockSignals(
true );
301 mClipItemComboBox->blockSignals(
true );
303 mPictureRotationSpinBox->setValue( mPicture->pictureRotation() );
305 mComposerMapComboBox->setItem( mPicture->linkedMap() );
307 if ( mPicture->linkedMap() )
309 mRotationFromComposerMapCheckBox->setCheckState( Qt::Checked );
310 mPictureRotationSpinBox->setEnabled(
false );
311 mComposerMapComboBox->setEnabled(
true );
312 mNorthTypeComboBox->setEnabled(
true );
313 mPictureRotationOffsetSpinBox->setEnabled(
true );
317 mRotationFromComposerMapCheckBox->setCheckState( Qt::Unchecked );
318 mPictureRotationSpinBox->setEnabled(
true );
319 mComposerMapComboBox->setEnabled(
false );
320 mNorthTypeComboBox->setEnabled(
false );
321 mPictureRotationOffsetSpinBox->setEnabled(
false );
323 mNorthTypeComboBox->setCurrentIndex( mNorthTypeComboBox->findData( mPicture->northMode() ) );
324 mPictureRotationOffsetSpinBox->setValue( mPicture->northOffset() );
326 mResizeModeComboBox->setCurrentIndex( mResizeModeComboBox->findData( mPicture->resizeMode() ) );
330 mAnchorPointComboBox->setCurrentIndex( mAnchorPointComboBox->findData( mPicture->pictureAnchor() ) );
334 mAnchorPointComboBox->setEnabled(
true );
338 mAnchorPointComboBox->setEnabled(
false );
341 switch ( mPicture->originalMode() )
345 mRadioSVG->setChecked(
true );
348 mRadioRaster->setChecked(
true );
352 mSvgSelectorWidget->setSvgPath( mPicture->picturePath() );
353 mSvgSelectorWidget->setSvgParameters( mPicture->svgDynamicParameters() );
355 updateSvgParamGui(
false );
356 mFillColorButton->setColor( mPicture->svgFillColor() );
357 mStrokeColorButton->setColor( mPicture->svgStrokeColor() );
358 mStrokeWidthSpinBox->setValue( mPicture->svgStrokeWidth() );
360 mClipToItemCheckBox->setChecked( mPicture->clipToItem() );
361 mClipItemComboBox->setItem( mPicture->clippingItem() );
363 mRotationFromComposerMapCheckBox->blockSignals(
false );
364 mPictureRotationSpinBox->blockSignals(
false );
365 mComposerMapComboBox->blockSignals(
false );
366 mNorthTypeComboBox->blockSignals(
false );
367 mPictureRotationOffsetSpinBox->blockSignals(
false );
368 mResizeModeComboBox->blockSignals(
false );
369 mAnchorPointComboBox->blockSignals(
false );
370 mFillColorButton->blockSignals(
false );
371 mStrokeColorButton->blockSignals(
false );
372 mStrokeWidthSpinBox->blockSignals(
false );
373 mClipToItemCheckBox->blockSignals(
false );
374 mClipItemComboBox->blockSignals(
false );
380void QgsLayoutPictureWidget::updateSvgParamGui(
bool resetValues )
385 const QString picturePath = mPicture->picturePath();
388 bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
389 QColor defaultFill, defaultStroke;
390 double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
391 bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
398 hasDefaultFillOpacity,
401 hasDefaultStrokeColor,
404 hasDefaultStrokeWidth,
406 hasStrokeOpacityParam,
407 hasDefaultStrokeOpacity,
413 QColor fill = mFillColorButton->color();
414 const double newOpacity = hasFillOpacityParam ? fill.alphaF() : 1.0;
415 if ( hasDefaultFillColor )
419 fill.setAlphaF( hasDefaultFillOpacity ? defaultFillOpacity : newOpacity );
420 mFillColorButton->setColor( fill );
422 mFillColorButton->setEnabled( hasFillParam );
423 mFillColorDDBtn->setEnabled( hasFillParam );
424 mFillColorButton->setAllowOpacity( hasFillOpacityParam );
427 QColor stroke = mStrokeColorButton->color();
428 const double newOpacity = hasStrokeOpacityParam ? stroke.alphaF() : 1.0;
429 if ( hasDefaultStrokeColor )
431 stroke = defaultStroke;
433 stroke.setAlphaF( hasDefaultStrokeOpacity ? defaultStrokeOpacity : newOpacity );
434 mStrokeColorButton->setColor( stroke );
436 mStrokeColorButton->setEnabled( hasStrokeParam );
437 mStrokeColorDDBtn->setEnabled( hasStrokeParam );
438 mStrokeColorButton->setAllowOpacity( hasStrokeOpacityParam );
439 if ( hasDefaultStrokeWidth && resetValues )
441 mStrokeWidthSpinBox->setValue( defaultStrokeWidth );
443 mStrokeWidthSpinBox->setEnabled( hasStrokeWidthParam );
444 mStrokeWidthDDBtn->setEnabled( hasStrokeWidthParam );
447void QgsLayoutPictureWidget::mFillColorButton_colorChanged(
const QColor &color )
450 mPicture->setSvgFillColor( color );
451 mPicture->endCommand();
455void QgsLayoutPictureWidget::mStrokeColorButton_colorChanged(
const QColor &color )
458 mPicture->setSvgStrokeColor( color );
459 mPicture->endCommand();
463void QgsLayoutPictureWidget::mStrokeWidthSpinBox_valueChanged(
double d )
466 mPicture->setSvgStrokeWidth( d );
467 mPicture->endCommand();
471void QgsLayoutPictureWidget::mPictureRotationOffsetSpinBox_valueChanged(
double d )
474 mPicture->setNorthOffset( d );
475 mPicture->endCommand();
479void QgsLayoutPictureWidget::mNorthTypeComboBox_currentIndexChanged(
int index )
481 mPicture->beginCommand( tr(
"Change Picture North Mode" ) );
483 mPicture->endCommand();
487void QgsLayoutPictureWidget::modeChanged(
bool checked )
492 const bool svg = mRadioSVG->isChecked();
500 mSvgSelectorWidget->setBrowserVisible( svg );
501 mSvgSelectorWidget->setAllowParameters( svg );
502 mSVGParamsGroupBox->setVisible( svg );
504 if ( mPicture && mPicture->mode() != newFormat )
506 mPicture->beginCommand( tr(
"Change Picture Type" ) );
507 mPicture->setMode( newFormat );
508 mPicture->endCommand();
512void QgsLayoutPictureWidget::sourceChanged(
const QString &source )
516 mPicture->beginCommand( tr(
"Change Picture" ) );
519 mPicture->endCommand();
524void QgsLayoutPictureWidget::setSvgDynamicParameters(
const QMap<QString, QgsProperty> ¶meters )
526 mPicture->beginCommand( tr(
"Set SVG parameters" ) );
527 mPicture->setSvgDynamicParameters( parameters );
529 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.
@ FlagProvidesClipPath
Item can act as a clipping path provider (see clipPath()).
const QgsLayout * layout() const
Returns the layout the object is attached to.
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.