Skip to content

Commit

Permalink
Start on ui for configuring reports
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jan 5, 2018
1 parent 6db2432 commit c9ddc9f
Show file tree
Hide file tree
Showing 17 changed files with 697 additions and 1 deletion.
5 changes: 5 additions & 0 deletions python/core/layout/qgsabstractreportsection.sip
Expand Up @@ -69,6 +69,11 @@ Note that ownership is not transferred to ``parent``.
virtual QString type() const = 0;
%Docstring
Returns the section subclass type.
%End

virtual QString description() const = 0;
%Docstring
Returns a user-visible, translated description of the section.
%End

virtual QgsAbstractReportSection *clone() const = 0 /Factory/;
Expand Down
1 change: 1 addition & 0 deletions python/core/layout/qgsreport.sip
Expand Up @@ -39,6 +39,7 @@ Note that ownership is not transferred to ``project``.
%End

virtual QString type() const;
virtual QString description() const;
virtual QIcon icon() const;

virtual QgsProject *layoutProject() const;
Expand Down
2 changes: 2 additions & 0 deletions python/core/layout/qgsreportsectionfieldgroup.sip
Expand Up @@ -35,6 +35,8 @@ Note that ownership is not transferred to ``parent``.
%End

virtual QString type() const;
virtual QString description() const;


QgsLayout *body();
%Docstring
Expand Down
1 change: 1 addition & 0 deletions python/core/layout/qgsreportsectionlayout.sip
Expand Up @@ -34,6 +34,7 @@ Note that ownership is not transferred to ``parent``.
%End

virtual QString type() const;
virtual QString description() const;

QgsLayout *body();
%Docstring
Expand Down
4 changes: 4 additions & 0 deletions src/app/CMakeLists.txt
Expand Up @@ -204,6 +204,8 @@ SET(QGIS_APP_SRCS
layout/qgslayoutscalebarwidget.cpp
layout/qgslayoutshapewidget.cpp
layout/qgslayouttablebackgroundcolorsdialog.cpp
layout/qgsreportorganizerwidget.cpp
layout/qgsreportsectionmodel.cpp

locator/qgsinbuiltlocatorfilters.cpp
locator/qgslocatoroptionswidget.cpp
Expand Down Expand Up @@ -423,6 +425,8 @@ SET (QGIS_APP_MOC_HDRS
layout/qgslayoutscalebarwidget.h
layout/qgslayoutshapewidget.h
layout/qgslayouttablebackgroundcolorsdialog.h
layout/qgsreportorganizerwidget.h
layout/qgsreportsectionmodel.h

locator/qgsinbuiltlocatorfilters.h
locator/qgslocatoroptionswidget.h
Expand Down
32 changes: 31 additions & 1 deletion src/app/layout/qgslayoutdesignerdialog.cpp
Expand Up @@ -60,6 +60,7 @@
#include "qgslayoutatlaswidget.h"
#include "qgslayoutpagecollection.h"
#include "qgsreport.h"
#include "qgsreportorganizerwidget.h"
#include "ui_qgssvgexportoptions.h"
#include <QShortcut>
#include <QComboBox>
Expand Down Expand Up @@ -646,6 +647,9 @@ QgsLayoutDesignerDialog::QgsLayoutDesignerDialog( QWidget *parent, Qt::WindowFla
mAtlasDock = new QgsDockWidget( tr( "Atlas" ), this );
mAtlasDock->setObjectName( QStringLiteral( "AtlasDock" ) );

mReportDock = new QgsDockWidget( tr( "Report" ), this );
mReportDock->setObjectName( QStringLiteral( "ReportDock" ) );

const QList<QDockWidget *> docks = findChildren<QDockWidget *>();
for ( QDockWidget *dock : docks )
{
Expand All @@ -658,20 +662,23 @@ QgsLayoutDesignerDialog::QgsLayoutDesignerDialog( QWidget *parent, Qt::WindowFla
addDockWidget( Qt::RightDockWidgetArea, mUndoDock );
addDockWidget( Qt::RightDockWidgetArea, mItemsDock );
addDockWidget( Qt::RightDockWidgetArea, mAtlasDock );
addDockWidget( Qt::RightDockWidgetArea, mReportDock );

createLayoutPropertiesWidget();

mUndoDock->show();
mItemDock->show();
mGeneralDock->show();
mAtlasDock->show();
mReportDock->show();
mItemsDock->show();

tabifyDockWidget( mGeneralDock, mUndoDock );
tabifyDockWidget( mItemDock, mUndoDock );
tabifyDockWidget( mGeneralDock, mItemDock );
tabifyDockWidget( mItemDock, mItemsDock );
tabifyDockWidget( mItemDock, mAtlasDock );
tabifyDockWidget( mItemDock, mReportDock );

toggleActions( false );

Expand Down Expand Up @@ -739,6 +746,19 @@ void QgsLayoutDesignerDialog::setMasterLayout( QgsMasterLayoutInterface *layout
mMenuAtlas = nullptr;
mAtlasToolbar->hide();
}

if ( dynamic_cast< QgsReport * >( layout ) )
{
createReportWidget();
}
else
{
// ideally we'd only create mReportDock in createReportWidget() -
// but if we do that, then it's always brought to the focus
// in tab widgets
mReportDock->hide();
mPanelsMenu->removeAction( mReportDock->toggleViewAction() );
}
}

QgsMasterLayoutInterface *QgsLayoutDesignerDialog::masterLayout()
Expand Down Expand Up @@ -2680,7 +2700,7 @@ void QgsLayoutDesignerDialog::createLayoutPropertiesWidget()

void QgsLayoutDesignerDialog::createAtlasWidget()
{
QgsPrintLayout *printLayout = qobject_cast< QgsPrintLayout * >( mLayout );
QgsPrintLayout *printLayout = dynamic_cast< QgsPrintLayout * >( mMasterLayout );
QgsLayoutAtlas *atlas = printLayout->atlas();
QgsLayoutAtlasWidget *atlasWidget = new QgsLayoutAtlasWidget( mAtlasDock, printLayout );
atlasWidget->setMessageBar( mMessageBar );
Expand All @@ -2700,6 +2720,16 @@ void QgsLayoutDesignerDialog::createAtlasWidget()
toggleAtlasControls( atlas->enabled() && atlas->coverageLayer() );
}

void QgsLayoutDesignerDialog::createReportWidget()
{
QgsReport *report = dynamic_cast< QgsReport * >( mMasterLayout );
QgsReportOrganizerWidget *reportWidget = new QgsReportOrganizerWidget( mReportDock, this, report );
reportWidget->setMessageBar( mMessageBar );
mReportDock->setWidget( reportWidget );

mPanelsMenu->addAction( mReportDock->toggleViewAction() );
}

void QgsLayoutDesignerDialog::initializeRegistry()
{
sInitializedRegistry = true;
Expand Down
3 changes: 3 additions & 0 deletions src/app/layout/qgslayoutdesignerdialog.h
Expand Up @@ -373,6 +373,8 @@ class QgsLayoutDesignerDialog: public QMainWindow, private Ui::QgsLayoutDesigner
QgsDockWidget *mItemsDock = nullptr;
QgsLayoutItemsListView *mItemsTreeView = nullptr;

QgsDockWidget *mReportDock = nullptr;

QAction *mUndoAction = nullptr;
QAction *mRedoAction = nullptr;
//! Copy/cut/paste actions
Expand Down Expand Up @@ -406,6 +408,7 @@ class QgsLayoutDesignerDialog: public QMainWindow, private Ui::QgsLayoutDesigner

void createLayoutPropertiesWidget();
void createAtlasWidget();
void createReportWidget();

void initializeRegistry();

Expand Down
154 changes: 154 additions & 0 deletions src/app/layout/qgsreportorganizerwidget.cpp
@@ -0,0 +1,154 @@
/***************************************************************************
qgsreportorganizerwidget.cpp
------------------------
begin : December 2017
copyright : (C) 2017 by Nyall Dawson
email : nyall dot dawson at gmail dot 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 "qgsreportorganizerwidget.h"
#include "qgsreport.h"
#include "qgsreportsectionmodel.h"
#include "qgsreportsectionlayout.h"
#include "qgsreportsectionfieldgroup.h"
#include "qgslayout.h"
#include "qgslayoutdesignerdialog.h"
#include <QMenu>
#include <QMessageBox>

#ifdef ENABLE_MODELTEST
#include "modeltest.h"
#endif

QgsReportOrganizerWidget::QgsReportOrganizerWidget( QWidget *parent, QgsLayoutDesignerDialog *designer, QgsReport *report )
: QgsPanelWidget( parent )
, mReport( report )
, mDesigner( designer )
{
setupUi( this );
setPanelTitle( tr( "Report" ) );

mSectionModel = new QgsReportSectionModel( mReport, mViewSections );
mViewSections->setModel( mSectionModel );

#ifdef ENABLE_MODELTEST
//new ModelTest( mSectionModel, this );
#endif

mViewSections->setEditTriggers( QAbstractItemView::AllEditTriggers );

QMenu *addMenu = new QMenu( mButtonAddSection );
QAction *layoutSection = new QAction( tr( "Single section" ), addMenu );
addMenu->addAction( layoutSection );
connect( layoutSection, &QAction::triggered, this, &QgsReportOrganizerWidget::addLayoutSection );
QAction *fieldGroupSection = new QAction( tr( "Field group" ), addMenu );
addMenu->addAction( fieldGroupSection );
connect( fieldGroupSection, &QAction::triggered, this, &QgsReportOrganizerWidget::addFieldGroupSection );

connect( mCheckShowHeader, &QCheckBox::toggled, this, &QgsReportOrganizerWidget::toggleHeader );
connect( mCheckShowFooter, &QCheckBox::toggled, this, &QgsReportOrganizerWidget::toggleFooter );
connect( mButtonEditHeader, &QPushButton::clicked, this, &QgsReportOrganizerWidget::editHeader );
connect( mButtonEditFooter, &QPushButton::clicked, this, &QgsReportOrganizerWidget::editFooter );
connect( mViewSections->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsReportOrganizerWidget::selectionChanged );

mButtonAddSection->setMenu( addMenu );
connect( mButtonRemoveSection, &QPushButton::clicked, this, &QgsReportOrganizerWidget::removeSection );
}

void QgsReportOrganizerWidget::setMessageBar( QgsMessageBar *bar )
{
mMessageBar = bar;
}

void QgsReportOrganizerWidget::addLayoutSection()
{
std::unique_ptr< QgsReportSectionLayout > section = qgis::make_unique< QgsReportSectionLayout >();
mSectionModel->addSection( mViewSections->currentIndex(), std::move( section ) );
}

void QgsReportOrganizerWidget::addFieldGroupSection()
{
std::unique_ptr< QgsReportSectionFieldGroup > section = qgis::make_unique< QgsReportSectionFieldGroup >();
mSectionModel->addSection( mViewSections->currentIndex(), std::move( section ) );
}

void QgsReportOrganizerWidget::removeSection()
{
QgsAbstractReportSection *section = mSectionModel->sectionForIndex( mViewSections->currentIndex() );
if ( dynamic_cast< QgsReport * >( section ) )
return; //report cannot be removed

int res = QMessageBox::question( this, tr( "Remove Section" ),
tr( "Are you sure you want to remove the report section?" ),
QMessageBox::Yes | QMessageBox::No, QMessageBox::No );
if ( res == QMessageBox::No )
return;

mSectionModel->removeRow( mViewSections->currentIndex().row(), mViewSections->currentIndex().parent() );
}

void QgsReportOrganizerWidget::toggleHeader( bool enabled )
{
QgsAbstractReportSection *parent = mSectionModel->sectionForIndex( mViewSections->currentIndex() );
if ( !parent )
parent = mReport;
parent->setHeaderEnabled( enabled );
}

void QgsReportOrganizerWidget::toggleFooter( bool enabled )
{
QgsAbstractReportSection *parent = mSectionModel->sectionForIndex( mViewSections->currentIndex() );
if ( !parent )
parent = mReport;
parent->setFooterEnabled( enabled );
}

void QgsReportOrganizerWidget::editHeader()
{
QgsAbstractReportSection *parent = mSectionModel->sectionForIndex( mViewSections->currentIndex() );
if ( !parent )
parent = mReport;

if ( !parent->header() )
{
std::unique_ptr< QgsLayout > header = qgis::make_unique< QgsLayout >( mReport->layoutProject() );
header->initializeDefaults();
parent->setHeader( header.release() );
}

mDesigner->setCurrentLayout( parent->header() );
}

void QgsReportOrganizerWidget::editFooter()
{
QgsAbstractReportSection *parent = mSectionModel->sectionForIndex( mViewSections->currentIndex() );
if ( !parent )
parent = mReport;

if ( !parent->footer() )
{
std::unique_ptr< QgsLayout > footer = qgis::make_unique< QgsLayout >( mReport->layoutProject() );
footer->initializeDefaults();
parent->setFooter( footer.release() );
}

mDesigner->setCurrentLayout( parent->footer() );
}

void QgsReportOrganizerWidget::selectionChanged( const QModelIndex &current, const QModelIndex & )
{
QgsAbstractReportSection *parent = mSectionModel->sectionForIndex( current );
if ( !parent )
parent = mReport;

whileBlocking( mCheckShowHeader )->setChecked( parent->headerEnabled() );
whileBlocking( mCheckShowFooter )->setChecked( parent->footerEnabled() );
}
59 changes: 59 additions & 0 deletions src/app/layout/qgsreportorganizerwidget.h
@@ -0,0 +1,59 @@
/***************************************************************************
qgsreportorganizerwidget.h
----------------------
begin : December 2017
copyright : (C) 2017 by Nyall Dawson
email : nyall dot dawson at gmail dot 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 QGSREPORTORGANIZERWIDGET_H
#define QGSREPORTORGANIZERWIDGET_H

#include "ui_qgsreportorganizerwidgetbase.h"
#include "qgspanelwidget.h"
#include <QStyledItemDelegate>

class QgsReportSectionModel;
class QgsReport;
class QgsMessageBar;
class QgsLayoutDesignerDialog ;

class QgsReportOrganizerWidget: public QgsPanelWidget, private Ui::QgsReportOrganizerBase
{
Q_OBJECT
public:
QgsReportOrganizerWidget( QWidget *parent, QgsLayoutDesignerDialog *designer, QgsReport *report );

void setMessageBar( QgsMessageBar *bar );

private slots:

void addLayoutSection();
void addFieldGroupSection();
void removeSection();
void toggleHeader( bool enabled );
void toggleFooter( bool enabled );
void editHeader();
void editFooter();
void selectionChanged( const QModelIndex &current, const QModelIndex &previous );

private:

QgsReport *mReport = nullptr;
QgsReportSectionModel *mSectionModel = nullptr;
QgsMessageBar *mMessageBar;
QgsLayoutDesignerDialog *mDesigner = nullptr;

};



#endif // QGSREPORTORGANIZERWIDGET_H

0 comments on commit c9ddc9f

Please sign in to comment.