Skip to content
Permalink
Browse files

[FEATURE][composer] Advanced customisation of cell background color

for attribute tables

This allows users to set differing colors for alternating rows and
columns, first/last row/column and header row. Fixes #5131.

Sponsored by Ville de Morges
  • Loading branch information
nyalldawson committed Sep 5, 2015
1 parent 1c079ea commit 9133538a749eef63263923a375eeeddb53178d84
Showing with 1,403 additions and 127 deletions.
  1. +69 −0 python/core/composer/qgscomposertablev2.sip
  2. +2 −0 src/app/CMakeLists.txt
  3. +12 −0 src/app/composer/qgscomposerattributetablewidget.cpp
  4. +1 −0 src/app/composer/qgscomposerattributetablewidget.h
  5. +125 −0 src/app/composer/qgscomposertablebackgroundcolorsdialog.cpp
  6. +65 −0 src/app/composer/qgscomposertablebackgroundcolorsdialog.h
  7. +2 −1 src/core/composer/qgscomposermultiframecommand.h
  8. +177 −35 src/core/composer/qgscomposertablev2.cpp
  9. +83 −0 src/core/composer/qgscomposertablev2.h
  10. +97 −90 src/ui/composer/qgscomposerattributetablewidgetbase.ui
  11. +548 −0 src/ui/composer/qgscomposertablebackgroundstyles.ui
  12. +221 −0 tests/src/core/testqgscomposertablev2.cpp
  13. +1 −1 tests/src/python/test_qgsdoccoverage.py
  14. BIN ...es/composer_table/expected_composerattributetable_align/expected_composerattributetable_align.png
  15. BIN ...poser_table/expected_composerattributetable_autowrap/expected_composerattributetable_autowrap.png
  16. BIN ...ser_table/expected_composerattributetable_cellstyle/expected_composerattributetable_cellstyle.png
  17. BIN ...able/expected_composerattributetable_cellstyle/expected_composerattributetable_cellstyle_mask.png
  18. BIN ...table/expected_composerattributetable_columnwidth/expected_composerattributetable_columnwidth.png
  19. BIN ...ser_table/expected_composerattributetable_drawempty/expected_composerattributetable_drawempty.png
  20. BIN ...table/expected_composerattributetable_headersonly/expected_composerattributetable_headersonly.png
  21. BIN ...ser_table/expected_composerattributetable_multiline/expected_composerattributetable_multiline.png
  22. BIN .../composer_table/expected_composerattributetable_render/expected_composerattributetable_render.png
  23. BIN ...table/expected_composerattributetable_showmessage/expected_composerattributetable_showmessage.png
@@ -15,8 +15,47 @@ typedef QList< QList< QVariant > > QgsComposerTableContents;
*/
typedef QList<QgsComposerTableColumn*> QgsComposerTableColumns;


/** \ingroup MapComposer
* \class QgsComposerTableStyle
* \brief Styling option for a composer table cell
* \note added in QGIS 2.12
*/

class QgsComposerTableStyle
{
%TypeHeaderCode
#include <qgscomposertablev2.h>
%End
public:

QgsComposerTableStyle();

//! Whether the styling option is enabled
bool enabled;

//! Cell background color
QColor cellBackgroundColor;

/** Writes the style's properties to XML for storage.
* @param styleElem an existing QDomElement in which to store the style's properties.
* @param doc QDomDocument for the destination XML.
* @see readXML
*/
bool writeXML( QDomElement& styleElem, QDomDocument & doc ) const;

/** Reads the style's properties from XML.
* @param styleElem a QDomElement holding the style's desired properties.
* @see writeXML
*/
bool readXML( const QDomElement& styleElem );

};


/** A class to display a table in the print composer, and allow
* the table to span over multiple frames
* \ingroup MapComposer
* @note added in QGIS 2.5
*/
class QgsComposerTableV2: QgsComposerMultiFrame
@@ -63,6 +102,21 @@ class QgsComposerTableV2: QgsComposerMultiFrame
WrapText /*!< text which doesn't fit inside the cell is wrapped. Note that this only applies to text in columns with a fixed width. */
};

/** Row or column groups for cell styling
*/
enum CellStyleGroup
{
OddColumns, /*!< Style odd numbered columns */
EvenColumns, /*!< Style even numbered columns */
OddRows, /*!< Style odd numbered rows */
EvenRows, /*!< Style even numbered rows */
FirstColumn, /*!< Style first column only */
LastColumn, /*!< Style last column only */
HeaderRow, /*!< Style header row */
FirstRow, /*!< Style first row only */
LastRow /*!< Style last row only */
};

QgsComposerTableV2( QgsComposition* composition /TransferThis/, bool createUndoCommands );
QgsComposerTableV2();

@@ -299,6 +353,21 @@ class QgsComposerTableV2: QgsComposerMultiFrame
*/
void setColumns( QgsComposerTableColumns columns );

/** Sets the cell style for a cell group.
* @param group group to set style for
* @param style new cell style
* @see cellStyle()
* @note added in QGIS 2.12
*/
void setCellStyle( CellStyleGroup group, const QgsComposerTableStyle& style );

/** Returns the cell style for a cell group.
* @param group group to retreive style for
* @see setCellStyle()
* @note added in QGIS 2.12
*/
const QgsComposerTableStyle* cellStyle( CellStyleGroup group ) const;

/** Returns the text used in the column headers for the table.
* @returns QMap of int to QString, where the int is the column index (starting at 0),
* and the string is the text to use for the column's header
@@ -136,6 +136,7 @@ SET(QGIS_APP_SRCS
composer/qgscomposerscalebarwidget.cpp
composer/qgscomposershapewidget.cpp
composer/qgscomposertablewidget.cpp
composer/qgscomposertablebackgroundcolorsdialog.cpp
composer/qgscomposerlegenditemdialog.cpp
composer/qgscomposerlegendlayersdialog.cpp
composer/qgscomposerlegendwidget.cpp
@@ -288,6 +289,7 @@ SET (QGIS_APP_MOC_HDRS
composer/qgscomposerpicturewidget.h
composer/qgscomposerscalebarwidget.h
composer/qgscomposertablewidget.h
composer/qgscomposertablebackgroundcolorsdialog.h
composer/qgscomposershapewidget.h
composer/qgscompositionwidget.h
composer/qgsatlascompositionwidget.h
@@ -29,6 +29,7 @@
#include "qgsproject.h"
#include "qgsrelationmanager.h"
#include "qgisgui.h"
#include "qgscomposertablebackgroundcolorsdialog.h"

QgsComposerAttributeTableWidget::QgsComposerAttributeTableWidget( QgsComposerAttributeTableV2* table, QgsComposerFrame* frame )
: QgsComposerItemBaseWidget( 0, table )
@@ -1025,6 +1026,17 @@ void QgsComposerAttributeTableWidget::on_mWrapBehaviourComboBox_currentIndexChan
}
}

void QgsComposerAttributeTableWidget::on_mAdvancedCustomisationButton_clicked()
{
if ( !mComposerTable )
{
return;
}

QgsComposerTableBackgroundColorsDialog d( mComposerTable, this );
d.exec();
}

void QgsComposerAttributeTableWidget::on_mDrawEmptyCheckBox_toggled( bool checked )
{
if ( !mComposerTable )
@@ -80,6 +80,7 @@ class QgsComposerAttributeTableWidget: public QgsComposerItemBaseWidget, private
void on_mEmptyFrameCheckBox_toggled( bool checked );
void on_mHideEmptyBgCheckBox_toggled( bool checked );
void on_mWrapBehaviourComboBox_currentIndexChanged( int index );
void on_mAdvancedCustomisationButton_clicked();

/** Inserts a new maximum number of features into the spin box (without the spinbox emitting a signal)*/
void setMaximumNumberOfFeatures( int n );
@@ -0,0 +1,125 @@
/***************************************************************************
qgscomposertablebackgroundcolorsdialog.cpp
------------------------------------------
begin : August 2015
copyright : (C) 2015 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 "qgscomposertablebackgroundcolorsdialog.h"
#include "qgscomposertablev2.h"
#include "qgscomposition.h"
#include <QSettings>
#include <QCheckBox>
#include <QPushButton>

QgsComposerTableBackgroundColorsDialog::QgsComposerTableBackgroundColorsDialog( QgsComposerTableV2* table, QWidget* parent, Qt::WindowFlags flags )
: QDialog( parent, flags )
, mComposerTable( table )
{
setupUi( this );

mCheckBoxMap.insert( QgsComposerTableV2::OddColumns, mOddColumnsCheckBox );
mCheckBoxMap.insert( QgsComposerTableV2::EvenColumns, mEvenColumnsCheckBox );
mCheckBoxMap.insert( QgsComposerTableV2::OddRows, mOddRowsCheckBox );
mCheckBoxMap.insert( QgsComposerTableV2::EvenRows, mEvenRowsCheckBox );
mCheckBoxMap.insert( QgsComposerTableV2::FirstColumn, mFirstColumnCheckBox );
mCheckBoxMap.insert( QgsComposerTableV2::LastColumn, mLastColumnCheckBox );
mCheckBoxMap.insert( QgsComposerTableV2::HeaderRow, mHeaderRowCheckBox );
mCheckBoxMap.insert( QgsComposerTableV2::FirstRow, mFirstRowCheckBox );
mCheckBoxMap.insert( QgsComposerTableV2::LastRow, mLastRowCheckBox );

mColorButtonMap.insert( QgsComposerTableV2::OddColumns, mOddColumnsColorButton );
mColorButtonMap.insert( QgsComposerTableV2::EvenColumns, mEvenColumnsColorButton );
mColorButtonMap.insert( QgsComposerTableV2::OddRows, mOddRowsColorButton );
mColorButtonMap.insert( QgsComposerTableV2::EvenRows, mEvenRowsColorButton );
mColorButtonMap.insert( QgsComposerTableV2::FirstColumn, mFirstColumnColorButton );
mColorButtonMap.insert( QgsComposerTableV2::LastColumn, mLastColumnColorButton );
mColorButtonMap.insert( QgsComposerTableV2::HeaderRow, mHeaderRowColorButton );
mColorButtonMap.insert( QgsComposerTableV2::FirstRow, mFirstRowColorButton );
mColorButtonMap.insert( QgsComposerTableV2::LastRow, mLastRowColorButton );

connect( buttonBox->button( QDialogButtonBox::Apply ), SIGNAL( clicked() ), this, SLOT( apply() ) );

QSettings settings;
restoreGeometry( settings.value( "/Windows/ComposerTableBackgroundColorsDialog/geometry" ).toByteArray() );

setGuiElementValues();
}

QgsComposerTableBackgroundColorsDialog::~QgsComposerTableBackgroundColorsDialog()
{
QSettings settings;
settings.setValue( "/Windows/ComposerTableBackgroundColorsDialog/geometry", saveGeometry() );
}

void QgsComposerTableBackgroundColorsDialog::apply()
{
if ( !mComposerTable )
return;

QgsComposition* composition = mComposerTable->composition();
if ( composition )
{
composition->beginMultiFrameCommand( mComposerTable, tr( "Table background customisation" ), QgsComposerMultiFrameMergeCommand::TableCellStyle );
}

Q_FOREACH ( QgsComposerTableV2::CellStyleGroup styleGroup, mCheckBoxMap.keys() )
{
QgsComposerTableStyle style;
style.enabled = mCheckBoxMap.value( styleGroup )->isChecked();
style.cellBackgroundColor = mColorButtonMap.value( styleGroup )->color();

mComposerTable->setCellStyle( styleGroup, style );
}

mComposerTable->setBackgroundColor( mDefaultColorButton->color() );

if ( composition )
{
composition->endMultiFrameCommand();
}

mComposerTable->update();
}

void QgsComposerTableBackgroundColorsDialog::on_buttonBox_accepted()
{
apply();
accept();
}

void QgsComposerTableBackgroundColorsDialog::on_buttonBox_rejected()
{
reject();
}

void QgsComposerTableBackgroundColorsDialog::setGuiElementValues()
{
if ( !mComposerTable )
return;

Q_FOREACH ( QgsComposerTableV2::CellStyleGroup styleGroup, mCheckBoxMap.keys() )
{
mCheckBoxMap.value( styleGroup )->setChecked( mComposerTable->cellStyle( styleGroup )->enabled );
mColorButtonMap.value( styleGroup )->setEnabled( mComposerTable->cellStyle( styleGroup )->enabled );
mColorButtonMap.value( styleGroup )->setColor( mComposerTable->cellStyle( styleGroup )->cellBackgroundColor );
mColorButtonMap.value( styleGroup )->setAllowAlpha( true );
mColorButtonMap.value( styleGroup )->setColorDialogTitle( tr( "Select background color" ) );
}

mDefaultColorButton->setColor( mComposerTable->backgroundColor() );
mDefaultColorButton->setAllowAlpha( true );
mDefaultColorButton->setColorDialogTitle( tr( "Select background color" ) );
mDefaultColorButton->setShowNoColor( true );
mDefaultColorButton->setNoColorString( tr( "No background" ) );
}
@@ -0,0 +1,65 @@
/***************************************************************************
qgscomposertablebackgroundcolorsdialog.h
----------------------------------------
begin : August 2015
copyright : (C) 2015 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 QGSCOMPOSERTABLEBACKGROUNDCOLORSDIALOG_H
#define QGSCOMPOSERTABLEBACKGROUNDCOLORSDIALOG_H

#include <QDialog>
#include "ui_qgscomposertablebackgroundstyles.h"
#include "qgscomposertablev2.h"

class QCheckBox;
class QgsColorButtonV2;

/** A dialog for customisation of the cell background colors for a QgsComposerTableV2
* /note added in QGIS 2.12
*/
class QgsComposerTableBackgroundColorsDialog: public QDialog, private Ui::QgsComposerTableBackgroundDialog
{
Q_OBJECT
public:

/** Constructor for QgsComposerTableBackgroundColorsDialog
* @param table associated composer table
* @param parent parent widget
* @param flags window flags
*/
QgsComposerTableBackgroundColorsDialog( QgsComposerTableV2* table, QWidget* parent = 0, Qt::WindowFlags flags = 0 );

~QgsComposerTableBackgroundColorsDialog();

private slots:

void apply();

void on_buttonBox_accepted();
void on_buttonBox_rejected();

private:

QgsComposerTableV2* mComposerTable;
QMap< QgsComposerTableV2::CellStyleGroup, QCheckBox* > mCheckBoxMap;
QMap< QgsComposerTableV2::CellStyleGroup, QgsColorButtonV2* > mColorButtonMap;


/** Sets the GUI elements to the values of the table*/
void setGuiElementValues();


};

#endif // QGSCOMPOSERTABLEBACKGROUNDCOLORSDIALOG_H
@@ -73,7 +73,8 @@ class CORE_EXPORT QgsComposerMultiFrameMergeCommand: public QgsComposerMultiFram
//attribute table
TableMaximumFeatures,
TableMargin,
TableGridStrokeWidth
TableGridStrokeWidth,
TableCellStyle
};

QgsComposerMultiFrameMergeCommand( Context c, QgsComposerMultiFrame* multiFrame, const QString& text );

0 comments on commit 9133538

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