Skip to content

Commit 9133538

Browse files
committed
[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
1 parent 1c079ea commit 9133538

23 files changed

+1403
-127
lines changed

python/core/composer/qgscomposertablev2.sip

+69
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,47 @@ typedef QList< QList< QVariant > > QgsComposerTableContents;
1515
*/
1616
typedef QList<QgsComposerTableColumn*> QgsComposerTableColumns;
1717

18+
19+
/** \ingroup MapComposer
20+
* \class QgsComposerTableStyle
21+
* \brief Styling option for a composer table cell
22+
* \note added in QGIS 2.12
23+
*/
24+
25+
class QgsComposerTableStyle
26+
{
27+
%TypeHeaderCode
28+
#include <qgscomposertablev2.h>
29+
%End
30+
public:
31+
32+
QgsComposerTableStyle();
33+
34+
//! Whether the styling option is enabled
35+
bool enabled;
36+
37+
//! Cell background color
38+
QColor cellBackgroundColor;
39+
40+
/** Writes the style's properties to XML for storage.
41+
* @param styleElem an existing QDomElement in which to store the style's properties.
42+
* @param doc QDomDocument for the destination XML.
43+
* @see readXML
44+
*/
45+
bool writeXML( QDomElement& styleElem, QDomDocument & doc ) const;
46+
47+
/** Reads the style's properties from XML.
48+
* @param styleElem a QDomElement holding the style's desired properties.
49+
* @see writeXML
50+
*/
51+
bool readXML( const QDomElement& styleElem );
52+
53+
};
54+
55+
1856
/** A class to display a table in the print composer, and allow
1957
* the table to span over multiple frames
58+
* \ingroup MapComposer
2059
* @note added in QGIS 2.5
2160
*/
2261
class QgsComposerTableV2: QgsComposerMultiFrame
@@ -63,6 +102,21 @@ class QgsComposerTableV2: QgsComposerMultiFrame
63102
WrapText /*!< text which doesn't fit inside the cell is wrapped. Note that this only applies to text in columns with a fixed width. */
64103
};
65104

105+
/** Row or column groups for cell styling
106+
*/
107+
enum CellStyleGroup
108+
{
109+
OddColumns, /*!< Style odd numbered columns */
110+
EvenColumns, /*!< Style even numbered columns */
111+
OddRows, /*!< Style odd numbered rows */
112+
EvenRows, /*!< Style even numbered rows */
113+
FirstColumn, /*!< Style first column only */
114+
LastColumn, /*!< Style last column only */
115+
HeaderRow, /*!< Style header row */
116+
FirstRow, /*!< Style first row only */
117+
LastRow /*!< Style last row only */
118+
};
119+
66120
QgsComposerTableV2( QgsComposition* composition /TransferThis/, bool createUndoCommands );
67121
QgsComposerTableV2();
68122

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

356+
/** Sets the cell style for a cell group.
357+
* @param group group to set style for
358+
* @param style new cell style
359+
* @see cellStyle()
360+
* @note added in QGIS 2.12
361+
*/
362+
void setCellStyle( CellStyleGroup group, const QgsComposerTableStyle& style );
363+
364+
/** Returns the cell style for a cell group.
365+
* @param group group to retreive style for
366+
* @see setCellStyle()
367+
* @note added in QGIS 2.12
368+
*/
369+
const QgsComposerTableStyle* cellStyle( CellStyleGroup group ) const;
370+
302371
/** Returns the text used in the column headers for the table.
303372
* @returns QMap of int to QString, where the int is the column index (starting at 0),
304373
* and the string is the text to use for the column's header

src/app/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ SET(QGIS_APP_SRCS
136136
composer/qgscomposerscalebarwidget.cpp
137137
composer/qgscomposershapewidget.cpp
138138
composer/qgscomposertablewidget.cpp
139+
composer/qgscomposertablebackgroundcolorsdialog.cpp
139140
composer/qgscomposerlegenditemdialog.cpp
140141
composer/qgscomposerlegendlayersdialog.cpp
141142
composer/qgscomposerlegendwidget.cpp
@@ -288,6 +289,7 @@ SET (QGIS_APP_MOC_HDRS
288289
composer/qgscomposerpicturewidget.h
289290
composer/qgscomposerscalebarwidget.h
290291
composer/qgscomposertablewidget.h
292+
composer/qgscomposertablebackgroundcolorsdialog.h
291293
composer/qgscomposershapewidget.h
292294
composer/qgscompositionwidget.h
293295
composer/qgsatlascompositionwidget.h

src/app/composer/qgscomposerattributetablewidget.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "qgsproject.h"
3030
#include "qgsrelationmanager.h"
3131
#include "qgisgui.h"
32+
#include "qgscomposertablebackgroundcolorsdialog.h"
3233

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

1029+
void QgsComposerAttributeTableWidget::on_mAdvancedCustomisationButton_clicked()
1030+
{
1031+
if ( !mComposerTable )
1032+
{
1033+
return;
1034+
}
1035+
1036+
QgsComposerTableBackgroundColorsDialog d( mComposerTable, this );
1037+
d.exec();
1038+
}
1039+
10281040
void QgsComposerAttributeTableWidget::on_mDrawEmptyCheckBox_toggled( bool checked )
10291041
{
10301042
if ( !mComposerTable )

src/app/composer/qgscomposerattributetablewidget.h

+1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ class QgsComposerAttributeTableWidget: public QgsComposerItemBaseWidget, private
8080
void on_mEmptyFrameCheckBox_toggled( bool checked );
8181
void on_mHideEmptyBgCheckBox_toggled( bool checked );
8282
void on_mWrapBehaviourComboBox_currentIndexChanged( int index );
83+
void on_mAdvancedCustomisationButton_clicked();
8384

8485
/** Inserts a new maximum number of features into the spin box (without the spinbox emitting a signal)*/
8586
void setMaximumNumberOfFeatures( int n );
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/***************************************************************************
2+
qgscomposertablebackgroundcolorsdialog.cpp
3+
------------------------------------------
4+
begin : August 2015
5+
copyright : (C) 2015 by Nyall Dawson
6+
email : nyall dot dawson at gmail dot com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#include "qgscomposertablebackgroundcolorsdialog.h"
19+
#include "qgscomposertablev2.h"
20+
#include "qgscomposition.h"
21+
#include <QSettings>
22+
#include <QCheckBox>
23+
#include <QPushButton>
24+
25+
QgsComposerTableBackgroundColorsDialog::QgsComposerTableBackgroundColorsDialog( QgsComposerTableV2* table, QWidget* parent, Qt::WindowFlags flags )
26+
: QDialog( parent, flags )
27+
, mComposerTable( table )
28+
{
29+
setupUi( this );
30+
31+
mCheckBoxMap.insert( QgsComposerTableV2::OddColumns, mOddColumnsCheckBox );
32+
mCheckBoxMap.insert( QgsComposerTableV2::EvenColumns, mEvenColumnsCheckBox );
33+
mCheckBoxMap.insert( QgsComposerTableV2::OddRows, mOddRowsCheckBox );
34+
mCheckBoxMap.insert( QgsComposerTableV2::EvenRows, mEvenRowsCheckBox );
35+
mCheckBoxMap.insert( QgsComposerTableV2::FirstColumn, mFirstColumnCheckBox );
36+
mCheckBoxMap.insert( QgsComposerTableV2::LastColumn, mLastColumnCheckBox );
37+
mCheckBoxMap.insert( QgsComposerTableV2::HeaderRow, mHeaderRowCheckBox );
38+
mCheckBoxMap.insert( QgsComposerTableV2::FirstRow, mFirstRowCheckBox );
39+
mCheckBoxMap.insert( QgsComposerTableV2::LastRow, mLastRowCheckBox );
40+
41+
mColorButtonMap.insert( QgsComposerTableV2::OddColumns, mOddColumnsColorButton );
42+
mColorButtonMap.insert( QgsComposerTableV2::EvenColumns, mEvenColumnsColorButton );
43+
mColorButtonMap.insert( QgsComposerTableV2::OddRows, mOddRowsColorButton );
44+
mColorButtonMap.insert( QgsComposerTableV2::EvenRows, mEvenRowsColorButton );
45+
mColorButtonMap.insert( QgsComposerTableV2::FirstColumn, mFirstColumnColorButton );
46+
mColorButtonMap.insert( QgsComposerTableV2::LastColumn, mLastColumnColorButton );
47+
mColorButtonMap.insert( QgsComposerTableV2::HeaderRow, mHeaderRowColorButton );
48+
mColorButtonMap.insert( QgsComposerTableV2::FirstRow, mFirstRowColorButton );
49+
mColorButtonMap.insert( QgsComposerTableV2::LastRow, mLastRowColorButton );
50+
51+
connect( buttonBox->button( QDialogButtonBox::Apply ), SIGNAL( clicked() ), this, SLOT( apply() ) );
52+
53+
QSettings settings;
54+
restoreGeometry( settings.value( "/Windows/ComposerTableBackgroundColorsDialog/geometry" ).toByteArray() );
55+
56+
setGuiElementValues();
57+
}
58+
59+
QgsComposerTableBackgroundColorsDialog::~QgsComposerTableBackgroundColorsDialog()
60+
{
61+
QSettings settings;
62+
settings.setValue( "/Windows/ComposerTableBackgroundColorsDialog/geometry", saveGeometry() );
63+
}
64+
65+
void QgsComposerTableBackgroundColorsDialog::apply()
66+
{
67+
if ( !mComposerTable )
68+
return;
69+
70+
QgsComposition* composition = mComposerTable->composition();
71+
if ( composition )
72+
{
73+
composition->beginMultiFrameCommand( mComposerTable, tr( "Table background customisation" ), QgsComposerMultiFrameMergeCommand::TableCellStyle );
74+
}
75+
76+
Q_FOREACH ( QgsComposerTableV2::CellStyleGroup styleGroup, mCheckBoxMap.keys() )
77+
{
78+
QgsComposerTableStyle style;
79+
style.enabled = mCheckBoxMap.value( styleGroup )->isChecked();
80+
style.cellBackgroundColor = mColorButtonMap.value( styleGroup )->color();
81+
82+
mComposerTable->setCellStyle( styleGroup, style );
83+
}
84+
85+
mComposerTable->setBackgroundColor( mDefaultColorButton->color() );
86+
87+
if ( composition )
88+
{
89+
composition->endMultiFrameCommand();
90+
}
91+
92+
mComposerTable->update();
93+
}
94+
95+
void QgsComposerTableBackgroundColorsDialog::on_buttonBox_accepted()
96+
{
97+
apply();
98+
accept();
99+
}
100+
101+
void QgsComposerTableBackgroundColorsDialog::on_buttonBox_rejected()
102+
{
103+
reject();
104+
}
105+
106+
void QgsComposerTableBackgroundColorsDialog::setGuiElementValues()
107+
{
108+
if ( !mComposerTable )
109+
return;
110+
111+
Q_FOREACH ( QgsComposerTableV2::CellStyleGroup styleGroup, mCheckBoxMap.keys() )
112+
{
113+
mCheckBoxMap.value( styleGroup )->setChecked( mComposerTable->cellStyle( styleGroup )->enabled );
114+
mColorButtonMap.value( styleGroup )->setEnabled( mComposerTable->cellStyle( styleGroup )->enabled );
115+
mColorButtonMap.value( styleGroup )->setColor( mComposerTable->cellStyle( styleGroup )->cellBackgroundColor );
116+
mColorButtonMap.value( styleGroup )->setAllowAlpha( true );
117+
mColorButtonMap.value( styleGroup )->setColorDialogTitle( tr( "Select background color" ) );
118+
}
119+
120+
mDefaultColorButton->setColor( mComposerTable->backgroundColor() );
121+
mDefaultColorButton->setAllowAlpha( true );
122+
mDefaultColorButton->setColorDialogTitle( tr( "Select background color" ) );
123+
mDefaultColorButton->setShowNoColor( true );
124+
mDefaultColorButton->setNoColorString( tr( "No background" ) );
125+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/***************************************************************************
2+
qgscomposertablebackgroundcolorsdialog.h
3+
----------------------------------------
4+
begin : August 2015
5+
copyright : (C) 2015 by Nyall Dawson
6+
email : nyall dot dawson at gmail dot com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#ifndef QGSCOMPOSERTABLEBACKGROUNDCOLORSDIALOG_H
19+
#define QGSCOMPOSERTABLEBACKGROUNDCOLORSDIALOG_H
20+
21+
#include <QDialog>
22+
#include "ui_qgscomposertablebackgroundstyles.h"
23+
#include "qgscomposertablev2.h"
24+
25+
class QCheckBox;
26+
class QgsColorButtonV2;
27+
28+
/** A dialog for customisation of the cell background colors for a QgsComposerTableV2
29+
* /note added in QGIS 2.12
30+
*/
31+
class QgsComposerTableBackgroundColorsDialog: public QDialog, private Ui::QgsComposerTableBackgroundDialog
32+
{
33+
Q_OBJECT
34+
public:
35+
36+
/** Constructor for QgsComposerTableBackgroundColorsDialog
37+
* @param table associated composer table
38+
* @param parent parent widget
39+
* @param flags window flags
40+
*/
41+
QgsComposerTableBackgroundColorsDialog( QgsComposerTableV2* table, QWidget* parent = 0, Qt::WindowFlags flags = 0 );
42+
43+
~QgsComposerTableBackgroundColorsDialog();
44+
45+
private slots:
46+
47+
void apply();
48+
49+
void on_buttonBox_accepted();
50+
void on_buttonBox_rejected();
51+
52+
private:
53+
54+
QgsComposerTableV2* mComposerTable;
55+
QMap< QgsComposerTableV2::CellStyleGroup, QCheckBox* > mCheckBoxMap;
56+
QMap< QgsComposerTableV2::CellStyleGroup, QgsColorButtonV2* > mColorButtonMap;
57+
58+
59+
/** Sets the GUI elements to the values of the table*/
60+
void setGuiElementValues();
61+
62+
63+
};
64+
65+
#endif // QGSCOMPOSERTABLEBACKGROUNDCOLORSDIALOG_H

src/core/composer/qgscomposermultiframecommand.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ class CORE_EXPORT QgsComposerMultiFrameMergeCommand: public QgsComposerMultiFram
7373
//attribute table
7474
TableMaximumFeatures,
7575
TableMargin,
76-
TableGridStrokeWidth
76+
TableGridStrokeWidth,
77+
TableCellStyle
7778
};
7879

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

0 commit comments

Comments
 (0)