Skip to content

Commit c9ddc9f

Browse files
committedJan 5, 2018
Start on ui for configuring reports
1 parent 6db2432 commit c9ddc9f

17 files changed

+697
-1
lines changed
 

‎python/core/layout/qgsabstractreportsection.sip

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ Note that ownership is not transferred to ``parent``.
6969
virtual QString type() const = 0;
7070
%Docstring
7171
Returns the section subclass type.
72+
%End
73+
74+
virtual QString description() const = 0;
75+
%Docstring
76+
Returns a user-visible, translated description of the section.
7277
%End
7378

7479
virtual QgsAbstractReportSection *clone() const = 0 /Factory/;

‎python/core/layout/qgsreport.sip

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Note that ownership is not transferred to ``project``.
3939
%End
4040

4141
virtual QString type() const;
42+
virtual QString description() const;
4243
virtual QIcon icon() const;
4344

4445
virtual QgsProject *layoutProject() const;

‎python/core/layout/qgsreportsectionfieldgroup.sip

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ Note that ownership is not transferred to ``parent``.
3535
%End
3636

3737
virtual QString type() const;
38+
virtual QString description() const;
39+
3840

3941
QgsLayout *body();
4042
%Docstring

‎python/core/layout/qgsreportsectionlayout.sip

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Note that ownership is not transferred to ``parent``.
3434
%End
3535

3636
virtual QString type() const;
37+
virtual QString description() const;
3738

3839
QgsLayout *body();
3940
%Docstring

‎src/app/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,8 @@ SET(QGIS_APP_SRCS
204204
layout/qgslayoutscalebarwidget.cpp
205205
layout/qgslayoutshapewidget.cpp
206206
layout/qgslayouttablebackgroundcolorsdialog.cpp
207+
layout/qgsreportorganizerwidget.cpp
208+
layout/qgsreportsectionmodel.cpp
207209

208210
locator/qgsinbuiltlocatorfilters.cpp
209211
locator/qgslocatoroptionswidget.cpp
@@ -423,6 +425,8 @@ SET (QGIS_APP_MOC_HDRS
423425
layout/qgslayoutscalebarwidget.h
424426
layout/qgslayoutshapewidget.h
425427
layout/qgslayouttablebackgroundcolorsdialog.h
428+
layout/qgsreportorganizerwidget.h
429+
layout/qgsreportsectionmodel.h
426430

427431
locator/qgsinbuiltlocatorfilters.h
428432
locator/qgslocatoroptionswidget.h

‎src/app/layout/qgslayoutdesignerdialog.cpp

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
#include "qgslayoutatlaswidget.h"
6161
#include "qgslayoutpagecollection.h"
6262
#include "qgsreport.h"
63+
#include "qgsreportorganizerwidget.h"
6364
#include "ui_qgssvgexportoptions.h"
6465
#include <QShortcut>
6566
#include <QComboBox>
@@ -646,6 +647,9 @@ QgsLayoutDesignerDialog::QgsLayoutDesignerDialog( QWidget *parent, Qt::WindowFla
646647
mAtlasDock = new QgsDockWidget( tr( "Atlas" ), this );
647648
mAtlasDock->setObjectName( QStringLiteral( "AtlasDock" ) );
648649

650+
mReportDock = new QgsDockWidget( tr( "Report" ), this );
651+
mReportDock->setObjectName( QStringLiteral( "ReportDock" ) );
652+
649653
const QList<QDockWidget *> docks = findChildren<QDockWidget *>();
650654
for ( QDockWidget *dock : docks )
651655
{
@@ -658,20 +662,23 @@ QgsLayoutDesignerDialog::QgsLayoutDesignerDialog( QWidget *parent, Qt::WindowFla
658662
addDockWidget( Qt::RightDockWidgetArea, mUndoDock );
659663
addDockWidget( Qt::RightDockWidgetArea, mItemsDock );
660664
addDockWidget( Qt::RightDockWidgetArea, mAtlasDock );
665+
addDockWidget( Qt::RightDockWidgetArea, mReportDock );
661666

662667
createLayoutPropertiesWidget();
663668

664669
mUndoDock->show();
665670
mItemDock->show();
666671
mGeneralDock->show();
667672
mAtlasDock->show();
673+
mReportDock->show();
668674
mItemsDock->show();
669675

670676
tabifyDockWidget( mGeneralDock, mUndoDock );
671677
tabifyDockWidget( mItemDock, mUndoDock );
672678
tabifyDockWidget( mGeneralDock, mItemDock );
673679
tabifyDockWidget( mItemDock, mItemsDock );
674680
tabifyDockWidget( mItemDock, mAtlasDock );
681+
tabifyDockWidget( mItemDock, mReportDock );
675682

676683
toggleActions( false );
677684

@@ -739,6 +746,19 @@ void QgsLayoutDesignerDialog::setMasterLayout( QgsMasterLayoutInterface *layout
739746
mMenuAtlas = nullptr;
740747
mAtlasToolbar->hide();
741748
}
749+
750+
if ( dynamic_cast< QgsReport * >( layout ) )
751+
{
752+
createReportWidget();
753+
}
754+
else
755+
{
756+
// ideally we'd only create mReportDock in createReportWidget() -
757+
// but if we do that, then it's always brought to the focus
758+
// in tab widgets
759+
mReportDock->hide();
760+
mPanelsMenu->removeAction( mReportDock->toggleViewAction() );
761+
}
742762
}
743763

744764
QgsMasterLayoutInterface *QgsLayoutDesignerDialog::masterLayout()
@@ -2680,7 +2700,7 @@ void QgsLayoutDesignerDialog::createLayoutPropertiesWidget()
26802700

26812701
void QgsLayoutDesignerDialog::createAtlasWidget()
26822702
{
2683-
QgsPrintLayout *printLayout = qobject_cast< QgsPrintLayout * >( mLayout );
2703+
QgsPrintLayout *printLayout = dynamic_cast< QgsPrintLayout * >( mMasterLayout );
26842704
QgsLayoutAtlas *atlas = printLayout->atlas();
26852705
QgsLayoutAtlasWidget *atlasWidget = new QgsLayoutAtlasWidget( mAtlasDock, printLayout );
26862706
atlasWidget->setMessageBar( mMessageBar );
@@ -2700,6 +2720,16 @@ void QgsLayoutDesignerDialog::createAtlasWidget()
27002720
toggleAtlasControls( atlas->enabled() && atlas->coverageLayer() );
27012721
}
27022722

2723+
void QgsLayoutDesignerDialog::createReportWidget()
2724+
{
2725+
QgsReport *report = dynamic_cast< QgsReport * >( mMasterLayout );
2726+
QgsReportOrganizerWidget *reportWidget = new QgsReportOrganizerWidget( mReportDock, this, report );
2727+
reportWidget->setMessageBar( mMessageBar );
2728+
mReportDock->setWidget( reportWidget );
2729+
2730+
mPanelsMenu->addAction( mReportDock->toggleViewAction() );
2731+
}
2732+
27032733
void QgsLayoutDesignerDialog::initializeRegistry()
27042734
{
27052735
sInitializedRegistry = true;

‎src/app/layout/qgslayoutdesignerdialog.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,8 @@ class QgsLayoutDesignerDialog: public QMainWindow, private Ui::QgsLayoutDesigner
373373
QgsDockWidget *mItemsDock = nullptr;
374374
QgsLayoutItemsListView *mItemsTreeView = nullptr;
375375

376+
QgsDockWidget *mReportDock = nullptr;
377+
376378
QAction *mUndoAction = nullptr;
377379
QAction *mRedoAction = nullptr;
378380
//! Copy/cut/paste actions
@@ -406,6 +408,7 @@ class QgsLayoutDesignerDialog: public QMainWindow, private Ui::QgsLayoutDesigner
406408

407409
void createLayoutPropertiesWidget();
408410
void createAtlasWidget();
411+
void createReportWidget();
409412

410413
void initializeRegistry();
411414

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
/***************************************************************************
2+
qgsreportorganizerwidget.cpp
3+
------------------------
4+
begin : December 2017
5+
copyright : (C) 2017 by Nyall Dawson
6+
email : nyall dot dawson at gmail dot com
7+
***************************************************************************/
8+
/***************************************************************************
9+
* *
10+
* This program is free software; you can redistribute it and/or modify *
11+
* it under the terms of the GNU General Public License as published by *
12+
* the Free Software Foundation; either version 2 of the License, or *
13+
* (at your option) any later version. *
14+
* *
15+
***************************************************************************/
16+
17+
#include "qgsreportorganizerwidget.h"
18+
#include "qgsreport.h"
19+
#include "qgsreportsectionmodel.h"
20+
#include "qgsreportsectionlayout.h"
21+
#include "qgsreportsectionfieldgroup.h"
22+
#include "qgslayout.h"
23+
#include "qgslayoutdesignerdialog.h"
24+
#include <QMenu>
25+
#include <QMessageBox>
26+
27+
#ifdef ENABLE_MODELTEST
28+
#include "modeltest.h"
29+
#endif
30+
31+
QgsReportOrganizerWidget::QgsReportOrganizerWidget( QWidget *parent, QgsLayoutDesignerDialog *designer, QgsReport *report )
32+
: QgsPanelWidget( parent )
33+
, mReport( report )
34+
, mDesigner( designer )
35+
{
36+
setupUi( this );
37+
setPanelTitle( tr( "Report" ) );
38+
39+
mSectionModel = new QgsReportSectionModel( mReport, mViewSections );
40+
mViewSections->setModel( mSectionModel );
41+
42+
#ifdef ENABLE_MODELTEST
43+
//new ModelTest( mSectionModel, this );
44+
#endif
45+
46+
mViewSections->setEditTriggers( QAbstractItemView::AllEditTriggers );
47+
48+
QMenu *addMenu = new QMenu( mButtonAddSection );
49+
QAction *layoutSection = new QAction( tr( "Single section" ), addMenu );
50+
addMenu->addAction( layoutSection );
51+
connect( layoutSection, &QAction::triggered, this, &QgsReportOrganizerWidget::addLayoutSection );
52+
QAction *fieldGroupSection = new QAction( tr( "Field group" ), addMenu );
53+
addMenu->addAction( fieldGroupSection );
54+
connect( fieldGroupSection, &QAction::triggered, this, &QgsReportOrganizerWidget::addFieldGroupSection );
55+
56+
connect( mCheckShowHeader, &QCheckBox::toggled, this, &QgsReportOrganizerWidget::toggleHeader );
57+
connect( mCheckShowFooter, &QCheckBox::toggled, this, &QgsReportOrganizerWidget::toggleFooter );
58+
connect( mButtonEditHeader, &QPushButton::clicked, this, &QgsReportOrganizerWidget::editHeader );
59+
connect( mButtonEditFooter, &QPushButton::clicked, this, &QgsReportOrganizerWidget::editFooter );
60+
connect( mViewSections->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsReportOrganizerWidget::selectionChanged );
61+
62+
mButtonAddSection->setMenu( addMenu );
63+
connect( mButtonRemoveSection, &QPushButton::clicked, this, &QgsReportOrganizerWidget::removeSection );
64+
}
65+
66+
void QgsReportOrganizerWidget::setMessageBar( QgsMessageBar *bar )
67+
{
68+
mMessageBar = bar;
69+
}
70+
71+
void QgsReportOrganizerWidget::addLayoutSection()
72+
{
73+
std::unique_ptr< QgsReportSectionLayout > section = qgis::make_unique< QgsReportSectionLayout >();
74+
mSectionModel->addSection( mViewSections->currentIndex(), std::move( section ) );
75+
}
76+
77+
void QgsReportOrganizerWidget::addFieldGroupSection()
78+
{
79+
std::unique_ptr< QgsReportSectionFieldGroup > section = qgis::make_unique< QgsReportSectionFieldGroup >();
80+
mSectionModel->addSection( mViewSections->currentIndex(), std::move( section ) );
81+
}
82+
83+
void QgsReportOrganizerWidget::removeSection()
84+
{
85+
QgsAbstractReportSection *section = mSectionModel->sectionForIndex( mViewSections->currentIndex() );
86+
if ( dynamic_cast< QgsReport * >( section ) )
87+
return; //report cannot be removed
88+
89+
int res = QMessageBox::question( this, tr( "Remove Section" ),
90+
tr( "Are you sure you want to remove the report section?" ),
91+
QMessageBox::Yes | QMessageBox::No, QMessageBox::No );
92+
if ( res == QMessageBox::No )
93+
return;
94+
95+
mSectionModel->removeRow( mViewSections->currentIndex().row(), mViewSections->currentIndex().parent() );
96+
}
97+
98+
void QgsReportOrganizerWidget::toggleHeader( bool enabled )
99+
{
100+
QgsAbstractReportSection *parent = mSectionModel->sectionForIndex( mViewSections->currentIndex() );
101+
if ( !parent )
102+
parent = mReport;
103+
parent->setHeaderEnabled( enabled );
104+
}
105+
106+
void QgsReportOrganizerWidget::toggleFooter( bool enabled )
107+
{
108+
QgsAbstractReportSection *parent = mSectionModel->sectionForIndex( mViewSections->currentIndex() );
109+
if ( !parent )
110+
parent = mReport;
111+
parent->setFooterEnabled( enabled );
112+
}
113+
114+
void QgsReportOrganizerWidget::editHeader()
115+
{
116+
QgsAbstractReportSection *parent = mSectionModel->sectionForIndex( mViewSections->currentIndex() );
117+
if ( !parent )
118+
parent = mReport;
119+
120+
if ( !parent->header() )
121+
{
122+
std::unique_ptr< QgsLayout > header = qgis::make_unique< QgsLayout >( mReport->layoutProject() );
123+
header->initializeDefaults();
124+
parent->setHeader( header.release() );
125+
}
126+
127+
mDesigner->setCurrentLayout( parent->header() );
128+
}
129+
130+
void QgsReportOrganizerWidget::editFooter()
131+
{
132+
QgsAbstractReportSection *parent = mSectionModel->sectionForIndex( mViewSections->currentIndex() );
133+
if ( !parent )
134+
parent = mReport;
135+
136+
if ( !parent->footer() )
137+
{
138+
std::unique_ptr< QgsLayout > footer = qgis::make_unique< QgsLayout >( mReport->layoutProject() );
139+
footer->initializeDefaults();
140+
parent->setFooter( footer.release() );
141+
}
142+
143+
mDesigner->setCurrentLayout( parent->footer() );
144+
}
145+
146+
void QgsReportOrganizerWidget::selectionChanged( const QModelIndex &current, const QModelIndex & )
147+
{
148+
QgsAbstractReportSection *parent = mSectionModel->sectionForIndex( current );
149+
if ( !parent )
150+
parent = mReport;
151+
152+
whileBlocking( mCheckShowHeader )->setChecked( parent->headerEnabled() );
153+
whileBlocking( mCheckShowFooter )->setChecked( parent->footerEnabled() );
154+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/***************************************************************************
2+
qgsreportorganizerwidget.h
3+
----------------------
4+
begin : December 2017
5+
copyright : (C) 2017 by Nyall Dawson
6+
email : nyall dot dawson at gmail dot com
7+
***************************************************************************/
8+
/***************************************************************************
9+
* *
10+
* This program is free software; you can redistribute it and/or modify *
11+
* it under the terms of the GNU General Public License as published by *
12+
* the Free Software Foundation; either version 2 of the License, or *
13+
* (at your option) any later version. *
14+
* *
15+
***************************************************************************/
16+
17+
#ifndef QGSREPORTORGANIZERWIDGET_H
18+
#define QGSREPORTORGANIZERWIDGET_H
19+
20+
#include "ui_qgsreportorganizerwidgetbase.h"
21+
#include "qgspanelwidget.h"
22+
#include <QStyledItemDelegate>
23+
24+
class QgsReportSectionModel;
25+
class QgsReport;
26+
class QgsMessageBar;
27+
class QgsLayoutDesignerDialog ;
28+
29+
class QgsReportOrganizerWidget: public QgsPanelWidget, private Ui::QgsReportOrganizerBase
30+
{
31+
Q_OBJECT
32+
public:
33+
QgsReportOrganizerWidget( QWidget *parent, QgsLayoutDesignerDialog *designer, QgsReport *report );
34+
35+
void setMessageBar( QgsMessageBar *bar );
36+
37+
private slots:
38+
39+
void addLayoutSection();
40+
void addFieldGroupSection();
41+
void removeSection();
42+
void toggleHeader( bool enabled );
43+
void toggleFooter( bool enabled );
44+
void editHeader();
45+
void editFooter();
46+
void selectionChanged( const QModelIndex &current, const QModelIndex &previous );
47+
48+
private:
49+
50+
QgsReport *mReport = nullptr;
51+
QgsReportSectionModel *mSectionModel = nullptr;
52+
QgsMessageBar *mMessageBar;
53+
QgsLayoutDesignerDialog *mDesigner = nullptr;
54+
55+
};
56+
57+
58+
59+
#endif // QGSREPORTORGANIZERWIDGET_H
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
/***************************************************************************
2+
qgsreportsectionmodel.cpp
3+
---------------------
4+
begin : December 2017
5+
copyright : (C) 2017 by Nyall Dawso
6+
email : nyall dot dawson at gmail dot com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#include "qgsreportsectionmodel.h"
17+
18+
#ifdef ENABLE_MODELTEST
19+
#include "modeltest.h"
20+
#endif
21+
22+
QgsReportSectionModel::QgsReportSectionModel( QgsReport *report, QObject *parent )
23+
: QAbstractItemModel( parent )
24+
, mReport( report )
25+
{
26+
}
27+
28+
Qt::ItemFlags QgsReportSectionModel::flags( const QModelIndex &index ) const
29+
{
30+
if ( !index.isValid() )
31+
return 0;
32+
33+
return QAbstractItemModel::flags( index );
34+
}
35+
36+
QVariant QgsReportSectionModel::data( const QModelIndex &index, int role ) const
37+
{
38+
if ( !index.isValid() )
39+
return QVariant();
40+
41+
QgsAbstractReportSection *section = sectionForIndex( index );
42+
if ( !section )
43+
return QVariant();
44+
45+
switch ( role )
46+
{
47+
case Qt::DisplayRole:
48+
case Qt::ToolTipRole:
49+
{
50+
switch ( index.column() )
51+
{
52+
case 0:
53+
return section->description();
54+
default:
55+
return QVariant();
56+
}
57+
break;
58+
}
59+
60+
case Qt::TextAlignmentRole:
61+
{
62+
return ( index.column() == 2 || index.column() == 3 ) ? Qt::AlignRight : Qt::AlignLeft;
63+
}
64+
65+
case Qt::EditRole:
66+
{
67+
switch ( index.column() )
68+
{
69+
case 0:
70+
return section->type();
71+
72+
default:
73+
return QVariant();
74+
}
75+
break;
76+
}
77+
78+
default:
79+
return QVariant();
80+
}
81+
82+
return QVariant();
83+
}
84+
85+
QVariant QgsReportSectionModel::headerData( int section, Qt::Orientation orientation, int role ) const
86+
{
87+
if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section <= 0 )
88+
{
89+
QStringList lst;
90+
lst << tr( "Section" );
91+
return lst[section];
92+
}
93+
94+
return QVariant();
95+
}
96+
97+
int QgsReportSectionModel::rowCount( const QModelIndex &parent ) const
98+
{
99+
QgsAbstractReportSection *parentSection = nullptr;
100+
if ( parent.column() > 0 )
101+
return 0;
102+
103+
if ( !parent.isValid() )
104+
parentSection = mReport;
105+
else
106+
parentSection = sectionForIndex( parent );
107+
108+
return parentSection->childCount();
109+
}
110+
111+
int QgsReportSectionModel::columnCount( const QModelIndex & ) const
112+
{
113+
return 1;
114+
}
115+
116+
QModelIndex QgsReportSectionModel::index( int row, int column, const QModelIndex &parent ) const
117+
{
118+
if ( !hasIndex( row, column, parent ) )
119+
return QModelIndex();
120+
121+
QgsAbstractReportSection *parentSection = nullptr;
122+
123+
if ( !parent.isValid() )
124+
parentSection = mReport;
125+
else
126+
parentSection = sectionForIndex( parent );
127+
128+
QgsAbstractReportSection *childSection = parentSection->childSection( row );
129+
if ( childSection )
130+
return createIndex( row, column, childSection );
131+
else
132+
return QModelIndex();
133+
}
134+
135+
QModelIndex QgsReportSectionModel::parent( const QModelIndex &index ) const
136+
{
137+
if ( !index.isValid() )
138+
return QModelIndex();
139+
140+
QgsAbstractReportSection *childSection = sectionForIndex( index );
141+
QgsAbstractReportSection *parentSection = childSection->parentSection();
142+
143+
if ( parentSection == mReport )
144+
return QModelIndex();
145+
146+
return createIndex( parentSection->row(), 0, parentSection );
147+
}
148+
149+
bool QgsReportSectionModel::setData( const QModelIndex &index, const QVariant &value, int role )
150+
{
151+
if ( !index.isValid() )
152+
return false;
153+
154+
QgsAbstractReportSection *section = sectionForIndex( index );
155+
( void )section;
156+
( void )value;
157+
158+
if ( role != Qt::EditRole )
159+
return false;
160+
161+
switch ( index.column() )
162+
{
163+
case 0:
164+
return false;
165+
166+
default:
167+
return false;
168+
}
169+
170+
emit dataChanged( index, index );
171+
return true;
172+
}
173+
174+
QgsAbstractReportSection *QgsReportSectionModel::sectionForIndex( const QModelIndex &index ) const
175+
{
176+
return static_cast<QgsAbstractReportSection *>( index.internalPointer() );
177+
}
178+
179+
bool QgsReportSectionModel::removeRows( int row, int count, const QModelIndex &parent )
180+
{
181+
QgsAbstractReportSection *parentSection = sectionForIndex( parent );
182+
183+
if ( row < 0 || row >= parentSection->childCount() )
184+
return false;
185+
186+
beginRemoveRows( parent, row, row + count - 1 );
187+
188+
for ( int i = 0; i < count; i++ )
189+
{
190+
if ( row < parentSection->childCount() )
191+
{
192+
parentSection->removeChildAt( row );
193+
}
194+
}
195+
196+
endRemoveRows();
197+
198+
return true;
199+
}
200+
201+
void QgsReportSectionModel::addSection( const QModelIndex &parent, std::unique_ptr<QgsAbstractReportSection> section )
202+
{
203+
QgsAbstractReportSection *parentSection = sectionForIndex( parent );
204+
if ( !parentSection )
205+
return;
206+
207+
beginInsertRows( parent, parentSection->childCount(), parentSection->childCount() );
208+
parentSection->appendChild( section.release() );
209+
endInsertRows();
210+
}
211+
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/***************************************************************************
2+
qgsreportsectionmodel.h
3+
---------------------
4+
begin : December 2017
5+
copyright : (C) 2017 by Nyall Dawso
6+
email : nyall dot dawson at gmail dot com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#ifndef QGSREPORTSECTIONMODEL_H
17+
#define QGSREPORTSECTIONMODEL_H
18+
19+
#include "qgis.h"
20+
#include "qgsreport.h"
21+
#include <QAbstractItemModel>
22+
23+
/**
24+
* \ingroup app
25+
* \class QgsReportSectionModel
26+
* \brief A model for managing the sections in a QgsReport.
27+
* \since QGIS 3.0
28+
*/
29+
class QgsReportSectionModel : public QAbstractItemModel
30+
{
31+
Q_OBJECT
32+
33+
public:
34+
35+
/**
36+
* Constructor for QgsReportSectionModel, for the specified \a report.
37+
*/
38+
QgsReportSectionModel( QgsReport *report, QObject *parent );
39+
40+
Qt::ItemFlags flags( const QModelIndex &index ) const override;
41+
QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const override;
42+
QVariant headerData( int section, Qt::Orientation orientation,
43+
int role = Qt::DisplayRole ) const override;
44+
int rowCount( const QModelIndex &parent = QModelIndex() ) const override;
45+
int columnCount( const QModelIndex & = QModelIndex() ) const override;
46+
47+
QModelIndex index( int row, int column, const QModelIndex &parent = QModelIndex() ) const override;
48+
QModelIndex parent( const QModelIndex &index ) const override;
49+
bool setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole ) override;
50+
bool removeRows( int row, int count, const QModelIndex &parent = QModelIndex() ) override;
51+
52+
void addSection( const QModelIndex &parent, std::unique_ptr< QgsAbstractReportSection > section );
53+
54+
/**
55+
* Returns the report section for the given \a index.
56+
*/
57+
QgsAbstractReportSection *sectionForIndex( const QModelIndex &index ) const;
58+
59+
private:
60+
QgsReport *mReport = nullptr;
61+
};
62+
63+
#endif // QGSREPORTSECTIONMODEL_H

‎src/core/layout/qgsabstractreportsection.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ class CORE_EXPORT QgsAbstractReportSection : public QgsAbstractLayoutIterator
8585
*/
8686
virtual QString type() const = 0;
8787

88+
/**
89+
* Returns a user-visible, translated description of the section.
90+
*/
91+
virtual QString description() const = 0;
92+
8893
/**
8994
* Clones the report section. Ownership of the returned section is
9095
* transferred to the caller.

‎src/core/layout/qgsreport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class CORE_EXPORT QgsReport : public QObject, public QgsAbstractReportSection, p
5353
QgsReport( QgsProject *project );
5454

5555
QString type() const override { return QStringLiteral( "SectionReport" ); }
56+
QString description() const override { return QObject::tr( "Report" ); }
5657
QIcon icon() const override;
5758
QgsProject *layoutProject() const override { return mProject; }
5859
QgsReport *clone() const override SIP_FACTORY;

‎src/core/layout/qgsreportsectionfieldgroup.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ QgsReportSectionFieldGroup::QgsReportSectionFieldGroup( QgsAbstractReportSection
2525

2626
}
2727

28+
QString QgsReportSectionFieldGroup::description() const
29+
{
30+
return QObject::tr( "Group: %1" ).arg( mField );
31+
}
32+
2833
QgsReportSectionFieldGroup *QgsReportSectionFieldGroup::clone() const
2934
{
3035
std::unique_ptr< QgsReportSectionFieldGroup > copy = qgis::make_unique< QgsReportSectionFieldGroup >( nullptr );

‎src/core/layout/qgsreportsectionfieldgroup.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class CORE_EXPORT QgsReportSectionFieldGroup : public QgsAbstractReportSection
4545
QgsReportSectionFieldGroup( QgsAbstractReportSection *parentSection = nullptr );
4646

4747
QString type() const override { return QStringLiteral( "SectionFieldGroup" ); }
48+
QString description() const override;
4849

4950
/**
5051
* Returns the body layout for the section.

‎src/core/layout/qgsreportsectionlayout.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class CORE_EXPORT QgsReportSectionLayout : public QgsAbstractReportSection
4242
QgsReportSectionLayout( QgsAbstractReportSection *parentSection = nullptr );
4343

4444
QString type() const override { return QStringLiteral( "SectionLayout" ); }
45+
QString description() const override { return QObject::tr( "Section" ); }
4546

4647
/**
4748
* Returns the body layout for the section.
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ui version="4.0">
3+
<class>QgsReportOrganizerBase</class>
4+
<widget class="QWidget" name="QgsReportOrganizerBase">
5+
<property name="geometry">
6+
<rect>
7+
<x>0</x>
8+
<y>0</y>
9+
<width>723</width>
10+
<height>520</height>
11+
</rect>
12+
</property>
13+
<property name="minimumSize">
14+
<size>
15+
<width>425</width>
16+
<height>300</height>
17+
</size>
18+
</property>
19+
<property name="windowTitle">
20+
<string>Layout Manager</string>
21+
</property>
22+
<layout class="QVBoxLayout" name="verticalLayout">
23+
<item>
24+
<widget class="QTreeView" name="mViewSections">
25+
<property name="contextMenuPolicy">
26+
<enum>Qt::CustomContextMenu</enum>
27+
</property>
28+
<property name="acceptDrops">
29+
<bool>true</bool>
30+
</property>
31+
<property name="editTriggers">
32+
<set>QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked</set>
33+
</property>
34+
<property name="dragEnabled">
35+
<bool>true</bool>
36+
</property>
37+
<property name="dragDropMode">
38+
<enum>QAbstractItemView::InternalMove</enum>
39+
</property>
40+
<property name="selectionMode">
41+
<enum>QAbstractItemView::ExtendedSelection</enum>
42+
</property>
43+
<property name="allColumnsShowFocus">
44+
<bool>true</bool>
45+
</property>
46+
<attribute name="headerMinimumSectionSize">
47+
<number>100</number>
48+
</attribute>
49+
<attribute name="headerStretchLastSection">
50+
<bool>true</bool>
51+
</attribute>
52+
</widget>
53+
</item>
54+
<item>
55+
<layout class="QHBoxLayout" name="horizontalLayout">
56+
<item>
57+
<widget class="QPushButton" name="mButtonAddSection">
58+
<property name="toolTip">
59+
<string>Add rule</string>
60+
</property>
61+
<property name="text">
62+
<string/>
63+
</property>
64+
<property name="icon">
65+
<iconset resource="../../../images/images.qrc">
66+
<normaloff>:/images/themes/default/symbologyAdd.svg</normaloff>:/images/themes/default/symbologyAdd.svg</iconset>
67+
</property>
68+
</widget>
69+
</item>
70+
<item>
71+
<widget class="QPushButton" name="mButtonRemoveSection">
72+
<property name="toolTip">
73+
<string>Remove selected rules</string>
74+
</property>
75+
<property name="text">
76+
<string/>
77+
</property>
78+
<property name="icon">
79+
<iconset resource="../../../images/images.qrc">
80+
<normaloff>:/images/themes/default/symbologyRemove.svg</normaloff>:/images/themes/default/symbologyRemove.svg</iconset>
81+
</property>
82+
</widget>
83+
</item>
84+
<item>
85+
<spacer name="horizontalSpacer">
86+
<property name="orientation">
87+
<enum>Qt::Horizontal</enum>
88+
</property>
89+
<property name="sizeHint" stdset="0">
90+
<size>
91+
<width>0</width>
92+
<height>20</height>
93+
</size>
94+
</property>
95+
</spacer>
96+
</item>
97+
</layout>
98+
</item>
99+
<item>
100+
<layout class="QGridLayout" name="gridLayout">
101+
<item row="1" column="1">
102+
<widget class="QPushButton" name="mButtonEditFooter">
103+
<property name="text">
104+
<string>Edit</string>
105+
</property>
106+
</widget>
107+
</item>
108+
<item row="0" column="0">
109+
<widget class="QCheckBox" name="mCheckShowHeader">
110+
<property name="text">
111+
<string>Show header</string>
112+
</property>
113+
</widget>
114+
</item>
115+
<item row="0" column="1">
116+
<widget class="QPushButton" name="mButtonEditHeader">
117+
<property name="text">
118+
<string>Edit</string>
119+
</property>
120+
</widget>
121+
</item>
122+
<item row="1" column="0">
123+
<widget class="QCheckBox" name="mCheckShowFooter">
124+
<property name="text">
125+
<string>Show footer</string>
126+
</property>
127+
</widget>
128+
</item>
129+
<item row="1" column="2">
130+
<spacer name="horizontalSpacer_2">
131+
<property name="orientation">
132+
<enum>Qt::Horizontal</enum>
133+
</property>
134+
<property name="sizeHint" stdset="0">
135+
<size>
136+
<width>40</width>
137+
<height>20</height>
138+
</size>
139+
</property>
140+
</spacer>
141+
</item>
142+
</layout>
143+
</item>
144+
</layout>
145+
</widget>
146+
<resources>
147+
<include location="../../../images/images.qrc"/>
148+
</resources>
149+
<connections/>
150+
</ui>

0 commit comments

Comments
 (0)
Please sign in to comment.