Merge pull request #5997 from nyalldawson/report_label

Show a label in layout designer for report sections
This commit is contained in:
Nyall Dawson 2018-01-06 11:29:38 +10:00 committed by GitHub
commit 0779b88729
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 212 additions and 17 deletions

View File

@ -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:

View File

@ -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 );
}

View File

@ -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 );
}
}

View File

@ -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 );
}

View File

@ -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

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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() )

View File

@ -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;