Skip to content

Commit

Permalink
[FEATURE] Parameterized svg support for composer svg images
Browse files Browse the repository at this point in the history
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 0cdfca7
Show file tree
Hide file tree
Showing 9 changed files with 519 additions and 56 deletions.
51 changes: 51 additions & 0 deletions python/core/composer/qgscomposerpicture.sip
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
106 changes: 103 additions & 3 deletions src/app/composer/qgscomposerpicturewidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
Expand Down Expand Up @@ -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 )
Expand All @@ -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();
}
}

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

void QgsComposerPictureWidget::on_mAddDirectoryButton_clicked()
Expand Down Expand Up @@ -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() );
Expand Down Expand Up @@ -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();
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 );
Expand Down
6 changes: 6 additions & 0 deletions src/app/composer/qgscomposerpicturewidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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
Loading

5 comments on commit 0cdfca7

@pka
Copy link
Member

@pka pka commented on 0cdfca7 Mar 24, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@jef-n
Copy link
Member

@jef-n jef-n commented on 0cdfca7 Mar 24, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pka
Copy link
Member

@pka pka commented on 0cdfca7 Mar 25, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Member

@jef-n jef-n commented on 0cdfca7 Mar 25, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No new features should be merged.

@nyalldawson
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.