Skip to content

Commit 1f9b9c8

Browse files
committedJul 14, 2020
[feature][layouts] Allow cells in manual text tables to have expression
based contents Allows individual cells from a manual text table to take their contents from a preset expression. Expressions have access to the full layout item expression context, allowing cells to calculate and display metadata style values or aggregate based calculations. Sponsored by City of Canning
1 parent 8e3151a commit 1f9b9c8

11 files changed

+314
-21
lines changed
 

‎python/gui/auto_generated/tableeditor/qgstableeditordialog.sip.in

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,14 @@ Returns the table header values.
116116
Sets the table ``headers``.
117117

118118
.. seealso:: :py:func:`tableHeaders`
119+
%End
120+
121+
void registerExpressionContextGenerator( QgsExpressionContextGenerator *generator );
122+
%Docstring
123+
Register an expression context generator class that will be used to retrieve
124+
an expression context for the editor when required.
125+
126+
.. versionadded:: 3.16
119127
%End
120128

121129
signals:

‎python/gui/auto_generated/tableeditor/qgstableeditorwidget.sip.in

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,16 @@ If the returned value contains both horizontal and vertical alignment flags, the
118118
the selected cells have a mix of different vertical alignments.
119119

120120
.. seealso:: :py:func:`selectionVerticalAlignment`
121+
%End
122+
123+
QgsProperty selectionCellProperty();
124+
%Docstring
125+
Returns the QgsProperty used for the contents of the currently selected cells.
126+
127+
If the returned value is a default constructed :py:class:`QgsProperty`, then the selected
128+
cells have a mix of different properties.
129+
130+
.. versionadded:: 3.16
121131
%End
122132

123133
QgsTextFormat selectionTextFormat();
@@ -305,6 +315,13 @@ Sets the vertical alignment for the currently selected cells.
305315

306316
.. seealso:: :py:func:`setSelectionHorizontalAlignment`
307317

318+
.. versionadded:: 3.16
319+
%End
320+
321+
void setSelectionCellProperty( const QgsProperty &property );
322+
%Docstring
323+
Sets the cell contents QgsProperty for the currently selected cells.
324+
308325
.. versionadded:: 3.16
309326
%End
310327

‎src/gui/layout/qgslayoutmanualtablewidget.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ void QgsLayoutManualTableWidget::setTableContents()
161161
else
162162
{
163163
mEditorDialog = new QgsTableEditorDialog( this );
164+
mEditorDialog->registerExpressionContextGenerator( mTable );
164165
connect( this, &QWidget::destroyed, mEditorDialog, &QMainWindow::close );
165166

166167
mEditorDialog->setIncludeTableHeader( mTable->includeTableHeader() );

‎src/gui/tableeditor/qgstableeditordialog.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ QgsTableEditorDialog::QgsTableEditorDialog( QWidget *parent )
6464

6565
int minDockWidth( fontMetrics().boundingRect( QStringLiteral( "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" ) ).width() );
6666

67-
mPropertiesDock = new QgsDockWidget( tr( "Formatting" ), this );
67+
mPropertiesDock = new QgsDockWidget( tr( "Cell Contents" ), this );
6868
mPropertiesDock->setObjectName( QStringLiteral( "FormattingDock" ) );
6969
mPropertiesStack = new QgsPanelWidgetStack();
7070
mPropertiesDock->setWidget( mPropertiesStack );
@@ -81,6 +81,7 @@ QgsTableEditorDialog::QgsTableEditorDialog( QWidget *parent )
8181

8282
connect( mFormattingWidget, &QgsTableEditorFormattingWidget::horizontalAlignmentChanged, mTableWidget, &QgsTableEditorWidget::setSelectionHorizontalAlignment );
8383
connect( mFormattingWidget, &QgsTableEditorFormattingWidget::verticalAlignmentChanged, mTableWidget, &QgsTableEditorWidget::setSelectionVerticalAlignment );
84+
connect( mFormattingWidget, &QgsTableEditorFormattingWidget::cellPropertyChanged, mTableWidget, &QgsTableEditorWidget::setSelectionCellProperty );
8485

8586
connect( mFormattingWidget, &QgsTableEditorFormattingWidget::textFormatChanged, this, [ = ]
8687
{
@@ -104,6 +105,7 @@ QgsTableEditorDialog::QgsTableEditorDialog( QWidget *parent )
104105
mFormattingWidget->setTextFormat( mTableWidget->selectionTextFormat() );
105106
mFormattingWidget->setHorizontalAlignment( mTableWidget->selectionHorizontalAlignment() );
106107
mFormattingWidget->setVerticalAlignment( mTableWidget->selectionVerticalAlignment() );
108+
mFormattingWidget->setCellProperty( mTableWidget->selectionCellProperty() );
107109

108110
updateActionNamesFromSelection();
109111

@@ -225,6 +227,11 @@ void QgsTableEditorDialog::setTableHeaders( const QVariantList &headers )
225227
mTableWidget->setTableHeaders( headers );
226228
}
227229

230+
void QgsTableEditorDialog::registerExpressionContextGenerator( QgsExpressionContextGenerator *generator )
231+
{
232+
mFormattingWidget->registerExpressionContextGenerator( generator );
233+
}
234+
228235
void QgsTableEditorDialog::updateActionNamesFromSelection()
229236
{
230237
const int rowCount = mTableWidget->rowsAssociatedWithSelection().size();

‎src/gui/tableeditor/qgstableeditordialog.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class QgsMessageBar;
2525
class QgsDockWidget;
2626
class QgsPanelWidgetStack;
2727
class QgsTableEditorFormattingWidget;
28+
class QgsExpressionContextGenerator;
2829

2930
/**
3031
* \ingroup gui
@@ -134,6 +135,13 @@ class GUI_EXPORT QgsTableEditorDialog : public QMainWindow, private Ui::QgsTable
134135
*/
135136
void setTableHeaders( const QVariantList &headers );
136137

138+
/**
139+
* Register an expression context generator class that will be used to retrieve
140+
* an expression context for the editor when required.
141+
* \since QGIS 3.16
142+
*/
143+
void registerExpressionContextGenerator( QgsExpressionContextGenerator *generator );
144+
137145
signals:
138146

139147
/**

‎src/gui/tableeditor/qgstableeditorformattingwidget.cpp

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@
1717
#include "qgsnumericformatselectorwidget.h"
1818
#include "qgsnumericformat.h"
1919
#include "qgis.h"
20+
#include "qgsproperty.h"
2021

2122
QgsTableEditorFormattingWidget::QgsTableEditorFormattingWidget( QWidget *parent )
2223
: QgsPanelWidget( parent )
2324
{
2425
setupUi( this );
25-
setPanelTitle( tr( "Formatting" ) );
26+
setPanelTitle( tr( "Cell Contents" ) );
2627

2728
mFormatNumbersCheckBox->setTristate( false );
2829

@@ -132,6 +133,19 @@ QgsTableEditorFormattingWidget::QgsTableEditorFormattingWidget( QWidget *parent
132133
emit verticalAlignmentChanged( mVerticalAlignComboBox->currentAlignment() );
133134
}
134135
} );
136+
137+
connect( mExpressionEdit, qgis::overload<const QString &>::of( &QgsFieldExpressionWidget::fieldChanged ), this, [ = ]( const QString & expression )
138+
{
139+
if ( !mBlockSignals )
140+
{
141+
emit cellPropertyChanged( expression.isEmpty() ? QgsProperty() : QgsProperty::fromExpression( expression ) );
142+
}
143+
} );
144+
145+
mExpressionEdit->setAllowEmptyFieldName( true );
146+
147+
mExpressionEdit->registerExpressionContextGenerator( this );
148+
mFontButton->registerExpressionContextGenerator( this );
135149
}
136150

137151
QgsNumericFormat *QgsTableEditorFormattingWidget::numericFormat()
@@ -219,4 +233,35 @@ void QgsTableEditorFormattingWidget::setVerticalAlignment( Qt::Alignment alignme
219233
mBlockSignals--;
220234
}
221235

236+
void QgsTableEditorFormattingWidget::setCellProperty( const QgsProperty &property )
237+
{
238+
mBlockSignals++;
239+
if ( !property.isActive() )
240+
mExpressionEdit->setExpression( QString() );
241+
else
242+
mExpressionEdit->setExpression( property.asExpression() );
243+
mBlockSignals--;
244+
}
245+
246+
void QgsTableEditorFormattingWidget::registerExpressionContextGenerator( QgsExpressionContextGenerator *generator )
247+
{
248+
mContextGenerator = generator;
249+
}
250+
251+
QgsExpressionContext QgsTableEditorFormattingWidget::createExpressionContext() const
252+
{
253+
QgsExpressionContext context;
254+
if ( mContextGenerator )
255+
context = mContextGenerator->createExpressionContext();
256+
257+
QgsExpressionContextScope *cellScope = new QgsExpressionContextScope();
258+
// TODO -- could set real row/column numbers here, in certain circumstances...
259+
cellScope->setVariable( QStringLiteral( "row_number" ), 0 );
260+
cellScope->setVariable( QStringLiteral( "column_number" ), 0 );
261+
context.appendScope( cellScope );
262+
263+
context.setHighlightedVariables( QStringList() << QStringLiteral( "row_number" ) << QStringLiteral( "column_number" ) );
264+
return context;
265+
}
266+
222267
QgsTableEditorFormattingWidget::~QgsTableEditorFormattingWidget() = default;

‎src/gui/tableeditor/qgstableeditorformattingwidget.h

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@
1818
#include "qgis_gui.h"
1919
#include "ui_qgstableeditorformattingwidgetbase.h"
2020
#include "qgspanelwidget.h"
21+
#include "qgsexpressioncontextgenerator.h"
2122
#include <memory>
2223

2324
#define SIP_NO_FILE
2425

2526
class QgsNumericFormat;
27+
class QgsProperty;
2628

2729
/**
2830
* \ingroup gui
@@ -36,7 +38,7 @@ class QgsNumericFormat;
3638
*
3739
* \since QGIS 3.12
3840
*/
39-
class GUI_EXPORT QgsTableEditorFormattingWidget : public QgsPanelWidget, private Ui::QgsTableEditorFormattingWidgetBase
41+
class GUI_EXPORT QgsTableEditorFormattingWidget : public QgsPanelWidget, public QgsExpressionContextGenerator, private Ui::QgsTableEditorFormattingWidgetBase
4042
{
4143
Q_OBJECT
4244
public:
@@ -134,6 +136,22 @@ class GUI_EXPORT QgsTableEditorFormattingWidget : public QgsPanelWidget, private
134136
*/
135137
void setVerticalAlignment( Qt::Alignment alignment );
136138

139+
/**
140+
* Sets the cell content's \a property to show in the widget.
141+
*
142+
* \since QGIS 3.16
143+
*/
144+
void setCellProperty( const QgsProperty &property );
145+
146+
/**
147+
* Register an expression context generator class that will be used to retrieve
148+
* an expression context for the widget when required.
149+
* \since QGIS 3.16
150+
*/
151+
void registerExpressionContextGenerator( QgsExpressionContextGenerator *generator );
152+
153+
QgsExpressionContext createExpressionContext() const override;
154+
137155
signals:
138156

139157
/**
@@ -186,10 +204,18 @@ class GUI_EXPORT QgsTableEditorFormattingWidget : public QgsPanelWidget, private
186204
*/
187205
void verticalAlignmentChanged( Qt::Alignment alignment );
188206

207+
/**
208+
* Emitted when the cell contents \a property shown in the widget is changed.
209+
*
210+
* \since QGIS 3.16
211+
*/
212+
void cellPropertyChanged( const QgsProperty &property );
213+
189214
private:
190215

191216
std::unique_ptr< QgsNumericFormat > mNumericFormat;
192217
int mBlockSignals = 0;
218+
QgsExpressionContextGenerator *mContextGenerator = nullptr;
193219

194220
};
195221

‎src/gui/tableeditor/qgstableeditorwidget.cpp

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -320,14 +320,19 @@ void QgsTableEditorWidget::setTableContents( const QgsTableContents &contents )
320320
int colNumber = 0;
321321
for ( const QgsTableCell &col : row )
322322
{
323-
QTableWidgetItem *item = new QTableWidgetItem( col.content().toString() );
323+
QTableWidgetItem *item = new QTableWidgetItem( col.content().value< QgsProperty >().isActive() ? col.content().value< QgsProperty >().asExpression() : col.content().toString() );
324324
item->setData( CellContent, col.content() ); // can't use EditRole, because Qt. (https://bugreports.qt.io/browse/QTBUG-11549)
325325
item->setData( Qt::BackgroundRole, col.backgroundColor().isValid() ? col.backgroundColor() : QColor( 255, 255, 255 ) );
326326
item->setData( PresetBackgroundColorRole, col.backgroundColor().isValid() ? col.backgroundColor() : QVariant() );
327327
item->setData( Qt::ForegroundRole, col.foregroundColor().isValid() ? col.foregroundColor() : QVariant() );
328328
item->setData( TextFormat, QVariant::fromValue( col.textFormat() ) );
329329
item->setData( HorizontalAlignment, static_cast< int >( col.horizontalAlignment() ) );
330330
item->setData( VerticalAlignment, static_cast< int >( col.verticalAlignment() ) );
331+
item->setData( CellProperty, QVariant::fromValue( col.content().value< QgsProperty >() ) );
332+
333+
if ( col.content().value< QgsProperty >().isActive() )
334+
item->setFlags( item->flags() & ( ~Qt::ItemIsEditable ) );
335+
331336
if ( col.numericFormat() )
332337
{
333338
mNumericFormats.insert( item, col.numericFormat()->clone() );
@@ -365,7 +370,7 @@ QgsTableContents QgsTableEditorWidget::tableContents() const
365370
QgsTableCell cell;
366371
if ( QTableWidgetItem *i = item( r, c ) )
367372
{
368-
cell.setContent( i->data( CellContent ) );
373+
cell.setContent( i->data( CellProperty ).value< QgsProperty >().isActive() ? i->data( CellProperty ) : i->data( CellContent ) );
369374
cell.setBackgroundColor( i->data( PresetBackgroundColorRole ).value< QColor >() );
370375
cell.setForegroundColor( i->data( Qt::ForegroundRole ).value< QColor >() );
371376
cell.setTextFormat( i->data( TextFormat ).value< QgsTextFormat >() );
@@ -579,6 +584,29 @@ Qt::Alignment QgsTableEditorWidget::selectionVerticalAlignment()
579584
return alignment;
580585
}
581586

587+
QgsProperty QgsTableEditorWidget::selectionCellProperty()
588+
{
589+
QgsProperty property;
590+
bool first = true;
591+
const QModelIndexList selection = selectedIndexes();
592+
for ( const QModelIndex &index : selection )
593+
{
594+
const QgsProperty cellProperty = model()->data( index, CellProperty ).value< QgsProperty >();
595+
if ( first )
596+
{
597+
property = cellProperty;
598+
first = false;
599+
}
600+
else if ( cellProperty == property )
601+
continue;
602+
else
603+
{
604+
return QgsProperty();
605+
}
606+
}
607+
return property;
608+
}
609+
582610
QgsTextFormat QgsTableEditorWidget::selectionTextFormat()
583611
{
584612
QgsTextFormat format;
@@ -1046,6 +1074,57 @@ void QgsTableEditorWidget::setSelectionVerticalAlignment( Qt::Alignment alignmen
10461074
emit tableChanged();
10471075
}
10481076

1077+
void QgsTableEditorWidget::setSelectionCellProperty( const QgsProperty &property )
1078+
{
1079+
const QModelIndexList selection = selectedIndexes();
1080+
bool changed = false;
1081+
mBlockSignals++;
1082+
for ( const QModelIndex &index : selection )
1083+
{
1084+
if ( index.row() == 0 && mIncludeHeader )
1085+
continue;
1086+
1087+
if ( QTableWidgetItem *i = item( index.row(), index.column() ) )
1088+
{
1089+
if ( i->data( CellProperty ).value< QgsProperty >() != property )
1090+
{
1091+
if ( property.isActive() )
1092+
{
1093+
i->setData( CellProperty, QVariant::fromValue( property ) );
1094+
i->setText( property.asExpression() );
1095+
i->setFlags( i->flags() & ( ~Qt::ItemIsEditable ) );
1096+
}
1097+
else
1098+
{
1099+
i->setData( CellProperty, QVariant() );
1100+
i->setText( QString() );
1101+
i->setFlags( i->flags() | Qt::ItemIsEditable );
1102+
}
1103+
changed = true;
1104+
}
1105+
}
1106+
else
1107+
{
1108+
QTableWidgetItem *newItem = new QTableWidgetItem( property.asExpression() );
1109+
if ( property.isActive() )
1110+
{
1111+
newItem->setData( CellProperty, QVariant::fromValue( property ) );
1112+
newItem->setFlags( newItem->flags() & ( ~Qt::ItemIsEditable ) );
1113+
}
1114+
else
1115+
{
1116+
newItem->setData( CellProperty, QVariant() );
1117+
newItem->setFlags( newItem->flags() | Qt::ItemIsEditable );
1118+
}
1119+
setItem( index.row(), index.column(), newItem );
1120+
changed = true;
1121+
}
1122+
}
1123+
mBlockSignals--;
1124+
if ( changed && !mBlockSignals )
1125+
emit tableChanged();
1126+
}
1127+
10491128
void QgsTableEditorWidget::setSelectionTextFormat( const QgsTextFormat &format )
10501129
{
10511130
const QModelIndexList selection = selectedIndexes();
@@ -1351,7 +1430,7 @@ void QgsTableEditorDelegate::setModelData( QWidget *editor, QAbstractItemModel *
13511430
if ( QgsTableEditorTextEdit *lineEdit = qobject_cast<QgsTableEditorTextEdit * >( editor ) )
13521431
{
13531432
const QString text = lineEdit->toPlainText();
1354-
if ( text != model->data( index, QgsTableEditorWidget::CellContent ).toString() )
1433+
if ( text != model->data( index, QgsTableEditorWidget::CellContent ).toString() && !model->data( index, QgsTableEditorWidget::CellProperty ).value< QgsProperty >().isActive() )
13551434
{
13561435
model->setData( index, text, QgsTableEditorWidget::CellContent );
13571436
model->setData( index, text, Qt::DisplayRole );

‎src/gui/tableeditor/qgstableeditorwidget.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "qgis_gui.h"
2222
#include "qgstablecell.h"
23+
#include "qgsproperty.h"
2324
#include <QTableWidget>
2425
#include <QPlainTextEdit>
2526
#include <QStyledItemDelegate>
@@ -202,6 +203,16 @@ class GUI_EXPORT QgsTableEditorWidget : public QTableWidget
202203
*/
203204
Qt::Alignment selectionVerticalAlignment();
204205

206+
/**
207+
* Returns the QgsProperty used for the contents of the currently selected cells.
208+
*
209+
* If the returned value is a default constructed QgsProperty, then the selected
210+
* cells have a mix of different properties.
211+
*
212+
* \since QGIS 3.16
213+
*/
214+
QgsProperty selectionCellProperty();
215+
205216
/**
206217
* Returns the text format for the currently selected cells.
207218
*
@@ -384,6 +395,13 @@ class GUI_EXPORT QgsTableEditorWidget : public QTableWidget
384395
*/
385396
void setSelectionVerticalAlignment( Qt::Alignment alignment );
386397

398+
/**
399+
* Sets the cell contents QgsProperty for the currently selected cells.
400+
*
401+
* \since QGIS 3.16
402+
*/
403+
void setSelectionCellProperty( const QgsProperty &property );
404+
387405
/**
388406
* Sets the text \a format for the selected cells.
389407
*
@@ -449,7 +467,8 @@ class GUI_EXPORT QgsTableEditorWidget : public QTableWidget
449467
CellContent,
450468
TextFormat,
451469
HorizontalAlignment,
452-
VerticalAlignment
470+
VerticalAlignment,
471+
CellProperty,
453472
};
454473

455474
void updateHeaders();

‎src/ui/qgstableeditorformattingwidgetbase.ui

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,28 @@
4646
<height>464</height>
4747
</rect>
4848
</property>
49-
<layout class="QVBoxLayout" name="mainLayout">
50-
<item>
49+
<layout class="QGridLayout" name="gridLayout">
50+
<item row="5" column="0">
51+
<spacer name="verticalSpacer">
52+
<property name="orientation">
53+
<enum>Qt::Vertical</enum>
54+
</property>
55+
<property name="sizeHint" stdset="0">
56+
<size>
57+
<width>20</width>
58+
<height>0</height>
59+
</size>
60+
</property>
61+
</spacer>
62+
</item>
63+
<item row="0" column="0">
64+
<widget class="QLabel" name="label_5">
65+
<property name="text">
66+
<string>Expression</string>
67+
</property>
68+
</widget>
69+
</item>
70+
<item row="2" column="0" colspan="2">
5171
<widget class="QGroupBox" name="groupBox_6">
5272
<property name="focusPolicy">
5373
<enum>Qt::StrongFocus</enum>
@@ -130,7 +150,7 @@
130150
</layout>
131151
</widget>
132152
</item>
133-
<item>
153+
<item row="3" column="0" colspan="2">
134154
<widget class="QGroupBox" name="groupBox_7">
135155
<property name="focusPolicy">
136156
<enum>Qt::StrongFocus</enum>
@@ -202,7 +222,7 @@
202222
</layout>
203223
</widget>
204224
</item>
205-
<item>
225+
<item row="4" column="0" colspan="2">
206226
<widget class="QGroupBox" name="groupBox_8">
207227
<property name="focusPolicy">
208228
<enum>Qt::StrongFocus</enum>
@@ -254,18 +274,18 @@
254274
</layout>
255275
</widget>
256276
</item>
257-
<item>
258-
<spacer name="verticalSpacer">
259-
<property name="orientation">
260-
<enum>Qt::Vertical</enum>
277+
<item row="0" column="1">
278+
<widget class="QgsFieldExpressionWidget" name="mExpressionEdit" native="true">
279+
<property name="sizePolicy">
280+
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
281+
<horstretch>0</horstretch>
282+
<verstretch>0</verstretch>
283+
</sizepolicy>
261284
</property>
262-
<property name="sizeHint" stdset="0">
263-
<size>
264-
<width>20</width>
265-
<height>0</height>
266-
</size>
285+
<property name="focusPolicy">
286+
<enum>Qt::StrongFocus</enum>
267287
</property>
268-
</spacer>
288+
</widget>
269289
</item>
270290
</layout>
271291
</widget>
@@ -301,6 +321,12 @@
301321
<extends>QComboBox</extends>
302322
<header>qgsalignmentcombobox.h</header>
303323
</customwidget>
324+
<customwidget>
325+
<class>QgsFieldExpressionWidget</class>
326+
<extends>QWidget</extends>
327+
<header>qgsfieldexpressionwidget.h</header>
328+
<container>1</container>
329+
</customwidget>
304330
</customwidgets>
305331
<tabstops>
306332
<tabstop>groupBox_6</tabstop>

‎tests/src/gui/testqgstableeditor.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class TestQgsTableEditor: public QObject
4141
void foregroundColor();
4242
void backgroundColor();
4343
void alignment();
44+
void properties();
4445
void textFormat();
4546
void numericFormat();
4647
void rowHeight();
@@ -924,6 +925,62 @@ void TestQgsTableEditor::alignment()
924925
QCOMPARE( w.selectionVerticalAlignment(), Qt::AlignLeft | Qt::AlignTop );
925926
}
926927

928+
void TestQgsTableEditor::properties()
929+
{
930+
QgsTableEditorWidget w;
931+
QVERIFY( w.tableContents().isEmpty() );
932+
933+
QSignalSpy spy( &w, &QgsTableEditorWidget::tableChanged );
934+
QgsTableCell c3;
935+
c3.setContent( 87 );
936+
std::unique_ptr< QgsCurrencyNumericFormat > format = qgis::make_unique< QgsCurrencyNumericFormat >();
937+
format->setNumberDecimalPlaces( 2 );
938+
format->setPrefix( QStringLiteral( "$" ) );
939+
c3.setNumericFormat( format.release() );
940+
QgsTableCell c2( QVariant::fromValue( QgsProperty::fromExpression( "1+2" ) ) );
941+
w.setTableContents( QgsTableContents() << ( QgsTableRow() << QgsTableCell( QStringLiteral( "Jet" ) ) << c2 << c3 << QgsTableCell( QStringLiteral( "Jet3" ) ) ) );
942+
QCOMPARE( spy.count(), 1 );
943+
944+
QCOMPARE( w.tableContents().size(), 1 );
945+
QCOMPARE( w.tableContents().at( 0 ).size(), 4 );
946+
QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content().toString(), QStringLiteral( "Jet" ) );
947+
QVERIFY( !w.tableContents().at( 0 ).at( 0 ).content().canConvert< QgsProperty >() );
948+
QVERIFY( w.tableContents().at( 0 ).at( 1 ).content().canConvert< QgsProperty >() );
949+
QCOMPARE( w.tableContents().at( 0 ).at( 1 ).content().value< QgsProperty >().asExpression(), QStringLiteral( "1+2" ) );
950+
QCOMPARE( w.tableContents().at( 0 ).at( 2 ).content().toString(), QStringLiteral( "87" ) );
951+
QVERIFY( !w.tableContents().at( 0 ).at( 2 ).content().canConvert< QgsProperty >() );
952+
QCOMPARE( w.tableContents().at( 0 ).at( 3 ).content().toString(), QStringLiteral( "Jet3" ) );
953+
QVERIFY( !w.tableContents().at( 0 ).at( 3 ).content().canConvert< QgsProperty >() );
954+
955+
w.selectionModel()->clearSelection();
956+
w.setSelectionCellProperty( QgsProperty::fromExpression( QStringLiteral( "2+3" ) ) );
957+
QCOMPARE( spy.count(), 1 );
958+
959+
w.selectionModel()->select( w.model()->index( 0, 0 ), QItemSelectionModel::ClearAndSelect );
960+
QVERIFY( !w.tableContents().at( 0 ).at( 0 ).content().canConvert< QgsProperty >() );
961+
w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::Select );
962+
QVERIFY( !w.selectionCellProperty().isActive() );
963+
w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::ClearAndSelect );
964+
QVERIFY( w.selectionCellProperty().isActive() );
965+
QCOMPARE( w.selectionCellProperty().asExpression(), QStringLiteral( "1+2" ) );
966+
w.selectionModel()->select( w.model()->index( 0, 0 ), QItemSelectionModel::Select );
967+
QVERIFY( !w.selectionCellProperty().isActive() );
968+
w.setSelectionCellProperty( QgsProperty::fromExpression( QStringLiteral( "3+4" ) ) );
969+
QCOMPARE( spy.count(), 2 );
970+
QVERIFY( w.selectionCellProperty().isActive() );
971+
QCOMPARE( w.selectionCellProperty().asExpression(), QStringLiteral( "3+4" ) );
972+
QVERIFY( w.tableContents().at( 0 ).at( 0 ).content().canConvert< QgsProperty >() );
973+
QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content().value< QgsProperty >().asExpression(), QStringLiteral( "3+4" ) );
974+
QVERIFY( w.tableContents().at( 0 ).at( 1 ).content().canConvert< QgsProperty >() );
975+
QCOMPARE( w.tableContents().at( 0 ).at( 1 ).content().value< QgsProperty >().asExpression(), QStringLiteral( "3+4" ) );
976+
QCOMPARE( w.tableContents().at( 0 ).at( 2 ).content().toString(), QStringLiteral( "87" ) );
977+
QVERIFY( !w.tableContents().at( 0 ).at( 2 ).content().canConvert< QgsProperty >() );
978+
QCOMPARE( w.tableContents().at( 0 ).at( 3 ).content().toString(), QStringLiteral( "Jet3" ) );
979+
QVERIFY( !w.tableContents().at( 0 ).at( 3 ).content().canConvert< QgsProperty >() );
980+
w.selectionModel()->select( w.model()->index( 0, 3 ), QItemSelectionModel::Select );
981+
QVERIFY( !w.selectionCellProperty().isActive() );
982+
}
983+
927984
void TestQgsTableEditor::textFormat()
928985
{
929986
QgsTableEditorWidget w;

0 commit comments

Comments
 (0)
Please sign in to comment.