Skip to content
Permalink
Browse files

Merge pull request #5997 from nyalldawson/report_label

Show a label in layout designer for report sections
  • Loading branch information
nyalldawson committed Jan 6, 2018
2 parents d300310 + 89884e8 commit 0779b88729e0809bc4107ad9083b72af103f06a6
@@ -263,6 +263,12 @@ Returns true if the current clipboard contains layout items.
%Docstring
Returns the delta (in layout coordinates) by which to move items
for the given key ``event``.
%End

void setSectionLabel( const QString &label );
%Docstring
Sets a section ``label``, to display above the first page shown in the
view.
%End

public slots:
@@ -2073,6 +2073,7 @@ void QgsLayoutDesignerDialog::atlasPreviewTriggered( bool checked )
else
{
atlas->endRender();
mView->setSectionLabel( QString() );
}
}

@@ -2634,16 +2635,7 @@ void QgsLayoutDesignerDialog::exportAtlasToPdf()
{
QString lastUsedFile = settings.value( QStringLiteral( "lastSaveAsPdfFile" ), QStringLiteral( "qgis.pdf" ), QgsSettings::App ).toString();
QFileInfo file( lastUsedFile );

QgsLayoutAtlas *printAtlas = atlas();
if ( printAtlas && printAtlas->enabled() && mActionAtlasPreview->isChecked() )
{
outputFileName = QDir( file.path() ).filePath( QgsFileUtils::stringToSafeFilename( printAtlas->currentFilename() ) + QStringLiteral( ".pdf" ) );
}
else
{
outputFileName = file.path() + '/' + QgsFileUtils::stringToSafeFilename( mMasterLayout->name() ) + QStringLiteral( ".pdf" );
}
outputFileName = file.path() + '/' + QgsFileUtils::stringToSafeFilename( mMasterLayout->name() ) + QStringLiteral( ".pdf" );

#ifdef Q_OS_MAC
QgisApp::instance()->activateWindow();
@@ -3827,6 +3819,8 @@ void QgsLayoutDesignerDialog::atlasFeatureChanged( const QgsFeature &feature )
mapCanvas->expressionContextScope().addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_geometry" ), QVariant::fromValue( feature.geometry() ), true ) );
mapCanvas->stopRendering();
mapCanvas->refreshAllLayers();

mView->setSectionLabel( atlas->nameForPage( atlas->currentFeatureNumber() ) );
}

void QgsLayoutDesignerDialog::loadAtlasPredefinedScalesFromProject()
@@ -4063,6 +4057,7 @@ void QgsLayoutDesignerDialog::setSectionTitle( const QString &title )
{
mSectionTitle = title;
updateWindowTitle();
mView->setSectionLabel( title );
}


@@ -73,7 +73,7 @@ void QgsReportSectionFieldGroupWidget::editHeader()
{
mSection->header()->reportContext().setLayer( mSection->layer() );
mDesigner->setCurrentLayout( mSection->header() );
mDesigner->setSectionTitle( tr( "%1 Header" ).arg( mSection->description() ) );
mDesigner->setSectionTitle( tr( "Header: %1" ).arg( mSection->description() ) );
mOrganizer->setEditedSection( mSection );
}
}
@@ -91,7 +91,7 @@ void QgsReportSectionFieldGroupWidget::editFooter()
{
mSection->footer()->reportContext().setLayer( mSection->layer() );
mDesigner->setCurrentLayout( mSection->footer() );
mDesigner->setSectionTitle( tr( "%1 Footer" ).arg( mSection->description() ) );
mDesigner->setSectionTitle( tr( "Footer: %1" ).arg( mSection->description() ) );
mOrganizer->setEditedSection( mSection );
}
}
@@ -114,7 +114,7 @@ void QgsReportSectionFieldGroupWidget::editBody()
{
mSection->body()->reportContext().setLayer( mSection->layer() );
mDesigner->setCurrentLayout( mSection->body() );
mDesigner->setSectionTitle( tr( "%1 Body" ).arg( mSection->description() ) );
mDesigner->setSectionTitle( tr( "Body: %1" ).arg( mSection->description() ) );
mOrganizer->setEditedSection( mSection );
}
}
@@ -63,7 +63,7 @@ void QgsReportLayoutSectionWidget::editHeader()
if ( mSection->header() )
{
mDesigner->setCurrentLayout( mSection->header() );
mDesigner->setSectionTitle( tr( "%1 Header" ).arg( mSection->description() ) );
mDesigner->setSectionTitle( tr( "Header: %1" ).arg( mSection->description() ) );
mOrganizer->setEditedSection( mSection );
}
}
@@ -80,7 +80,7 @@ void QgsReportLayoutSectionWidget::editFooter()
if ( mSection->footer() )
{
mDesigner->setCurrentLayout( mSection->footer() );
mDesigner->setSectionTitle( tr( "%1 Footer" ).arg( mSection->description() ) );
mDesigner->setSectionTitle( tr( "Footer: %1" ).arg( mSection->description() ) );
mOrganizer->setEditedSection( mSection );
}
}
@@ -100,6 +100,6 @@ void QgsReportLayoutSectionWidget::editBody()
}

mDesigner->setCurrentLayout( mSection->body() );
mDesigner->setSectionTitle( tr( "%1 Body" ).arg( mSection->description() ) );
mDesigner->setSectionTitle( tr( "Body: %1" ).arg( mSection->description() ) );
mOrganizer->setEditedSection( mSection );
}
@@ -27,7 +27,10 @@ QgsReportSectionFieldGroup::QgsReportSectionFieldGroup( QgsAbstractReportSection

QString QgsReportSectionFieldGroup::description() const
{
return QObject::tr( "Group: %1" ).arg( mField );
if ( mCoverageLayer.get() )
return QObject::tr( "Group: %1 - %2" ).arg( mCoverageLayer->name(), mField );
else
return QObject::tr( "Group" );
}

QIcon QgsReportSectionFieldGroup::icon() const
@@ -166,6 +166,7 @@ SET(QGIS_GUI_SRCS
layout/qgslayoutitemwidget.cpp
layout/qgslayoutmousehandles.cpp
layout/qgslayoutnewitempropertiesdialog.cpp
layout/qgslayoutreportsectionlabel.cpp
layout/qgslayoutruler.cpp
layout/qgslayoutunitscombobox.cpp
layout/qgslayoutview.cpp
@@ -801,6 +802,7 @@ SET(QGIS_GUI_HDRS
layertree/qgslayertreeembeddedconfigwidget.h
layertree/qgslayertreeembeddedwidgetregistry.h

layout/qgslayoutreportsectionlabel.h
layout/qgslayoutviewmouseevent.h
layout/qgslayoutviewrubberband.h

@@ -0,0 +1,99 @@
/***************************************************************************
qgslayoutreportsectionlabel.cpp
------------------------
begin : January 2018
copyright : (C) 2018 by Nyall Dawson
email : nyall.dawson@gmail.com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgslayoutreportsectionlabel.h"
#include "qgslayout.h"
#include "qgslayoutview.h"
#include <QGraphicsView>
#include <QPainter>
#include <QWidget>
#include <QBrush>

QgsLayoutReportSectionLabel::QgsLayoutReportSectionLabel( QgsLayout *layout, QgsLayoutView *view )
: QGraphicsRectItem( nullptr )
, mLayout( layout )
, mView( view )
{
setCacheMode( QGraphicsItem::DeviceCoordinateCache );
}

QgsLayoutReportSectionLabel::~QgsLayoutReportSectionLabel()
{

}

void QgsLayoutReportSectionLabel::paint( QPainter *painter, const QStyleOptionGraphicsItem *, QWidget * )
{
if ( !mLayout || !mLayout->renderContext().isPreviewRender() )
{
//don't draw label in outputs
return;
}

if ( mLabel.isEmpty() )
return;

QFont f;
f.setPointSizeF( 8 );
QFontMetrics fm( f );
QSize s = fm.size( 0, mLabel );
double margin = fm.height() / 5.0;

double scaleValue = scale() / painter->transform().m11();
painter->save();
painter->setRenderHint( QPainter::Antialiasing, true );
painter->scale( scaleValue, scaleValue );
QRectF r = rect();
QRectF scaledRect( r.left() / scaleValue, r.top() / scaleValue, r.width() / scaleValue, r.height() / scaleValue );

if ( scaledRect.width() < s.width() + 2 * margin || scaledRect.height() < s.height() + 2 * margin )
{
// zoomed out too far to fully draw label inside item rect
return;
}

QRectF textRect = QRectF( scaledRect.left() + margin, scaledRect.top() + margin, scaledRect.width() - 2 * margin, scaledRect.height() - 2 * margin );
QRectF boxRect = QRectF( scaledRect.left(), scaledRect.bottom() - ( s.height() + 2 * margin ), s.width() + 2 * margin, s.height() + 2 * margin );

QPainterPath p;
p.moveTo( boxRect.bottomRight() );
p.lineTo( boxRect.right(), boxRect.top() + margin );
p.arcTo( boxRect.right() - 2 * margin, boxRect.top(), 2 * margin, 2 * margin, 0, 90 );
p.lineTo( boxRect.left() + margin, boxRect.top() );
p.arcTo( boxRect.left(), boxRect.top(), 2 * margin, 2 * margin, 90, 90 );
p.lineTo( boxRect.bottomLeft() );
p.lineTo( boxRect.bottomRight() );

painter->setPen( QColor( 150, 150, 150, 150 ) );
QLinearGradient g( 0, boxRect.top(), 0, boxRect.bottom() );
g.setColorAt( 0, QColor( 200, 200, 200, 150 ) );
g.setColorAt( 1, QColor( 150, 150, 150, 150 ) );

painter->setBrush( QBrush( g ) );
painter->drawPath( p );

painter->setPen( QPen( QColor( 0, 0, 0, 100 ) ) );
painter->setFont( f );
painter->drawText( textRect, Qt::AlignBottom, mLabel );
painter->restore();
}

void QgsLayoutReportSectionLabel::setLabel( const QString &label )
{
mLabel = label;
update();
}
@@ -0,0 +1,63 @@
/***************************************************************************
qgslayoutreportsectionlabel.h
-----------------------
begin : January 2018
copyright : (C) 2018 by Nyall Dawson
email : nyall.dawson@gmail.com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSLAYOUTREPORTSECTIONLABEL_H
#define QGSLAYOUTREPORTSECTIONLABEL_H

#define SIP_NO_FILE

#include <QGraphicsRectItem>
#include "qgis_gui.h"
#include "qgslayoutview.h"
#include "qgslayout.h"

///@cond PRIVATE

/**
* \ingroup gui
* Draws a label describing the current report section within a layout designer view.
*
* \note not available in Python bindings
* \since QGIS 3.0
*
*/
class GUI_EXPORT QgsLayoutReportSectionLabel: public QGraphicsRectItem
{

public:

/**
* Constructor for QgsLayoutReportSectionLabel.
*/
QgsLayoutReportSectionLabel( QgsLayout *layout, QgsLayoutView *view );

~QgsLayoutReportSectionLabel();

void paint( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget ) override;

void setLabel( const QString &label );

private:

QPointer< QgsLayout > mLayout;
QPointer< QgsLayoutView > mView;
QString mLabel;

};

///@endcond PRIVATE

#endif // QGSLAYOUTREPORTSECTIONLABEL_H
@@ -33,6 +33,7 @@
#include "qgslayoutitemgroup.h"
#include "qgslayoutpagecollection.h"
#include "qgslayoutundostack.h"
#include "qgslayoutreportsectionlabel.h"
#include <memory>
#include <QDesktopWidget>
#include <QMenu>
@@ -97,6 +98,9 @@ void QgsLayoutView::setCurrentLayout( QgsLayout *layout )
mVerticalSnapLine->hide();
layout->addItem( mVerticalSnapLine );

delete mSectionLabel;
mSectionLabel = nullptr;

if ( mHorizontalRuler )
{
connect( &layout->guides(), &QAbstractItemModel::dataChanged, mHorizontalRuler, [ = ] { mHorizontalRuler->update(); } );
@@ -480,6 +484,21 @@ void QgsLayoutView::setPaintingEnabled( bool enabled )
update();
}

void QgsLayoutView::setSectionLabel( const QString &label )
{
if ( !currentLayout() )
return;

if ( !mSectionLabel )
{
mSectionLabel = new QgsLayoutReportSectionLabel( currentLayout(), this );
currentLayout()->addItem( mSectionLabel );
mSectionLabel->setRect( 0, -200, 1000, 200 );
mSectionLabel->setZValue( -1 );
}
mSectionLabel->setLabel( label );
}

void QgsLayoutView::zoomFull()
{
if ( !scene() )
@@ -36,6 +36,7 @@ class QgsLayoutViewToolTemporaryMousePan;
class QgsLayoutRuler;
class QgsLayoutViewMenuProvider;
class QgsLayoutViewSnapMarker;
class QgsLayoutReportSectionLabel;

/**
* \ingroup gui
@@ -277,6 +278,12 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView
*/
void setPaintingEnabled( bool enabled ); SIP_SKIP

/**
* Sets a section \a label, to display above the first page shown in the
* view.
*/
void setSectionLabel( const QString &label );

public slots:

/**
@@ -543,6 +550,7 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView
std::unique_ptr< QgsLayoutViewMenuProvider > mMenuProvider;

QgsLayoutViewSnapMarker *mSnapMarker = nullptr;
QgsLayoutReportSectionLabel *mSectionLabel = nullptr;

QGraphicsLineItem *mHorizontalSnapLine = nullptr;
QGraphicsLineItem *mVerticalSnapLine = nullptr;

0 comments on commit 0779b88

Please sign in to comment.
You can’t perform that action at this time.