Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[composer] Set base stylesheet of composer labels to match the
label font and margins when rendering as HTML.

This allows interactive choice of font, margins and colors and
avoids the need to manually set these with CSS within the
label HTML code.
  • Loading branch information
nyalldawson committed Mar 30, 2016
1 parent 6526cf5 commit 9104704
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 13 deletions.
1 change: 1 addition & 0 deletions ci/travis/linux/qt5/blacklist.txt
Expand Up @@ -74,6 +74,7 @@ PyQgsZonalStatistics
qgis_alignrastertest
qgis_atlascompositiontest
qgis_composereffectstest
qgis_composerlabeltest
qgis_composermapgridtest
qgis_composermapoverviewtest
qgis_composermaptest
Expand Down
23 changes: 11 additions & 12 deletions src/app/composer/qgscomposerlabelwidget.cpp
Expand Up @@ -50,18 +50,10 @@ void QgsComposerLabelWidget::on_mHtmlCheckBox_stateChanged( int state )
{
if ( mComposerLabel )
{
if ( state )
{
mFontButton->setEnabled( false );
mFontColorButton->setEnabled( false );
mAppearanceGroup->setEnabled( false );
}
else
{
mFontButton->setEnabled( true );
mFontColorButton->setEnabled( true );
mAppearanceGroup->setEnabled( true );
}
mVerticalAlignementLabel->setDisabled( state );
mTopRadioButton->setDisabled( state );
mMiddleRadioButton->setDisabled( state );
mBottomRadioButton->setDisabled( state );

mComposerLabel->beginCommand( tr( "Label text HTML state changed" ), QgsComposerMergeCommand::ComposerLabelSetText );
mComposerLabel->blockSignals( true );
Expand Down Expand Up @@ -249,6 +241,13 @@ void QgsComposerLabelWidget::setGuiElementValues()
mCenterRadioButton->setChecked( mComposerLabel->hAlign() == Qt::AlignHCenter );
mRightRadioButton->setChecked( mComposerLabel->hAlign() == Qt::AlignRight );
mFontColorButton->setColor( mComposerLabel->fontColor() );


mVerticalAlignementLabel->setDisabled( mComposerLabel->htmlState() );
mTopRadioButton->setDisabled( mComposerLabel->htmlState() );
mMiddleRadioButton->setDisabled( mComposerLabel->htmlState() );
mBottomRadioButton->setDisabled( mComposerLabel->htmlState() );

blockAllSignals( false );
}

Expand Down
16 changes: 16 additions & 0 deletions src/core/composer/qgscomposerlabel.cpp
Expand Up @@ -133,6 +133,7 @@ void QgsComposerLabel::paint( QPainter* painter, const QStyleOptionGraphicsItem*
webPage->mainFrame()->setZoomFactor( 10.0 );
webPage->mainFrame()->setScrollBarPolicy( Qt::Horizontal, Qt::ScrollBarAlwaysOff );
webPage->mainFrame()->setScrollBarPolicy( Qt::Vertical, Qt::ScrollBarAlwaysOff );
webPage->settings()->setUserStyleSheetUrl( createStylesheetUrl() );

// QGIS segfaults when rendering web page while in composer if html
// contains images. So if we are not printing the composition, then
Expand Down Expand Up @@ -633,3 +634,18 @@ void QgsComposerLabel::itemShiftAdjustSize( double newWidth, double newHeight, d
}
}
}

QUrl QgsComposerLabel::createStylesheetUrl() const
{
QString stylesheet;
stylesheet += QString( "body { margin: %1 %2;" ).arg( qMax( mMarginX * mHtmlUnitsToMM, 0.0 ) ).arg( qMax( mMarginY * mHtmlUnitsToMM, 0.0 ) );
stylesheet += QgsFontUtils::asCSS( mFont, 0.352778 * mHtmlUnitsToMM );
stylesheet += QString( "color: %1;" ).arg( mFontColor.name() );
stylesheet += QString( "text-align: %1; }" ).arg( mHAlignment == Qt::AlignLeft ? "left" : mHAlignment == Qt::AlignRight ? "right" : "center" );

QByteArray ba;
ba.append( stylesheet.toUtf8() );
QUrl cssFileURL = QUrl( "data:text/css;charset=utf-8;base64," + ba.toBase64() );

return cssFileURL;
}
4 changes: 4 additions & 0 deletions src/core/composer/qgscomposerlabel.h
Expand Up @@ -204,10 +204,14 @@ class CORE_EXPORT QgsComposerLabel: public QgsComposerItem
/** Replaces replace '$CURRENT_DATE<(FORMAT)>' with the current date (e.g. $CURRENT_DATE(d 'June' yyyy)*/
void replaceDateText( QString& text ) const;

//! Creates an encoded stylesheet url using the current font and label appearance settings
QUrl createStylesheetUrl() const;

QScopedPointer<QgsFeature> mExpressionFeature;
QgsVectorLayer* mExpressionLayer;
QMap<QString, QVariant> mSubstitutions;
QgsDistanceArea* mDistanceArea;

};

#endif
42 changes: 41 additions & 1 deletion tests/src/core/testqgscomposerlabel.cpp
Expand Up @@ -22,6 +22,8 @@
#include "qgsmaprenderer.h"
#include "qgsvectorlayer.h"
#include "qgsvectordataprovider.h"
#include "qgsmultirenderchecker.h"
#include "qgsfontutils.h"

#include <QObject>
#include <QtTest/QtTest>
Expand Down Expand Up @@ -50,14 +52,16 @@ class TestQgsComposerLabel : public QObject
void feature_evaluation();
// test page expressions
void page_evaluation();

void marginMethods(); //tests getting/setting margins
void render();
void renderAsHtml();

private:
QgsComposition* mComposition;
QgsComposerLabel* mComposerLabel;
QgsMapSettings *mMapSettings;
QgsVectorLayer* mVectorLayer;
QString mReport;
};

void TestQgsComposerLabel::initTestCase()
Expand Down Expand Up @@ -89,6 +93,15 @@ void TestQgsComposerLabel::initTestCase()

void TestQgsComposerLabel::cleanupTestCase()
{
QString myReportFile = QDir::tempPath() + "/qgistest.html";
QFile myFile( myReportFile );
if ( myFile.open( QIODevice::WriteOnly | QIODevice::Append ) )
{
QTextStream myQTextStream( &myFile );
myQTextStream << mReport;
myFile.close();
}

delete mComposition;
delete mMapSettings;

Expand Down Expand Up @@ -225,5 +238,32 @@ void TestQgsComposerLabel::marginMethods()
QCOMPARE( label3.marginY(), 12.0 );
}

void TestQgsComposerLabel::render()
{
mComposerLabel->setText( "test label" );
mComposerLabel->setFont( QgsFontUtils::getStandardTestFont( "Bold", 48 ) );
mComposerLabel->setPos( 70, 70 );
mComposerLabel->adjustSizeToText();

QgsCompositionChecker checker( "composerlabel_render", mComposition );
checker.setControlPathPrefix( "composer_label" );
QVERIFY( checker.testComposition( mReport, 0, 0 ) );
}

void TestQgsComposerLabel::renderAsHtml()
{
mComposerLabel->setFontColor( QColor( 200, 40, 60 ) );
mComposerLabel->setText( "test <i>html</i>" );
mComposerLabel->setFont( QgsFontUtils::getStandardTestFont( "Bold", 48 ) );
mComposerLabel->setPos( 70, 70 );
mComposerLabel->adjustSizeToText();
mComposerLabel->setHtmlState( 1 );
mComposerLabel->update();

QgsCompositionChecker checker( "composerlabel_renderhtml", mComposition );
checker.setControlPathPrefix( "composer_label" );
QVERIFY( checker.testComposition( mReport, 0, 0 ) );
}

QTEST_MAIN( TestQgsComposerLabel )
#include "testqgscomposerlabel.moc"
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

1 comment on commit 9104704

@nirvn
Copy link
Contributor

@nirvn nirvn commented on 9104704 Mar 30, 2016

Choose a reason for hiding this comment

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

@nyalldawson works very well here, thanks for that. It might be useful for @NathanW2 too with his html-enabled feature labels.

Please sign in to comment.