Skip to content
Permalink
Browse files
[FEATURE] Parameterized svg support for composer svg images
This makes it possible to change SVG fill/outline color and outline
width when using parameterised SVG files such as those included
with QGIS (fix #10542)

(cherry-picked from ed3cb12)
  • Loading branch information
nyalldawson committed Mar 20, 2016
1 parent 9542653 commit 0cdfca7d9b48951b6a3b80e6278a9046633246db
@@ -156,6 +156,57 @@ class QgsComposerPicture: QgsComposerItem
*/
ItemPositionMode pictureAnchor() const;

/** Returns the fill color used for parameterized SVG files.
* @see setSvgFillColor()
* @see svgBorderColor()
* @note added in QGIS 2.14.1
*/
QColor svgFillColor() const;

/** Sets the fill color used for parameterized SVG files.
* @param color fill color.
* @note this setting only has an effect on parameterized SVG files, and is ignored for
* non-parameterized SVG files.
* @see svgFillColor()
* @see setSvgBorderColor()
* @note added in QGIS 2.14.1
*/
void setSvgFillColor( const QColor& color );

/** Returns the border color used for parameterized SVG files.
* @see setSvgBorderColor()
* @see svgFillColor()
* @note added in QGIS 2.14.1
*/
QColor svgBorderColor() const;

/** Sets the border color used for parameterized SVG files.
* @param color border color.
* @note this setting only has an effect on parameterized SVG files, and is ignored for
* non-parameterized SVG files.
* @see svgBorderlColor()
* @see setSvgFillColor()
* @note added in QGIS 2.14.1
*/
void setSvgBorderColor( const QColor& color );

/** Returns the border width (in mm) used for parameterized SVG files.
* @see setSvgBorderWidth()
* @see svgBorderColor()
* @note added in QGIS 2.14.1
*/
double svgBorderWidth() const;

/** Sets the border width used for parameterized SVG files.
* @param width border width in mm
* @note this setting only has an effect on parameterized SVG files, and is ignored for
* non-parameterized SVG files.
* @see svgBorderWidth()
* @see setSvgBorderColor()
* @note added in QGIS 2.14.1
*/
void setSvgBorderWidth( double width );

/** Returns whether the picture item is using an expression for the image source.
* @returns true if the picture is using an expression for the source, false if
* it is using a single static file path for the source.
@@ -37,6 +37,13 @@ QgsComposerPictureWidget::QgsComposerPictureWidget( QgsComposerPicture* picture
{
setupUi( this );

mFillColorButton->setAllowAlpha( true );
mFillColorButton->setColorDialogTitle( tr( "Select fill color" ) );
mFillColorButton->setContext( "composer" );
mOutlineColorButton->setAllowAlpha( true );
mOutlineColorButton->setColorDialogTitle( tr( "Select outline color" ) );
mOutlineColorButton->setContext( "composer" );

//add widget for general composer item properties
QgsComposerItemWidget* itemPropertiesWidget = new QgsComposerItemWidget( this, picture );
mainLayout->addWidget( itemPropertiesWidget );
@@ -110,6 +117,7 @@ void QgsComposerPictureWidget::on_mPictureBrowseButton_clicked()
mPictureLineEdit->blockSignals( true );
mPictureLineEdit->setText( filePath );
mPictureLineEdit->blockSignals( false );
updateSvgParamGui();

//pass file path to QgsComposerPicture
if ( mPicture )
@@ -127,13 +135,11 @@ void QgsComposerPictureWidget::on_mPictureLineEdit_editingFinished()
{
QString filePath = mPictureLineEdit->text();

//check if file exists
QFileInfo fileInfo( filePath );

mPicture->beginCommand( tr( "Picture changed" ) );
mPicture->setPicturePath( filePath );
mPicture->update();
mPicture->endCommand();
updateSvgParamGui();
}
}

@@ -161,6 +167,7 @@ void QgsComposerPictureWidget::on_mPreviewListWidget_currentItemChanged( QListWi
mPictureLineEdit->setText( absoluteFilePath );
mPicture->update();
mPicture->endCommand();
updateSvgParamGui();
}

void QgsComposerPictureWidget::on_mAddDirectoryButton_clicked()
@@ -383,6 +390,9 @@ void QgsComposerPictureWidget::setGuiElementValues()
mRotationFromComposerMapCheckBox->blockSignals( true );
mResizeModeComboBox->blockSignals( true );
mAnchorPointComboBox->blockSignals( true );
mFillColorButton->blockSignals( true );
mOutlineColorButton->blockSignals( true );
mOutlineWidthSpinBox->blockSignals( true );

mPictureLineEdit->setText( mPicture->picturePath() );
mPictureRotationSpinBox->setValue( mPicture->pictureRotation() );
@@ -425,12 +435,20 @@ void QgsComposerPictureWidget::setGuiElementValues()
mAnchorPointComboBox->setEnabled( false );
}

updateSvgParamGui( false );
mFillColorButton->setColor( mPicture->svgFillColor() );
mOutlineColorButton->setColor( mPicture->svgBorderColor() );
mOutlineWidthSpinBox->setValue( mPicture->svgBorderWidth() );

mRotationFromComposerMapCheckBox->blockSignals( false );
mPictureRotationSpinBox->blockSignals( false );
mPictureLineEdit->blockSignals( false );
mComposerMapComboBox->blockSignals( false );
mResizeModeComboBox->blockSignals( false );
mAnchorPointComboBox->blockSignals( false );
mFillColorButton->blockSignals( false );
mOutlineColorButton->blockSignals( false );
mOutlineWidthSpinBox->blockSignals( false );

populateDataDefinedButtons();
}
@@ -465,6 +483,64 @@ QIcon QgsComposerPictureWidget::svgToIcon( const QString& filePath ) const
return QIcon( QPixmap::fromImage( img ) );
}

void QgsComposerPictureWidget::updateSvgParamGui( bool resetValues )
{
if ( !mPicture )
return;

QString picturePath = mPicture->picturePath();
if ( !picturePath.endsWith( ".svg", Qt::CaseInsensitive ) )
{
mFillColorButton->setEnabled( false );
mOutlineColorButton->setEnabled( false );
mOutlineWidthSpinBox->setEnabled( false );
return;
}

//activate gui for svg parameters only if supported by the svg file
bool hasFillParam, hasFillOpacityParam, hasOutlineParam, hasOutlineWidthParam, hasOutlineOpacityParam;
QColor defaultFill, defaultOutline;
double defaultOutlineWidth, defaultFillOpacity, defaultOutlineOpacity;
bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultOutlineColor, hasDefaultOutlineWidth, hasDefaultOutlineOpacity;
QgsSvgCache::instance()->containsParams( picturePath, hasFillParam, hasDefaultFillColor, defaultFill,
hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity,
hasOutlineParam, hasDefaultOutlineColor, defaultOutline,
hasOutlineWidthParam, hasDefaultOutlineWidth, defaultOutlineWidth,
hasOutlineOpacityParam, hasDefaultOutlineOpacity, defaultOutlineOpacity );

if ( resetValues )
{
QColor fill = mFillColorButton->color();
double newOpacity = hasFillOpacityParam ? fill.alphaF() : 1.0;
if ( hasDefaultFillColor )
{
fill = defaultFill;
}
fill.setAlphaF( hasDefaultFillOpacity ? defaultFillOpacity : newOpacity );
mFillColorButton->setColor( fill );
}
mFillColorButton->setEnabled( hasFillParam );
mFillColorButton->setAllowAlpha( hasFillOpacityParam );
if ( resetValues )
{
QColor outline = mOutlineColorButton->color();
double newOpacity = hasOutlineOpacityParam ? outline.alphaF() : 1.0;
if ( hasDefaultOutlineColor )
{
outline = defaultOutline;
}
outline.setAlphaF( hasDefaultOutlineOpacity ? defaultOutlineOpacity : newOpacity );
mOutlineColorButton->setColor( outline );
}
mOutlineColorButton->setEnabled( hasOutlineParam );
mOutlineColorButton->setAllowAlpha( hasOutlineOpacityParam );
if ( hasDefaultOutlineWidth && resetValues )
{
mOutlineWidthSpinBox->setValue( defaultOutlineWidth );
}
mOutlineWidthSpinBox->setEnabled( hasOutlineWidthParam );
}

int QgsComposerPictureWidget::addDirectoryToPreview( const QString& path )
{
//go through all files of a directory
@@ -620,6 +696,30 @@ void QgsComposerPictureWidget::loadPicturePreviews( bool collapsed )
}
}

void QgsComposerPictureWidget::on_mFillColorButton_colorChanged( const QColor& color )
{
mPicture->beginCommand( tr( "Picture fill color changed" ) );
mPicture->setSvgFillColor( color );
mPicture->endCommand();
mPicture->update();
}

void QgsComposerPictureWidget::on_mOutlineColorButton_colorChanged( const QColor& color )
{
mPicture->beginCommand( tr( "Picture border color changed" ) );
mPicture->setSvgBorderColor( color );
mPicture->endCommand();
mPicture->update();
}

void QgsComposerPictureWidget::on_mOutlineWidthSpinBox_valueChanged( double d )
{
mPicture->beginCommand( tr( "Picture border width changed" ) );
mPicture->setSvgBorderWidth( d );
mPicture->endCommand();
mPicture->update();
}

void QgsComposerPictureWidget::showEvent( QShowEvent * event )
{
Q_UNUSED( event );
@@ -70,6 +70,10 @@ class QgsComposerPictureWidget: public QgsComposerItemBaseWidget, private Ui::Qg
* @param collapsed Whether the parent group box is collapsed */
void loadPicturePreviews( bool collapsed );

void on_mFillColorButton_colorChanged( const QColor& color );
void on_mOutlineColorButton_colorChanged( const QColor& color );
void on_mOutlineWidthSpinBox_valueChanged( double d );

private:
QgsComposerPicture* mPicture;
/** Whether the picture selection previews have been loaded */
@@ -87,6 +91,8 @@ class QgsComposerPictureWidget: public QgsComposerItemBaseWidget, private Ui::Qg

//! Renders an svg file to a QIcon, correctly handling any SVG parameters present in the file
QIcon svgToIcon( const QString& filePath ) const;

void updateSvgParamGui( bool resetValues = true );
};

#endif

5 comments on commit 0cdfca7

@pka

This comment has been minimized.

Copy link
Member

@pka pka replied Mar 24, 2016

Was this an oversight to add new features in the LTR branch? @jef-n @mhugent

@jef-n

This comment has been minimized.

Copy link
Member

@jef-n jef-n replied Mar 24, 2016

@pka

This comment has been minimized.

Copy link
Member

@pka pka replied Mar 25, 2016

OK, released. Are there any restrictions on features which can be merged in the LTR? Is there a feature freeze deadline for 2.14.2, @jef-n?

@jef-n

This comment has been minimized.

Copy link
Member

@jef-n jef-n replied Mar 25, 2016

No new features should be merged.

@nyalldawson

This comment has been minimized.

Copy link
Collaborator Author

@nyalldawson nyalldawson replied Mar 25, 2016

There was some discussion in #2876 on github and on irc. But this is the only way to solve #10542, and given the severity of that bug it was decided it's better to allow a feature then suffer that bug for all of 2.14.

Please sign in to comment.