1 /***************************************************************************
2     testqgstableeditor.cpp
3      --------------------------------------
4     Date                 : January 2020
5     Copyright            : (C) 2020 Nyall Dawson
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 
17 #include "qgstest.h"
18 
19 #include "qgstableeditorwidget.h"
20 #include "qgscurrencynumericformat.h"
21 #include "qgsbearingnumericformat.h"
22 #include <QSignalSpy>
23 
24 class TestQgsTableEditor: public QObject
25 {
26     Q_OBJECT
27   private slots:
28     void initTestCase(); // will be called before the first testfunction is executed.
29     void cleanupTestCase(); // will be called after the last testfunction was executed.
30     void init(); // will be called before each testfunction is executed.
31     void cleanup(); // will be called after every testfunction.
32     void testData();
33     void insertRowsBelow();
34     void insertRowsAbove();
35     void insertColumnsBefore();
36     void insertColumnsAfter();
37     void deleteRows();
38     void deleteColumns();
39     void selectRows();
40     void selectColumns();
41     void clearSelected();
42     void foregroundColor();
43     void backgroundColor();
44     void alignment();
45     void properties();
46     void textFormat();
47     void numericFormat();
48     void rowHeight();
49     void columnWidth();
50     void headers();
51 
52   private:
53 
54 };
55 
initTestCase()56 void TestQgsTableEditor::initTestCase()
57 {
58 
59 }
60 
cleanupTestCase()61 void TestQgsTableEditor::cleanupTestCase()
62 {
63 }
64 
init()65 void TestQgsTableEditor::init()
66 {
67 }
68 
cleanup()69 void TestQgsTableEditor::cleanup()
70 {
71 }
72 
testData()73 void TestQgsTableEditor::testData()
74 {
75   QgsTableEditorWidget w;
76   QVERIFY( w.tableContents().isEmpty() );
77 
78   const QSignalSpy spy( &w, &QgsTableEditorWidget::tableChanged );
79   QgsTableCell c3;
80   c3.setContent( 87 );
81   std::unique_ptr< QgsCurrencyNumericFormat > format = std::make_unique< QgsCurrencyNumericFormat >();
82   format->setNumberDecimalPlaces( 2 );
83   format->setPrefix( QStringLiteral( "$" ) );
84   c3.setNumericFormat( format.release() );
85   c3.setHorizontalAlignment( Qt::AlignJustify );
86   c3.setVerticalAlignment( Qt::AlignBottom );
87   QgsTableCell c2( 76 );
88   c2.setBackgroundColor( QColor( 255, 0, 0 ) );
89   QgsTextFormat textFormat;
90   textFormat.setSize( 12.6 );
91   textFormat.setColor( QColor( 0, 255, 0 ) );
92   c2.setTextFormat( textFormat );
93   c2.setHorizontalAlignment( Qt::AlignRight );
94   c2.setVerticalAlignment( Qt::AlignTop );
95   w.setTableContents( QgsTableContents() << ( QgsTableRow() << QgsTableCell( QStringLiteral( "Jet" ) ) << c2 << c3 ) );
96   QCOMPARE( spy.count(), 1 );
97 
98   QCOMPARE( w.tableContents().size(), 1 );
99   QCOMPARE( w.tableContents().at( 0 ).size(), 3 );
100   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content().toString(), QStringLiteral( "Jet" ) );
101   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).backgroundColor().isValid() );
102   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).textFormat().isValid() );
103   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).textFormat().isValid() );
104   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).numericFormat() );
105   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).horizontalAlignment(), Qt::AlignLeft );
106   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).verticalAlignment(), Qt::AlignVCenter );
107   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).content().toString(), QStringLiteral( "76" ) );
108   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).backgroundColor(), QColor( 255, 0, 0 ) );
109   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).textFormat().color(), QColor( 0, 255, 0 ) );
110   QVERIFY( !w.tableContents().at( 0 ).at( 1 ).numericFormat() );
111   QVERIFY( w.tableContents().at( 0 ).at( 1 ).textFormat().isValid() );
112   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).textFormat().size(), 12.6 );
113   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).horizontalAlignment(), Qt::AlignRight );
114   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).verticalAlignment(), Qt::AlignTop );
115   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).content().toString(), QStringLiteral( "87" ) );
116   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).backgroundColor().isValid() );
117   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).textFormat().isValid() );
118   QVERIFY( w.tableContents().at( 0 ).at( 2 ).numericFormat() );
119   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).numericFormat()->id(), QStringLiteral( "currency" ) );
120   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).horizontalAlignment(), Qt::AlignJustify );
121   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).verticalAlignment(), Qt::AlignBottom );
122 }
123 
insertRowsBelow()124 void TestQgsTableEditor::insertRowsBelow()
125 {
126   QgsTableEditorWidget w;
127   QVERIFY( w.tableContents().isEmpty() );
128 
129   const QSignalSpy spy( &w, &QgsTableEditorWidget::tableChanged );
130   QgsTableCell c3;
131   c3.setContent( 87 );
132   std::unique_ptr< QgsCurrencyNumericFormat > format = std::make_unique< QgsCurrencyNumericFormat >();
133   format->setNumberDecimalPlaces( 2 );
134   format->setPrefix( QStringLiteral( "$" ) );
135   c3.setNumericFormat( format.release() );
136   QgsTableCell c2( 76 );
137   c2.setBackgroundColor( QColor( 255, 0, 0 ) );
138   QgsTextFormat c2f;
139   c2f.setColor( QColor( 0, 255, 0 ) ) ;
140   c2.setTextFormat( c2f );
141   w.setTableContents( QgsTableContents() << ( QgsTableRow() << QgsTableCell( QStringLiteral( "Jet" ) ) << c2 << c3 ) );
142   QCOMPARE( spy.count(), 1 );
143 
144   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::ClearAndSelect );
145   w.insertRowsBelow();
146   QCOMPARE( spy.count(), 2 );
147 
148   QCOMPARE( w.tableContents().size(), 2 );
149   QCOMPARE( w.tableContents().at( 0 ).size(), 3 );
150   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content().toString(), QStringLiteral( "Jet" ) );
151   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).backgroundColor().isValid() );
152   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).textFormat().isValid() );
153   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).numericFormat() );
154   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).content().toString(), QStringLiteral( "76" ) );
155   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).backgroundColor(), QColor( 255, 0, 0 ) );
156   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).textFormat().color(), QColor( 0, 255, 0 ) );
157   QVERIFY( !w.tableContents().at( 0 ).at( 1 ).numericFormat() );
158   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).content().toString(), QStringLiteral( "87" ) );
159   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).backgroundColor().isValid() );
160   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).textFormat().isValid() );
161   QVERIFY( w.tableContents().at( 0 ).at( 2 ).numericFormat() );
162   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).numericFormat()->id(), QStringLiteral( "currency" ) );
163   QCOMPARE( w.tableContents().at( 1 ).size(), 3 );
164   QCOMPARE( w.tableContents().at( 1 ).at( 0 ).content().toString(), QString() );
165   QVERIFY( !w.tableContents().at( 1 ).at( 0 ).backgroundColor().isValid() );
166   QVERIFY( !w.tableContents().at( 1 ).at( 0 ).textFormat().isValid() );
167   QCOMPARE( w.tableContents().at( 1 ).at( 1 ).content().toString(), QString() );
168   QVERIFY( !w.tableContents().at( 1 ).at( 1 ).backgroundColor().isValid() );
169   QVERIFY( !w.tableContents().at( 1 ).at( 1 ).textFormat().isValid() );
170   QCOMPARE( w.tableContents().at( 1 ).at( 2 ).content().toString(), QString() );
171   QVERIFY( !w.tableContents().at( 1 ).at( 2 ).backgroundColor().isValid() );
172   QVERIFY( !w.tableContents().at( 1 ).at( 2 ).textFormat().isValid() );
173 
174   // two rows selected = insert two rows, etc
175   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::ClearAndSelect );
176   w.selectionModel()->select( w.model()->index( 1, 2 ), QItemSelectionModel::Select );
177   w.insertRowsBelow();
178   QCOMPARE( spy.count(), 3 );
179 
180   QCOMPARE( w.tableContents().size(), 4 );
181   QCOMPARE( w.tableContents().at( 0 ).size(), 3 );
182   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content().toString(), QStringLiteral( "Jet" ) );
183   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).backgroundColor().isValid() );
184   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).textFormat().isValid() );
185   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).numericFormat() );
186   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).content().toString(), QStringLiteral( "76" ) );
187   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).backgroundColor(), QColor( 255, 0, 0 ) );
188   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).textFormat().color(), QColor( 0, 255, 0 ) );
189   QVERIFY( !w.tableContents().at( 0 ).at( 1 ).numericFormat() );
190   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).content().toString(), QStringLiteral( "87" ) );
191   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).backgroundColor().isValid() );
192   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).textFormat().isValid() );
193   QVERIFY( w.tableContents().at( 0 ).at( 2 ).numericFormat() );
194   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).numericFormat()->id(), QStringLiteral( "currency" ) );
195   QCOMPARE( w.tableContents().at( 1 ).size(), 3 );
196   QCOMPARE( w.tableContents().at( 1 ).at( 0 ).content().toString(), QString() );
197   QVERIFY( !w.tableContents().at( 1 ).at( 0 ).backgroundColor().isValid() );
198   QVERIFY( !w.tableContents().at( 1 ).at( 0 ).textFormat().isValid() );
199   QCOMPARE( w.tableContents().at( 1 ).at( 1 ).content().toString(), QString() );
200   QVERIFY( !w.tableContents().at( 1 ).at( 1 ).backgroundColor().isValid() );
201   QVERIFY( !w.tableContents().at( 1 ).at( 1 ).textFormat().isValid() );
202   QCOMPARE( w.tableContents().at( 1 ).at( 2 ).content().toString(), QString() );
203   QVERIFY( !w.tableContents().at( 1 ).at( 2 ).backgroundColor().isValid() );
204   QVERIFY( !w.tableContents().at( 1 ).at( 2 ).textFormat().isValid() );
205   QCOMPARE( w.tableContents().at( 2 ).size(), 3 );
206   QCOMPARE( w.tableContents().at( 2 ).at( 0 ).content().toString(), QString() );
207   QVERIFY( !w.tableContents().at( 2 ).at( 0 ).backgroundColor().isValid() );
208   QVERIFY( !w.tableContents().at( 2 ).at( 0 ).textFormat().isValid() );
209   QCOMPARE( w.tableContents().at( 2 ).at( 1 ).content().toString(), QString() );
210   QVERIFY( !w.tableContents().at( 2 ).at( 1 ).backgroundColor().isValid() );
211   QVERIFY( !w.tableContents().at( 2 ).at( 1 ).textFormat().isValid() );
212   QCOMPARE( w.tableContents().at( 2 ).at( 2 ).content().toString(), QString() );
213   QVERIFY( !w.tableContents().at( 2 ).at( 2 ).backgroundColor().isValid() );
214   QVERIFY( !w.tableContents().at( 2 ).at( 2 ).textFormat().isValid() );
215   QCOMPARE( w.tableContents().at( 3 ).size(), 3 );
216   QCOMPARE( w.tableContents().at( 3 ).at( 0 ).content().toString(), QString() );
217   QVERIFY( !w.tableContents().at( 3 ).at( 0 ).backgroundColor().isValid() );
218   QVERIFY( !w.tableContents().at( 3 ).at( 0 ).textFormat().isValid() );
219   QCOMPARE( w.tableContents().at( 3 ).at( 1 ).content().toString(), QString() );
220   QVERIFY( !w.tableContents().at( 3 ).at( 1 ).backgroundColor().isValid() );
221   QVERIFY( !w.tableContents().at( 3 ).at( 1 ).textFormat().isValid() );
222   QCOMPARE( w.tableContents().at( 3 ).at( 2 ).content().toString(), QString() );
223   QVERIFY( !w.tableContents().at( 3 ).at( 2 ).backgroundColor().isValid() );
224   QVERIFY( !w.tableContents().at( 3 ).at( 2 ).textFormat().isValid() );
225 
226   // non consecutive selection = no action
227   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::ClearAndSelect );
228   w.selectionModel()->select( w.model()->index( 2, 2 ), QItemSelectionModel::Select );
229   w.insertRowsBelow();
230   QCOMPARE( spy.count(), 3 );
231   QCOMPARE( w.tableContents().size(), 4 );
232 }
233 
insertRowsAbove()234 void TestQgsTableEditor::insertRowsAbove()
235 {
236   QgsTableEditorWidget w;
237   QVERIFY( w.tableContents().isEmpty() );
238 
239   const QSignalSpy spy( &w, &QgsTableEditorWidget::tableChanged );
240   QgsTableCell c3;
241   c3.setContent( 87 );
242   std::unique_ptr< QgsCurrencyNumericFormat > format = std::make_unique< QgsCurrencyNumericFormat >();
243   format->setNumberDecimalPlaces( 2 );
244   format->setPrefix( QStringLiteral( "$" ) );
245   c3.setNumericFormat( format.release() );
246   QgsTableCell c2( 76 );
247   c2.setBackgroundColor( QColor( 255, 0, 0 ) );
248   QgsTextFormat c2f;
249   c2f.setColor( QColor( 0, 255, 0 ) );
250   c2.setTextFormat( c2f );
251   w.setTableContents( QgsTableContents() << ( QgsTableRow() << QgsTableCell( QStringLiteral( "Jet" ) ) << c2 << c3 ) );
252   QCOMPARE( spy.count(), 1 );
253 
254   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::ClearAndSelect );
255   w.insertRowsAbove();
256   QCOMPARE( spy.count(), 2 );
257 
258   QCOMPARE( w.tableContents().size(), 2 );
259   QCOMPARE( w.tableContents().at( 0 ).size(), 3 );
260   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content().toString(), QString() );
261   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).backgroundColor().isValid() );
262   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).textFormat().isValid() );
263   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).content().toString(), QString() );
264   QVERIFY( !w.tableContents().at( 0 ).at( 1 ).backgroundColor().isValid() );
265   QVERIFY( !w.tableContents().at( 0 ).at( 1 ).textFormat().isValid() );
266   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).content().toString(), QString() );
267   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).backgroundColor().isValid() );
268   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).textFormat().isValid() );
269   QCOMPARE( w.tableContents().at( 1 ).size(), 3 );
270   QCOMPARE( w.tableContents().at( 1 ).at( 0 ).content().toString(), QStringLiteral( "Jet" ) );
271   QVERIFY( !w.tableContents().at( 1 ).at( 0 ).backgroundColor().isValid() );
272   QVERIFY( !w.tableContents().at( 1 ).at( 0 ).textFormat().isValid() );
273   QVERIFY( !w.tableContents().at( 1 ).at( 0 ).numericFormat() );
274   QCOMPARE( w.tableContents().at( 1 ).at( 1 ).content().toString(), QStringLiteral( "76" ) );
275   QCOMPARE( w.tableContents().at( 1 ).at( 1 ).backgroundColor(), QColor( 255, 0, 0 ) );
276   QCOMPARE( w.tableContents().at( 1 ).at( 1 ).textFormat().color(), QColor( 0, 255, 0 ) );
277   QVERIFY( !w.tableContents().at( 1 ).at( 1 ).numericFormat() );
278   QCOMPARE( w.tableContents().at( 1 ).at( 2 ).content().toString(), QStringLiteral( "87" ) );
279   QVERIFY( !w.tableContents().at( 1 ).at( 2 ).backgroundColor().isValid() );
280   QVERIFY( !w.tableContents().at( 1 ).at( 2 ).textFormat().isValid() );
281   QVERIFY( w.tableContents().at( 1 ).at( 2 ).numericFormat() );
282   QCOMPARE( w.tableContents().at( 1 ).at( 2 ).numericFormat()->id(), QStringLiteral( "currency" ) );
283 
284   // two rows selected = insert two rows, etc
285   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::ClearAndSelect );
286   w.selectionModel()->select( w.model()->index( 1, 2 ), QItemSelectionModel::Select );
287   w.insertRowsAbove();
288   QCOMPARE( spy.count(), 3 );
289 
290   QCOMPARE( w.tableContents().size(), 4 );
291   QCOMPARE( w.tableContents().at( 0 ).size(), 3 );
292   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content().toString(), QString() );
293   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).backgroundColor().isValid() );
294   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).textFormat().isValid() );
295   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).content().toString(), QString() );
296   QVERIFY( !w.tableContents().at( 0 ).at( 1 ).backgroundColor().isValid() );
297   QVERIFY( !w.tableContents().at( 0 ).at( 1 ).textFormat().isValid() );
298   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).content().toString(), QString() );
299   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).backgroundColor().isValid() );
300   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).textFormat().isValid() );
301   QCOMPARE( w.tableContents().at( 1 ).size(), 3 );
302   QCOMPARE( w.tableContents().at( 1 ).at( 0 ).content().toString(), QString() );
303   QVERIFY( !w.tableContents().at( 1 ).at( 0 ).backgroundColor().isValid() );
304   QVERIFY( !w.tableContents().at( 1 ).at( 0 ).textFormat().isValid() );
305   QCOMPARE( w.tableContents().at( 1 ).at( 1 ).content().toString(), QString() );
306   QVERIFY( !w.tableContents().at( 1 ).at( 1 ).backgroundColor().isValid() );
307   QVERIFY( !w.tableContents().at( 1 ).at( 1 ).textFormat().isValid() );
308   QCOMPARE( w.tableContents().at( 1 ).at( 2 ).content().toString(), QString() );
309   QVERIFY( !w.tableContents().at( 1 ).at( 2 ).backgroundColor().isValid() );
310   QVERIFY( !w.tableContents().at( 1 ).at( 2 ).textFormat().isValid() );
311   QCOMPARE( w.tableContents().at( 2 ).size(), 3 );
312   QCOMPARE( w.tableContents().at( 2 ).at( 0 ).content().toString(), QString() );
313   QVERIFY( !w.tableContents().at( 2 ).at( 0 ).backgroundColor().isValid() );
314   QVERIFY( !w.tableContents().at( 2 ).at( 0 ).textFormat().isValid() );
315   QCOMPARE( w.tableContents().at( 2 ).at( 1 ).content().toString(), QString() );
316   QVERIFY( !w.tableContents().at( 2 ).at( 1 ).backgroundColor().isValid() );
317   QVERIFY( !w.tableContents().at( 2 ).at( 1 ).textFormat().isValid() );
318   QCOMPARE( w.tableContents().at( 2 ).at( 2 ).content().toString(), QString() );
319   QVERIFY( !w.tableContents().at( 2 ).at( 2 ).backgroundColor().isValid() );
320   QVERIFY( !w.tableContents().at( 2 ).at( 2 ).textFormat().isValid() );
321   QCOMPARE( w.tableContents().at( 3 ).size(), 3 );
322   QCOMPARE( w.tableContents().at( 3 ).at( 0 ).content().toString(), QStringLiteral( "Jet" ) );
323   QVERIFY( !w.tableContents().at( 3 ).at( 0 ).backgroundColor().isValid() );
324   QVERIFY( !w.tableContents().at( 3 ).at( 0 ).textFormat().isValid() );
325   QVERIFY( !w.tableContents().at( 3 ).at( 0 ).numericFormat() );
326   QCOMPARE( w.tableContents().at( 3 ).at( 1 ).content().toString(), QStringLiteral( "76" ) );
327   QCOMPARE( w.tableContents().at( 3 ).at( 1 ).backgroundColor(), QColor( 255, 0, 0 ) );
328   QCOMPARE( w.tableContents().at( 3 ).at( 1 ).textFormat().color(), QColor( 0, 255, 0 ) );
329   QVERIFY( !w.tableContents().at( 3 ).at( 1 ).numericFormat() );
330   QCOMPARE( w.tableContents().at( 3 ).at( 2 ).content().toString(), QStringLiteral( "87" ) );
331   QVERIFY( !w.tableContents().at( 3 ).at( 2 ).backgroundColor().isValid() );
332   QVERIFY( !w.tableContents().at( 3 ).at( 2 ).textFormat().isValid() );
333   QVERIFY( w.tableContents().at( 3 ).at( 2 ).numericFormat() );
334   QCOMPARE( w.tableContents().at( 3 ).at( 2 ).numericFormat()->id(), QStringLiteral( "currency" ) );
335 
336   // non consecutive selection = no action
337   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::ClearAndSelect );
338   w.selectionModel()->select( w.model()->index( 2, 2 ), QItemSelectionModel::Select );
339   w.insertRowsAbove();
340   QCOMPARE( spy.count(), 3 );
341   QCOMPARE( w.tableContents().size(), 4 );
342 }
343 
insertColumnsBefore()344 void TestQgsTableEditor::insertColumnsBefore()
345 {
346   QgsTableEditorWidget w;
347   QVERIFY( w.tableContents().isEmpty() );
348 
349   const QSignalSpy spy( &w, &QgsTableEditorWidget::tableChanged );
350   QgsTableCell c3;
351   c3.setContent( 87 );
352   std::unique_ptr< QgsCurrencyNumericFormat > format = std::make_unique< QgsCurrencyNumericFormat >();
353   format->setNumberDecimalPlaces( 2 );
354   format->setPrefix( QStringLiteral( "$" ) );
355   c3.setNumericFormat( format.release() );
356   QgsTableCell c2( 76 );
357   c2.setBackgroundColor( QColor( 255, 0, 0 ) );
358   QgsTextFormat c2f;
359   c2f.setColor( QColor( 0, 255, 0 ) );
360   c2.setTextFormat( c2f );
361   w.setTableContents( QgsTableContents() << ( QgsTableRow() << QgsTableCell( QStringLiteral( "Jet" ) ) << c2 << c3 ) );
362   QCOMPARE( spy.count(), 1 );
363 
364   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::ClearAndSelect );
365   w.insertColumnsBefore();
366   QCOMPARE( spy.count(), 2 );
367 
368   QCOMPARE( w.tableContents().size(), 1 );
369   QCOMPARE( w.tableContents().at( 0 ).size(), 4 );
370   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content().toString(), QStringLiteral( "Jet" ) );
371   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).backgroundColor().isValid() );
372   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).textFormat().isValid() );
373   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).numericFormat() );
374   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).content().toString(), QString() );
375   QVERIFY( !w.tableContents().at( 0 ).at( 1 ).backgroundColor().isValid() );
376   QVERIFY( !w.tableContents().at( 0 ).at( 1 ).textFormat().isValid() );
377   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).content().toString(), QStringLiteral( "76" ) );
378   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).backgroundColor(), QColor( 255, 0, 0 ) );
379   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).textFormat().color(), QColor( 0, 255, 0 ) );
380   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).numericFormat() );
381   QCOMPARE( w.tableContents().at( 0 ).at( 3 ).content().toString(), QStringLiteral( "87" ) );
382   QVERIFY( !w.tableContents().at( 0 ).at( 3 ).backgroundColor().isValid() );
383   QVERIFY( !w.tableContents().at( 0 ).at( 3 ).textFormat().isValid() );
384   QVERIFY( w.tableContents().at( 0 ).at( 3 ).numericFormat() );
385   QCOMPARE( w.tableContents().at( 0 ).at( 3 ).numericFormat()->id(), QStringLiteral( "currency" ) );
386 
387   // two rows selected = insert two rows, etc
388   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::ClearAndSelect );
389   w.selectionModel()->select( w.model()->index( 0, 2 ), QItemSelectionModel::Select );
390   w.insertColumnsBefore();
391   QCOMPARE( spy.count(), 3 );
392 
393   QCOMPARE( w.tableContents().size(), 1 );
394   QCOMPARE( w.tableContents().at( 0 ).size(), 6 );
395   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content().toString(), QStringLiteral( "Jet" ) );
396   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).backgroundColor().isValid() );
397   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).textFormat().isValid() );
398   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).numericFormat() );
399   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).content().toString(), QString() );
400   QVERIFY( !w.tableContents().at( 0 ).at( 1 ).backgroundColor().isValid() );
401   QVERIFY( !w.tableContents().at( 0 ).at( 1 ).textFormat().isValid() );
402   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).content().toString(), QString() );
403   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).backgroundColor().isValid() );
404   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).textFormat().isValid() );
405   QCOMPARE( w.tableContents().at( 0 ).at( 3 ).content().toString(), QString() );
406   QVERIFY( !w.tableContents().at( 0 ).at( 3 ).backgroundColor().isValid() );
407   QVERIFY( !w.tableContents().at( 0 ).at( 3 ).textFormat().isValid() );
408   QCOMPARE( w.tableContents().at( 0 ).at( 4 ).content().toString(), QStringLiteral( "76" ) );
409   QCOMPARE( w.tableContents().at( 0 ).at( 4 ).backgroundColor(), QColor( 255, 0, 0 ) );
410   QCOMPARE( w.tableContents().at( 0 ).at( 4 ).textFormat().color(), QColor( 0, 255, 0 ) );
411   QVERIFY( !w.tableContents().at( 0 ).at( 4 ).numericFormat() );
412   QCOMPARE( w.tableContents().at( 0 ).at( 5 ).content().toString(), QStringLiteral( "87" ) );
413   QVERIFY( !w.tableContents().at( 0 ).at( 5 ).backgroundColor().isValid() );
414   QVERIFY( !w.tableContents().at( 0 ).at( 5 ).textFormat().isValid() );
415   QVERIFY( w.tableContents().at( 0 ).at( 5 ).numericFormat() );
416   QCOMPARE( w.tableContents().at( 0 ).at( 5 ).numericFormat()->id(), QStringLiteral( "currency" ) );
417 
418   // non consecutive selection = no action
419   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::ClearAndSelect );
420   w.selectionModel()->select( w.model()->index( 0, 3 ), QItemSelectionModel::Select );
421   w.insertColumnsBefore();
422   QCOMPARE( spy.count(), 3 );
423   QCOMPARE( w.tableContents().at( 0 ).size(), 6 );
424 }
425 
insertColumnsAfter()426 void TestQgsTableEditor::insertColumnsAfter()
427 {
428   QgsTableEditorWidget w;
429   QVERIFY( w.tableContents().isEmpty() );
430 
431   const QSignalSpy spy( &w, &QgsTableEditorWidget::tableChanged );
432   QgsTableCell c3;
433   c3.setContent( 87 );
434   std::unique_ptr< QgsCurrencyNumericFormat > format = std::make_unique< QgsCurrencyNumericFormat >();
435   format->setNumberDecimalPlaces( 2 );
436   format->setPrefix( QStringLiteral( "$" ) );
437   c3.setNumericFormat( format.release() );
438   QgsTableCell c2( 76 );
439   c2.setBackgroundColor( QColor( 255, 0, 0 ) );
440   QgsTextFormat c2f;
441   c2f.setColor( QColor( 0, 255, 0 ) );
442   c2.setTextFormat( c2f );
443   w.setTableContents( QgsTableContents() << ( QgsTableRow() << QgsTableCell( QStringLiteral( "Jet" ) ) << c2 << c3 ) );
444   QCOMPARE( spy.count(), 1 );
445 
446   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::ClearAndSelect );
447   w.insertColumnsAfter();
448   QCOMPARE( spy.count(), 2 );
449 
450   QCOMPARE( w.tableContents().size(), 1 );
451   QCOMPARE( w.tableContents().at( 0 ).size(), 4 );
452   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content().toString(), QStringLiteral( "Jet" ) );
453   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).backgroundColor().isValid() );
454   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).textFormat().isValid() );
455   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).numericFormat() );
456   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).content().toString(), QStringLiteral( "76" ) );
457   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).backgroundColor(), QColor( 255, 0, 0 ) );
458   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).textFormat().color(), QColor( 0, 255, 0 ) );
459   QVERIFY( !w.tableContents().at( 0 ).at( 1 ).numericFormat() );
460   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).content().toString(), QString() );
461   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).backgroundColor().isValid() );
462   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).textFormat().isValid() );
463   QCOMPARE( w.tableContents().at( 0 ).at( 3 ).content().toString(), QStringLiteral( "87" ) );
464   QVERIFY( !w.tableContents().at( 0 ).at( 3 ).backgroundColor().isValid() );
465   QVERIFY( !w.tableContents().at( 0 ).at( 3 ).textFormat().isValid() );
466   QVERIFY( w.tableContents().at( 0 ).at( 3 ).numericFormat() );
467   QCOMPARE( w.tableContents().at( 0 ).at( 3 ).numericFormat()->id(), QStringLiteral( "currency" ) );
468 
469   // two rows selected = insert two rows, etc
470   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::ClearAndSelect );
471   w.selectionModel()->select( w.model()->index( 0, 2 ), QItemSelectionModel::Select );
472   w.insertColumnsAfter();
473   QCOMPARE( spy.count(), 3 );
474 
475   QCOMPARE( w.tableContents().size(), 1 );
476   QCOMPARE( w.tableContents().at( 0 ).size(), 6 );
477   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content().toString(), QStringLiteral( "Jet" ) );
478   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).backgroundColor().isValid() );
479   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).textFormat().isValid() );
480   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).numericFormat() );
481   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).content().toString(), QStringLiteral( "76" ) );
482   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).backgroundColor(), QColor( 255, 0, 0 ) );
483   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).textFormat().color(), QColor( 0, 255, 0 ) );
484   QVERIFY( !w.tableContents().at( 0 ).at( 1 ).numericFormat() );
485   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).content().toString(), QString() );
486   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).backgroundColor().isValid() );
487   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).textFormat().isValid() );
488   QCOMPARE( w.tableContents().at( 0 ).at( 3 ).content().toString(), QString() );
489   QVERIFY( !w.tableContents().at( 0 ).at( 3 ).backgroundColor().isValid() );
490   QVERIFY( !w.tableContents().at( 0 ).at( 3 ).textFormat().isValid() );
491   QCOMPARE( w.tableContents().at( 0 ).at( 4 ).content().toString(), QString() );
492   QVERIFY( !w.tableContents().at( 0 ).at( 4 ).backgroundColor().isValid() );
493   QVERIFY( !w.tableContents().at( 0 ).at( 4 ).textFormat().isValid() );
494   QCOMPARE( w.tableContents().at( 0 ).at( 5 ).content().toString(), QStringLiteral( "87" ) );
495   QVERIFY( !w.tableContents().at( 0 ).at( 5 ).backgroundColor().isValid() );
496   QVERIFY( !w.tableContents().at( 0 ).at( 5 ).textFormat().isValid() );
497   QVERIFY( w.tableContents().at( 0 ).at( 5 ).numericFormat() );
498   QCOMPARE( w.tableContents().at( 0 ).at( 5 ).numericFormat()->id(), QStringLiteral( "currency" ) );
499 
500   // non consecutive selection = no action
501   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::ClearAndSelect );
502   w.selectionModel()->select( w.model()->index( 0, 3 ), QItemSelectionModel::Select );
503   w.insertColumnsAfter();
504   QCOMPARE( spy.count(), 3 );
505   QCOMPARE( w.tableContents().at( 0 ).size(), 6 );
506 }
507 
deleteRows()508 void TestQgsTableEditor::deleteRows()
509 {
510   QgsTableEditorWidget w;
511   QVERIFY( w.tableContents().isEmpty() );
512 
513   const QSignalSpy spy( &w, &QgsTableEditorWidget::tableChanged );
514   QgsTableCell c3;
515   c3.setContent( 87 );
516   std::unique_ptr< QgsCurrencyNumericFormat > format = std::make_unique< QgsCurrencyNumericFormat >();
517   format->setNumberDecimalPlaces( 2 );
518   format->setPrefix( QStringLiteral( "$" ) );
519   QgsTableCell c2( 76 );
520   c2.setNumericFormat( format.release() );
521   c2.setBackgroundColor( QColor( 255, 0, 0 ) );
522   QgsTextFormat c2f;
523   c2f.setColor( QColor( 0, 255, 0 ) );
524   c2.setTextFormat( c2f );
525   w.setTableContents( QgsTableContents() << ( QgsTableRow() << QgsTableCell( QStringLiteral( "Jet" ) ) )
526                       << ( QgsTableRow() << c2 )
527                       << ( QgsTableRow() << c3 )
528                       << ( QgsTableRow() << QgsTableCell( QStringLiteral( "Jet3" ) ) ) );
529   QCOMPARE( spy.count(), 1 );
530 
531   // no selection
532   w.selectionModel()->clear();
533   w.deleteRows();
534   QCOMPARE( spy.count(), 1 );
535   QCOMPARE( w.tableContents().size(), 4 );
536 
537   w.selectionModel()->select( w.model()->index( 2, 0 ), QItemSelectionModel::ClearAndSelect );
538   w.deleteRows();
539   QCOMPARE( spy.count(), 2 );
540 
541   QCOMPARE( w.tableContents().size(), 3 );
542   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content().toString(), QStringLiteral( "Jet" ) );
543   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).backgroundColor().isValid() );
544   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).textFormat().isValid() );
545   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).numericFormat() );
546   QCOMPARE( w.tableContents().at( 1 ).at( 0 ).content().toString(), QStringLiteral( "76" ) );
547   QCOMPARE( w.tableContents().at( 1 ).at( 0 ).backgroundColor(), QColor( 255, 0, 0 ) );
548   QCOMPARE( w.tableContents().at( 1 ).at( 0 ).textFormat().color(), QColor( 0, 255, 0 ) );
549   QCOMPARE( w.tableContents().at( 1 ).at( 0 ).numericFormat()->id(), QStringLiteral( "currency" ) );
550   QCOMPARE( w.tableContents().at( 2 ).at( 0 ).content().toString(), QStringLiteral( "Jet3" ) );
551   QVERIFY( !w.tableContents().at( 2 ).at( 0 ).backgroundColor().isValid() );
552   QVERIFY( !w.tableContents().at( 2 ).at( 0 ).textFormat().isValid() );
553 
554   w.selectionModel()->select( w.model()->index( 0, 0 ), QItemSelectionModel::ClearAndSelect );
555   w.selectionModel()->select( w.model()->index( 2, 0 ), QItemSelectionModel::Select );
556   w.deleteRows();
557   QCOMPARE( spy.count(), 3 );
558 
559   QCOMPARE( w.tableContents().size(), 1 );
560   QCOMPARE( w.tableContents().at( 0 ).size(), 1 );
561   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content().toString(), QStringLiteral( "76" ) );
562   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).backgroundColor(), QColor( 255, 0, 0 ) );
563   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).textFormat().color(), QColor( 0, 255, 0 ) );
564   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).numericFormat()->id(), QStringLiteral( "currency" ) );
565 
566   // last row can't be deleted
567   w.selectionModel()->select( w.model()->index( 0, 0 ), QItemSelectionModel::ClearAndSelect );
568   w.deleteRows();
569   QCOMPARE( spy.count(), 3 );
570   QCOMPARE( w.tableContents().size(), 1 );
571   QCOMPARE( w.tableContents().at( 0 ).size(), 1 );
572 
573 }
574 
deleteColumns()575 void TestQgsTableEditor::deleteColumns()
576 {
577   QgsTableEditorWidget w;
578   QVERIFY( w.tableContents().isEmpty() );
579 
580   const QSignalSpy spy( &w, &QgsTableEditorWidget::tableChanged );
581   QgsTableCell c3;
582   c3.setContent( 87 );
583   std::unique_ptr< QgsCurrencyNumericFormat > format = std::make_unique< QgsCurrencyNumericFormat >();
584   format->setNumberDecimalPlaces( 2 );
585   format->setPrefix( QStringLiteral( "$" ) );
586   QgsTableCell c2( 76 );
587   c2.setNumericFormat( format.release() );
588   c2.setBackgroundColor( QColor( 255, 0, 0 ) );
589   QgsTextFormat c2f;
590   c2f.setColor( QColor( 0, 255, 0 ) );
591   c2.setTextFormat( c2f );
592   w.setTableContents( QgsTableContents() << ( QgsTableRow() << QgsTableCell( QStringLiteral( "Jet" ) ) << c2 << c3 << QgsTableCell( QStringLiteral( "Jet3" ) ) ) );
593   QCOMPARE( spy.count(), 1 );
594 
595   // no selection
596   w.selectionModel()->clear();
597   w.deleteColumns();
598   QCOMPARE( spy.count(), 1 );
599   QCOMPARE( w.tableContents().size(), 1 );
600   QCOMPARE( w.tableContents().at( 0 ).size(), 4 );
601 
602   w.selectionModel()->select( w.model()->index( 0, 2 ), QItemSelectionModel::ClearAndSelect );
603   w.deleteColumns();
604   QCOMPARE( spy.count(), 2 );
605 
606   QCOMPARE( w.tableContents().size(), 1 );
607   QCOMPARE( w.tableContents().at( 0 ).size(), 3 );
608   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content().toString(), QStringLiteral( "Jet" ) );
609   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).backgroundColor().isValid() );
610   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).textFormat().isValid() );
611   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).numericFormat() );
612   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).content().toString(), QStringLiteral( "76" ) );
613   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).backgroundColor(), QColor( 255, 0, 0 ) );
614   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).textFormat().color(), QColor( 0, 255, 0 ) );
615   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).numericFormat()->id(), QStringLiteral( "currency" ) );
616   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).content().toString(), QStringLiteral( "Jet3" ) );
617   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).backgroundColor().isValid() );
618   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).textFormat().isValid() );
619 
620   w.selectionModel()->select( w.model()->index( 0, 0 ), QItemSelectionModel::ClearAndSelect );
621   w.selectionModel()->select( w.model()->index( 0, 2 ), QItemSelectionModel::Select );
622   w.deleteColumns();
623   QCOMPARE( spy.count(), 3 );
624 
625   QCOMPARE( w.tableContents().size(), 1 );
626   QCOMPARE( w.tableContents().at( 0 ).size(), 1 );
627   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content().toString(), QStringLiteral( "76" ) );
628   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).backgroundColor(), QColor( 255, 0, 0 ) );
629   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).textFormat().color(), QColor( 0, 255, 0 ) );
630   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).numericFormat()->id(), QStringLiteral( "currency" ) );
631 
632   // last column can't be deleted
633   w.selectionModel()->select( w.model()->index( 0, 0 ), QItemSelectionModel::ClearAndSelect );
634   w.deleteColumns();
635   QCOMPARE( spy.count(), 3 );
636   QCOMPARE( w.tableContents().size(), 1 );
637   QCOMPARE( w.tableContents().at( 0 ).size(), 1 );
638 
639 }
640 
selectRows()641 void TestQgsTableEditor::selectRows()
642 {
643   QgsTableEditorWidget w;
644   w.setTableContents( QgsTableContents() << ( QgsTableRow() << QgsTableCell() << QgsTableCell() << QgsTableCell() )
645                       << ( QgsTableRow() << QgsTableCell()  << QgsTableCell() << QgsTableCell() )
646                       << ( QgsTableRow() << QgsTableCell() << QgsTableCell() << QgsTableCell() )
647                       << ( QgsTableRow() << QgsTableCell() << QgsTableCell() << QgsTableCell() ) );
648 
649   w.selectionModel()->select( w.model()->index( 0, 0 ), QItemSelectionModel::ClearAndSelect );
650   w.expandRowSelection();
651   QCOMPARE( w.selectionModel()->selectedIndexes().size(), 3 );
652   QVERIFY( w.selectionModel()->isSelected( w.model()->index( 0, 0 ) ) );
653   QVERIFY( w.selectionModel()->isSelected( w.model()->index( 0, 1 ) ) );
654   QVERIFY( w.selectionModel()->isSelected( w.model()->index( 0, 2 ) ) );
655 
656 
657   w.selectionModel()->select( w.model()->index( 1, 1 ), QItemSelectionModel::ClearAndSelect );
658   w.selectionModel()->select( w.model()->index( 1, 2 ), QItemSelectionModel::Select );
659   w.selectionModel()->select( w.model()->index( 2, 0 ), QItemSelectionModel::Select );
660   w.expandRowSelection();
661   QCOMPARE( w.selectionModel()->selectedIndexes().size(), 6 );
662   QVERIFY( w.selectionModel()->isSelected( w.model()->index( 1, 0 ) ) );
663   QVERIFY( w.selectionModel()->isSelected( w.model()->index( 1, 1 ) ) );
664   QVERIFY( w.selectionModel()->isSelected( w.model()->index( 1, 2 ) ) );
665   QVERIFY( w.selectionModel()->isSelected( w.model()->index( 2, 0 ) ) );
666   QVERIFY( w.selectionModel()->isSelected( w.model()->index( 2, 1 ) ) );
667   QVERIFY( w.selectionModel()->isSelected( w.model()->index( 2, 2 ) ) );
668 
669   w.selectionModel()->clearSelection();
670   w.expandRowSelection();
671   QCOMPARE( w.selectionModel()->selectedIndexes().size(), 0 );
672 }
673 
selectColumns()674 void TestQgsTableEditor::selectColumns()
675 {
676   QgsTableEditorWidget w;
677   w.setTableContents( QgsTableContents() << ( QgsTableRow() << QgsTableCell() << QgsTableCell() << QgsTableCell() )
678                       << ( QgsTableRow() << QgsTableCell()  << QgsTableCell() << QgsTableCell() )
679                       << ( QgsTableRow() << QgsTableCell() << QgsTableCell() << QgsTableCell() ) );
680 
681   w.selectionModel()->select( w.model()->index( 0, 0 ), QItemSelectionModel::ClearAndSelect );
682   w.expandColumnSelection();
683   QCOMPARE( w.selectionModel()->selectedIndexes().size(), 3 );
684   QVERIFY( w.selectionModel()->isSelected( w.model()->index( 0, 0 ) ) );
685   QVERIFY( w.selectionModel()->isSelected( w.model()->index( 1, 0 ) ) );
686   QVERIFY( w.selectionModel()->isSelected( w.model()->index( 2, 0 ) ) );
687 
688   w.selectionModel()->select( w.model()->index( 1, 1 ), QItemSelectionModel::ClearAndSelect );
689   w.selectionModel()->select( w.model()->index( 2, 1 ), QItemSelectionModel::Select );
690   w.selectionModel()->select( w.model()->index( 0, 2 ), QItemSelectionModel::Select );
691   w.expandColumnSelection();
692   QCOMPARE( w.selectionModel()->selectedIndexes().size(), 6 );
693   QVERIFY( w.selectionModel()->isSelected( w.model()->index( 0, 1 ) ) );
694   QVERIFY( w.selectionModel()->isSelected( w.model()->index( 1, 1 ) ) );
695   QVERIFY( w.selectionModel()->isSelected( w.model()->index( 2, 1 ) ) );
696   QVERIFY( w.selectionModel()->isSelected( w.model()->index( 0, 2 ) ) );
697   QVERIFY( w.selectionModel()->isSelected( w.model()->index( 1, 2 ) ) );
698   QVERIFY( w.selectionModel()->isSelected( w.model()->index( 2, 2 ) ) );
699 
700   w.selectionModel()->clearSelection();
701   w.expandColumnSelection();
702   QCOMPARE( w.selectionModel()->selectedIndexes().size(), 0 );
703 }
704 
clearSelected()705 void TestQgsTableEditor::clearSelected()
706 {
707   QgsTableEditorWidget w;
708   w.setTableContents( QgsTableContents() << ( QgsTableRow() << QgsTableCell( QStringLiteral( "A1" ) ) << QgsTableCell( QStringLiteral( "A2" ) ) << QgsTableCell( QStringLiteral( "A3" ) ) )
709                       << ( QgsTableRow() << QgsTableCell( QStringLiteral( "B1" ) )  << QgsTableCell( QStringLiteral( "B2" ) ) << QgsTableCell( QStringLiteral( "B3" ) ) )
710                       << ( QgsTableRow() << QgsTableCell( QStringLiteral( "C1" ) ) << QgsTableCell( QStringLiteral( "C2" ) ) << QgsTableCell( QStringLiteral( "C3" ) ) ) );
711 
712   const QSignalSpy spy( &w, &QgsTableEditorWidget::tableChanged );
713   w.selectionModel()->clearSelection();
714   w.clearSelectedCells();
715   QCOMPARE( spy.count(), 0 );
716   QCOMPARE( w.tableContents().size(), 3 );
717   QCOMPARE( w.tableContents().at( 0 ).size(), 3 );
718   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content().toString(), QStringLiteral( "A1" ) );
719   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).content().toString(), QStringLiteral( "A2" ) );
720   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).content().toString(), QStringLiteral( "A3" ) );
721   QCOMPARE( w.tableContents().at( 1 ).size(), 3 );
722   QCOMPARE( w.tableContents().at( 1 ).at( 0 ).content().toString(), QStringLiteral( "B1" ) );
723   QCOMPARE( w.tableContents().at( 1 ).at( 1 ).content().toString(), QStringLiteral( "B2" ) );
724   QCOMPARE( w.tableContents().at( 1 ).at( 2 ).content().toString(), QStringLiteral( "B3" ) );
725   QCOMPARE( w.tableContents().at( 2 ).size(), 3 );
726   QCOMPARE( w.tableContents().at( 2 ).at( 0 ).content().toString(), QStringLiteral( "C1" ) );
727   QCOMPARE( w.tableContents().at( 2 ).at( 1 ).content().toString(), QStringLiteral( "C2" ) );
728   QCOMPARE( w.tableContents().at( 2 ).at( 2 ).content().toString(), QStringLiteral( "C3" ) );
729 
730   w.selectionModel()->select( w.model()->index( 1, 1 ), QItemSelectionModel::ClearAndSelect );
731   w.selectionModel()->select( w.model()->index( 1, 2 ), QItemSelectionModel::Select );
732   w.selectionModel()->select( w.model()->index( 0, 2 ), QItemSelectionModel::Select );
733   w.clearSelectedCells();
734   QCOMPARE( spy.count(), 1 );
735   QCOMPARE( w.tableContents().size(), 3 );
736   QCOMPARE( w.tableContents().at( 0 ).size(), 3 );
737   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content().toString(), QStringLiteral( "A1" ) );
738   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).content().toString(), QStringLiteral( "A2" ) );
739   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).content().toString(), QString() );
740   QCOMPARE( w.tableContents().at( 1 ).size(), 3 );
741   QCOMPARE( w.tableContents().at( 1 ).at( 0 ).content().toString(), QStringLiteral( "B1" ) );
742   QCOMPARE( w.tableContents().at( 1 ).at( 1 ).content().toString(), QString() );
743   QCOMPARE( w.tableContents().at( 1 ).at( 2 ).content().toString(), QString() );
744   QCOMPARE( w.tableContents().at( 2 ).size(), 3 );
745   QCOMPARE( w.tableContents().at( 2 ).at( 0 ).content().toString(), QStringLiteral( "C1" ) );
746   QCOMPARE( w.tableContents().at( 2 ).at( 1 ).content().toString(), QStringLiteral( "C2" ) );
747   QCOMPARE( w.tableContents().at( 2 ).at( 2 ).content().toString(), QStringLiteral( "C3" ) );
748 
749 }
750 
foregroundColor()751 void TestQgsTableEditor::foregroundColor()
752 {
753   QgsTableEditorWidget w;
754   QVERIFY( w.tableContents().isEmpty() );
755 
756   const QSignalSpy spy( &w, &QgsTableEditorWidget::tableChanged );
757   QgsTableCell c3;
758   c3.setContent( 87 );
759   std::unique_ptr< QgsCurrencyNumericFormat > format = std::make_unique< QgsCurrencyNumericFormat >();
760   format->setNumberDecimalPlaces( 2 );
761   format->setPrefix( QStringLiteral( "$" ) );
762   c3.setNumericFormat( format.release() );
763   QgsTableCell c2( 76 );
764   c2.setBackgroundColor( QColor( 255, 0, 0 ) );
765   QgsTextFormat f = c2.textFormat();
766   f.setColor( QColor( 0, 255, 0 ) );
767   c2.setTextFormat( f );
768   w.setTableContents( QgsTableContents() << ( QgsTableRow() << QgsTableCell( QStringLiteral( "Jet" ) ) << c2 << c3 << QgsTableCell( QStringLiteral( "Jet3" ) ) ) );
769   QCOMPARE( spy.count(), 1 );
770 
771   QCOMPARE( w.tableContents().size(), 1 );
772   QCOMPARE( w.tableContents().at( 0 ).size(), 4 );
773   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content().toString(), QStringLiteral( "Jet" ) );
774   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).backgroundColor().isValid() );
775   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).textFormat().isValid() );
776   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).numericFormat() );
777   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).content().toString(), QStringLiteral( "76" ) );
778   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).backgroundColor(), QColor( 255, 0, 0 ) );
779   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).textFormat().color(), QColor( 0, 255, 0 ) );
780   QVERIFY( !w.tableContents().at( 0 ).at( 1 ).numericFormat() );
781   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).content().toString(), QStringLiteral( "87" ) );
782   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).backgroundColor().isValid() );
783   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).textFormat().isValid() );
784   QVERIFY( w.tableContents().at( 0 ).at( 2 ).numericFormat() );
785   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).numericFormat()->id(), QStringLiteral( "currency" ) );
786   QCOMPARE( w.tableContents().at( 0 ).at( 3 ).content().toString(), QStringLiteral( "Jet3" ) );
787   QVERIFY( !w.tableContents().at( 0 ).at( 3 ).backgroundColor().isValid() );
788   QVERIFY( !w.tableContents().at( 0 ).at( 3 ).textFormat().isValid() );
789   QVERIFY( !w.tableContents().at( 0 ).at( 3 ).numericFormat() );
790 
791   w.selectionModel()->clearSelection();
792   QgsTextFormat f2;
793   f2.setColor( QColor( 255, 255, 0 ) );
794   w.setSelectionTextFormat( f2 );
795   QCOMPARE( spy.count(), 1 );
796 
797   w.selectionModel()->select( w.model()->index( 0, 0 ), QItemSelectionModel::ClearAndSelect );
798   QVERIFY( !w.selectionTextFormat().isValid() );
799   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::Select );
800   QVERIFY( !w.selectionTextFormat().isValid() );
801   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::ClearAndSelect );
802   QCOMPARE( w.selectionTextFormat().color(), QColor( 0, 255, 0 ) );
803   w.selectionModel()->select( w.model()->index( 0, 0 ), QItemSelectionModel::Select );
804   QVERIFY( !w.selectionTextFormat().isValid() );
805   w.setSelectionTextFormat( f2 );
806   QCOMPARE( spy.count(), 2 );
807   QCOMPARE( w.selectionTextFormat().color(), QColor( 255, 255, 0 ) );
808   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).textFormat().color(), QColor( 255, 255, 0 ) );
809   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).textFormat().color(), QColor( 255, 255, 0 ) );
810   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).textFormat().isValid() );
811   QVERIFY( !w.tableContents().at( 0 ).at( 3 ).textFormat().isValid() );
812   w.selectionModel()->select( w.model()->index( 0, 3 ), QItemSelectionModel::Select );
813   QVERIFY( !w.selectionTextFormat().isValid() );
814 }
815 
backgroundColor()816 void TestQgsTableEditor::backgroundColor()
817 {
818   QgsTableEditorWidget w;
819   QVERIFY( w.tableContents().isEmpty() );
820 
821   const QSignalSpy spy( &w, &QgsTableEditorWidget::tableChanged );
822   QgsTableCell c3;
823   c3.setContent( 87 );
824   std::unique_ptr< QgsCurrencyNumericFormat > format = std::make_unique< QgsCurrencyNumericFormat >();
825   format->setNumberDecimalPlaces( 2 );
826   format->setPrefix( QStringLiteral( "$" ) );
827   c3.setNumericFormat( format.release() );
828   QgsTableCell c2( 76 );
829   c2.setBackgroundColor( QColor( 255, 0, 0 ) );
830   QgsTextFormat c2f;
831   c2f.setColor( QColor( 0, 255, 0 ) );
832   c2.setTextFormat( c2f );
833   w.setTableContents( QgsTableContents() << ( QgsTableRow() << QgsTableCell( QStringLiteral( "Jet" ) ) << c2 << c3 << QgsTableCell( QStringLiteral( "Jet3" ) ) ) );
834   QCOMPARE( spy.count(), 1 );
835 
836   QCOMPARE( w.tableContents().size(), 1 );
837   QCOMPARE( w.tableContents().at( 0 ).size(), 4 );
838   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content().toString(), QStringLiteral( "Jet" ) );
839   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).backgroundColor().isValid() );
840   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).textFormat().isValid() );
841   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).numericFormat() );
842   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).content().toString(), QStringLiteral( "76" ) );
843   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).backgroundColor(), QColor( 255, 0, 0 ) );
844   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).textFormat().color(), QColor( 0, 255, 0 ) );
845   QVERIFY( !w.tableContents().at( 0 ).at( 1 ).numericFormat() );
846   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).content().toString(), QStringLiteral( "87" ) );
847   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).backgroundColor().isValid() );
848   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).textFormat().isValid() );
849   QVERIFY( w.tableContents().at( 0 ).at( 2 ).numericFormat() );
850   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).numericFormat()->id(), QStringLiteral( "currency" ) );
851   QCOMPARE( w.tableContents().at( 0 ).at( 3 ).content().toString(), QStringLiteral( "Jet3" ) );
852   QVERIFY( !w.tableContents().at( 0 ).at( 3 ).backgroundColor().isValid() );
853   QVERIFY( !w.tableContents().at( 0 ).at( 3 ).textFormat().isValid() );
854   QVERIFY( !w.tableContents().at( 0 ).at( 3 ).numericFormat() );
855 
856   w.selectionModel()->clearSelection();
857   w.setSelectionBackgroundColor( QColor( 255, 255, 0 ) );
858   QCOMPARE( spy.count(), 1 );
859 
860   w.selectionModel()->select( w.model()->index( 0, 0 ), QItemSelectionModel::ClearAndSelect );
861   QVERIFY( !w.selectionBackgroundColor().isValid() );
862   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::Select );
863   QVERIFY( !w.selectionBackgroundColor().isValid() );
864   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::ClearAndSelect );
865   QCOMPARE( w.selectionBackgroundColor(), QColor( 255, 0, 0 ) );
866   w.selectionModel()->select( w.model()->index( 0, 0 ), QItemSelectionModel::Select );
867   QVERIFY( !w.selectionBackgroundColor().isValid() );
868   w.setSelectionBackgroundColor( QColor( 255, 255, 0 ) );
869   QCOMPARE( spy.count(), 2 );
870   QCOMPARE( w.selectionBackgroundColor(), QColor( 255, 255, 0 ) );
871   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).backgroundColor(), QColor( 255, 255, 0 ) );
872   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).backgroundColor(), QColor( 255, 255, 0 ) );
873   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).backgroundColor().isValid() );
874   QVERIFY( !w.tableContents().at( 0 ).at( 3 ).backgroundColor().isValid() );
875   w.selectionModel()->select( w.model()->index( 0, 3 ), QItemSelectionModel::Select );
876   QVERIFY( !w.selectionBackgroundColor().isValid() );
877 }
878 
alignment()879 void TestQgsTableEditor::alignment()
880 {
881   QgsTableEditorWidget w;
882   QVERIFY( w.tableContents().isEmpty() );
883 
884   const QSignalSpy spy( &w, &QgsTableEditorWidget::tableChanged );
885   QgsTableCell c3;
886   c3.setContent( 87 );
887   std::unique_ptr< QgsCurrencyNumericFormat > format = std::make_unique< QgsCurrencyNumericFormat >();
888   format->setNumberDecimalPlaces( 2 );
889   format->setPrefix( QStringLiteral( "$" ) );
890   c3.setNumericFormat( format.release() );
891   QgsTableCell c2( 76 );
892   c2.setHorizontalAlignment( Qt::AlignRight );
893   c2.setVerticalAlignment( Qt::AlignBottom );
894   w.setTableContents( QgsTableContents() << ( QgsTableRow() << QgsTableCell( QStringLiteral( "Jet" ) ) << c2 << c3 << QgsTableCell( QStringLiteral( "Jet3" ) ) ) );
895   QCOMPARE( spy.count(), 1 );
896 
897   QCOMPARE( w.tableContents().size(), 1 );
898   QCOMPARE( w.tableContents().at( 0 ).size(), 4 );
899   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content().toString(), QStringLiteral( "Jet" ) );
900   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).horizontalAlignment(), Qt::AlignLeft );
901   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).verticalAlignment(), Qt::AlignVCenter );
902   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).content().toString(), QStringLiteral( "76" ) );
903   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).horizontalAlignment(), Qt::AlignRight );
904   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).verticalAlignment(), Qt::AlignBottom );
905   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).content().toString(), QStringLiteral( "87" ) );
906   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).horizontalAlignment(), Qt::AlignLeft );
907   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).verticalAlignment(), Qt::AlignVCenter );
908   QCOMPARE( w.tableContents().at( 0 ).at( 3 ).content().toString(), QStringLiteral( "Jet3" ) );
909   QCOMPARE( w.tableContents().at( 0 ).at( 3 ).horizontalAlignment(), Qt::AlignLeft );
910   QCOMPARE( w.tableContents().at( 0 ).at( 3 ).verticalAlignment(), Qt::AlignVCenter );
911 
912   w.selectionModel()->clearSelection();
913   w.setSelectionVerticalAlignment( Qt::AlignTop );
914   w.setSelectionHorizontalAlignment( Qt::AlignCenter );
915   QCOMPARE( spy.count(), 1 );
916 
917   w.selectionModel()->select( w.model()->index( 0, 0 ), QItemSelectionModel::ClearAndSelect );
918   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).horizontalAlignment(), Qt::AlignLeft );
919   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).verticalAlignment(), Qt::AlignVCenter );
920   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::Select );
921   QCOMPARE( w.selectionHorizontalAlignment(), Qt::AlignLeft | Qt::AlignTop );
922   QCOMPARE( w.selectionVerticalAlignment(), Qt::AlignLeft | Qt::AlignTop );
923   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::ClearAndSelect );
924   QCOMPARE( w.selectionHorizontalAlignment(), Qt::AlignRight );
925   QCOMPARE( w.selectionVerticalAlignment(), Qt::AlignBottom );
926   w.selectionModel()->select( w.model()->index( 0, 0 ), QItemSelectionModel::Select );
927   QCOMPARE( w.selectionHorizontalAlignment(), Qt::AlignLeft | Qt::AlignTop );
928   QCOMPARE( w.selectionVerticalAlignment(), Qt::AlignLeft | Qt::AlignTop );
929   w.setSelectionHorizontalAlignment( Qt::AlignJustify );
930   w.setSelectionVerticalAlignment( Qt::AlignTop );
931   QCOMPARE( spy.count(), 3 );
932   QCOMPARE( w.selectionHorizontalAlignment(), Qt::AlignJustify );
933   QCOMPARE( w.selectionVerticalAlignment(), Qt::AlignTop );
934   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).horizontalAlignment(), Qt::AlignJustify );
935   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).verticalAlignment(), Qt::AlignTop );
936   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).horizontalAlignment(), Qt::AlignJustify );
937   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).verticalAlignment(), Qt::AlignTop );
938   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).horizontalAlignment(), Qt::AlignLeft );
939   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).verticalAlignment(), Qt::AlignVCenter );
940   QCOMPARE( w.tableContents().at( 0 ).at( 3 ).horizontalAlignment(), Qt::AlignLeft );
941   QCOMPARE( w.tableContents().at( 0 ).at( 3 ).verticalAlignment(), Qt::AlignVCenter );
942   w.selectionModel()->select( w.model()->index( 0, 3 ), QItemSelectionModel::Select );
943   QCOMPARE( w.selectionHorizontalAlignment(), Qt::AlignLeft | Qt::AlignTop );
944   QCOMPARE( w.selectionVerticalAlignment(), Qt::AlignLeft | Qt::AlignTop );
945 }
946 
properties()947 void TestQgsTableEditor::properties()
948 {
949   QgsTableEditorWidget w;
950   QVERIFY( w.tableContents().isEmpty() );
951 
952   const QSignalSpy spy( &w, &QgsTableEditorWidget::tableChanged );
953   QgsTableCell c3;
954   c3.setContent( 87 );
955   std::unique_ptr< QgsCurrencyNumericFormat > format = std::make_unique< QgsCurrencyNumericFormat >();
956   format->setNumberDecimalPlaces( 2 );
957   format->setPrefix( QStringLiteral( "$" ) );
958   c3.setNumericFormat( format.release() );
959   const QgsTableCell c2( QVariant::fromValue( QgsProperty::fromExpression( "1+2" ) ) );
960   w.setTableContents( QgsTableContents() << ( QgsTableRow() << QgsTableCell( QStringLiteral( "Jet" ) ) << c2 << c3 << QgsTableCell( QStringLiteral( "Jet3" ) ) ) );
961   QCOMPARE( spy.count(), 1 );
962 
963   QCOMPARE( w.tableContents().size(), 1 );
964   QCOMPARE( w.tableContents().at( 0 ).size(), 4 );
965   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content().toString(), QStringLiteral( "Jet" ) );
966   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).content().canConvert< QgsProperty >() );
967   QVERIFY( w.tableContents().at( 0 ).at( 1 ).content().canConvert< QgsProperty >() );
968   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).content().value< QgsProperty >().asExpression(), QStringLiteral( "1+2" ) );
969   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).content().toString(), QStringLiteral( "87" ) );
970   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).content().canConvert< QgsProperty >() );
971   QCOMPARE( w.tableContents().at( 0 ).at( 3 ).content().toString(), QStringLiteral( "Jet3" ) );
972   QVERIFY( !w.tableContents().at( 0 ).at( 3 ).content().canConvert< QgsProperty >() );
973 
974   w.selectionModel()->clearSelection();
975   w.setSelectionCellProperty( QgsProperty::fromExpression( QStringLiteral( "2+3" ) ) );
976   QCOMPARE( spy.count(), 1 );
977 
978   w.selectionModel()->select( w.model()->index( 0, 0 ), QItemSelectionModel::ClearAndSelect );
979   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).content().canConvert< QgsProperty >() );
980   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::Select );
981   QVERIFY( !w.selectionCellProperty().isActive() );
982   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::ClearAndSelect );
983   QVERIFY( w.selectionCellProperty().isActive() );
984   QCOMPARE( w.selectionCellProperty().asExpression(), QStringLiteral( "1+2" ) );
985   w.selectionModel()->select( w.model()->index( 0, 0 ), QItemSelectionModel::Select );
986   QVERIFY( !w.selectionCellProperty().isActive() );
987   w.setSelectionCellProperty( QgsProperty::fromExpression( QStringLiteral( "3+4" ) ) );
988   QCOMPARE( spy.count(), 2 );
989   QVERIFY( w.selectionCellProperty().isActive() );
990   QCOMPARE( w.selectionCellProperty().asExpression(), QStringLiteral( "3+4" ) );
991   QVERIFY( w.tableContents().at( 0 ).at( 0 ).content().canConvert< QgsProperty >() );
992   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content().value< QgsProperty >().asExpression(), QStringLiteral( "3+4" ) );
993   QVERIFY( w.tableContents().at( 0 ).at( 1 ).content().canConvert< QgsProperty >() );
994   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).content().value< QgsProperty >().asExpression(), QStringLiteral( "3+4" ) );
995   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).content().toString(), QStringLiteral( "87" ) );
996   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).content().canConvert< QgsProperty >() );
997   QCOMPARE( w.tableContents().at( 0 ).at( 3 ).content().toString(), QStringLiteral( "Jet3" ) );
998   QVERIFY( !w.tableContents().at( 0 ).at( 3 ).content().canConvert< QgsProperty >() );
999   w.selectionModel()->select( w.model()->index( 0, 3 ), QItemSelectionModel::Select );
1000   QVERIFY( !w.selectionCellProperty().isActive() );
1001 }
1002 
textFormat()1003 void TestQgsTableEditor::textFormat()
1004 {
1005   QgsTableEditorWidget w;
1006   QVERIFY( w.tableContents().isEmpty() );
1007 
1008   const QSignalSpy spy( &w, &QgsTableEditorWidget::tableChanged );
1009   QgsTableCell c3;
1010   c3.setContent( 87 );
1011   QgsTextFormat format;
1012   format.setSize( 12.6 );
1013   c3.setTextFormat( format );
1014   QgsTableCell c2( 76 );
1015   c2.setTextFormat( format );
1016   w.setTableContents( QgsTableContents() << ( QgsTableRow() << QgsTableCell( QStringLiteral( "Jet" ) ) << c2 << c3 << QgsTableCell( QStringLiteral( "Jet3" ) ) ) );
1017   QCOMPARE( spy.count(), 1 );
1018 
1019   QCOMPARE( w.tableContents().size(), 1 );
1020   QCOMPARE( w.tableContents().at( 0 ).size(), 4 );
1021   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content().toString(), QStringLiteral( "Jet" ) );
1022   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).textFormat().isValid() );
1023   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).content().toString(), QStringLiteral( "76" ) );
1024   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).textFormat().size(), 12.6 );
1025   QVERIFY( w.tableContents().at( 0 ).at( 1 ).textFormat().isValid() );
1026   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).content().toString(), QStringLiteral( "87" ) );
1027   QVERIFY( w.tableContents().at( 0 ).at( 2 ).textFormat().isValid() );
1028   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).textFormat().size(), 12.6 );
1029   QCOMPARE( w.tableContents().at( 0 ).at( 3 ).content().toString(), QStringLiteral( "Jet3" ) );
1030   QVERIFY( !w.tableContents().at( 0 ).at( 3 ).textFormat().isValid() );
1031 
1032   w.selectionModel()->clearSelection();
1033   format.setSize( 21 );
1034   w.setSelectionTextFormat( format );
1035   QCOMPARE( spy.count(), 1 );
1036 
1037   w.selectionModel()->select( w.model()->index( 0, 0 ), QItemSelectionModel::ClearAndSelect );
1038   QVERIFY( w.selectionTextFormat().size() !=  21.0 );
1039   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::Select );
1040   QVERIFY( w.selectionTextFormat().size() !=  21.0 );
1041   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::ClearAndSelect );
1042   QCOMPARE( w.selectionTextFormat().size(), 12.6 );
1043   w.selectionModel()->select( w.model()->index( 0, 0 ), QItemSelectionModel::Select );
1044   QVERIFY( w.selectionTextFormat().size() !=  21.0 );
1045   w.setSelectionTextFormat( format );
1046   QCOMPARE( spy.count(), 2 );
1047   QVERIFY( w.selectionTextFormat().isValid() );
1048   QCOMPARE( w.selectionTextFormat().size(), 21.0 );
1049   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).textFormat().size(), 21.0 );
1050   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).textFormat().size(), 21.0 );
1051   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).textFormat().size(), 12.6 );
1052   QVERIFY( w.tableContents().at( 0 ).at( 3 ).textFormat().size() != 21 );
1053 }
1054 
numericFormat()1055 void TestQgsTableEditor::numericFormat()
1056 {
1057   QgsTableEditorWidget w;
1058   QVERIFY( w.tableContents().isEmpty() );
1059 
1060   const QSignalSpy spy( &w, &QgsTableEditorWidget::tableChanged );
1061   QgsTableCell c3;
1062   c3.setContent( 87 );
1063   std::unique_ptr< QgsCurrencyNumericFormat > format = std::make_unique< QgsCurrencyNumericFormat >();
1064   format->setNumberDecimalPlaces( 2 );
1065   format->setPrefix( QStringLiteral( "$" ) );
1066   QgsTableCell c2( 76 );
1067   c2.setNumericFormat( format.release() );
1068   c2.setBackgroundColor( QColor( 255, 0, 0 ) );
1069   QgsTextFormat c2f;
1070   c2f.setColor( QColor( 0, 255, 0 ) );
1071   c2.setTextFormat( c2f );
1072   w.setTableContents( QgsTableContents() << ( QgsTableRow() << QgsTableCell( QStringLiteral( "Jet" ) ) << c2 << c3 << QgsTableCell( QStringLiteral( "Jet3" ) ) ) );
1073   QCOMPARE( spy.count(), 1 );
1074 
1075   QCOMPARE( w.tableContents().size(), 1 );
1076   QCOMPARE( w.tableContents().at( 0 ).size(), 4 );
1077   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content().toString(), QStringLiteral( "Jet" ) );
1078   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).backgroundColor().isValid() );
1079   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).textFormat().isValid() );
1080   QVERIFY( !w.tableContents().at( 0 ).at( 0 ).numericFormat() );
1081   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).content().toString(), QStringLiteral( "76" ) );
1082   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).backgroundColor(), QColor( 255, 0, 0 ) );
1083   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).textFormat().color(), QColor( 0, 255, 0 ) );
1084   QVERIFY( w.tableContents().at( 0 ).at( 1 ).numericFormat() );
1085   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).numericFormat()->id(), QStringLiteral( "currency" ) );
1086   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).content().toString(), QStringLiteral( "87" ) );
1087   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).backgroundColor().isValid() );
1088   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).textFormat().isValid() );
1089   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).numericFormat() );
1090   QCOMPARE( w.tableContents().at( 0 ).at( 3 ).content().toString(), QStringLiteral( "Jet3" ) );
1091   QVERIFY( !w.tableContents().at( 0 ).at( 3 ).backgroundColor().isValid() );
1092   QVERIFY( !w.tableContents().at( 0 ).at( 3 ).textFormat().isValid() );
1093   QVERIFY( !w.tableContents().at( 0 ).at( 3 ).numericFormat() );
1094 
1095   w.selectionModel()->clearSelection();
1096   w.setSelectionNumericFormat( new QgsBearingNumericFormat() );
1097   QVERIFY( !w.hasMixedSelectionNumericFormat() );
1098   QCOMPARE( spy.count(), 1 );
1099 
1100   w.selectionModel()->select( w.model()->index( 0, 0 ), QItemSelectionModel::ClearAndSelect );
1101   QVERIFY( !w.selectionNumericFormat() );
1102   QVERIFY( !w.hasMixedSelectionNumericFormat() );
1103   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::Select );
1104   QVERIFY( !w.selectionNumericFormat() );
1105   QVERIFY( w.hasMixedSelectionNumericFormat() );
1106   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::ClearAndSelect );
1107   QCOMPARE( w.selectionNumericFormat()->id(), QStringLiteral( "currency" ) );
1108   QVERIFY( !w.hasMixedSelectionNumericFormat() );
1109   w.selectionModel()->select( w.model()->index( 0, 0 ), QItemSelectionModel::Select );
1110   QVERIFY( !w.selectionNumericFormat() );
1111   QVERIFY( w.hasMixedSelectionNumericFormat() );
1112   w.setSelectionNumericFormat( new QgsBearingNumericFormat() );
1113   QCOMPARE( spy.count(), 2 );
1114   QCOMPARE( w.selectionNumericFormat()->id(), QStringLiteral( "bearing" ) );
1115   QVERIFY( !w.hasMixedSelectionNumericFormat() );
1116   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).numericFormat()->id(), QStringLiteral( "bearing" ) );
1117   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).numericFormat()->id(), QStringLiteral( "bearing" ) );
1118   QVERIFY( !w.tableContents().at( 0 ).at( 2 ).numericFormat() );
1119   QVERIFY( !w.tableContents().at( 0 ).at( 3 ).numericFormat() );
1120   w.selectionModel()->select( w.model()->index( 0, 3 ), QItemSelectionModel::Select );
1121   QVERIFY( !w.selectionNumericFormat() );
1122   QVERIFY( w.hasMixedSelectionNumericFormat() );
1123 }
1124 
rowHeight()1125 void TestQgsTableEditor::rowHeight()
1126 {
1127   QgsTableEditorWidget w;
1128   QVERIFY( w.tableContents().isEmpty() );
1129 
1130   const QSignalSpy spy( &w, &QgsTableEditorWidget::tableChanged );
1131   w.setTableContents( QgsTableContents() << ( QgsTableRow() << QgsTableCell() << QgsTableCell() << QgsTableCell() )
1132                       << ( QgsTableRow() << QgsTableCell()  << QgsTableCell() << QgsTableCell() )
1133                       << ( QgsTableRow() << QgsTableCell() << QgsTableCell() << QgsTableCell() ) );
1134   QCOMPARE( spy.count(), 1 );
1135   w.setTableRowHeight( 1, 14.0 );
1136 
1137   QCOMPARE( w.selectionRowHeight(), 0.0 );
1138   QCOMPARE( w.tableRowHeight( 0 ), 0.0 );
1139   QCOMPARE( w.tableRowHeight( 1 ), 14.0 );
1140   QCOMPARE( w.tableRowHeight( 2 ), 0.0 );
1141   w.selectionModel()->clearSelection();
1142   w.setSelectionRowHeight( 15.0 );
1143   QCOMPARE( spy.count(), 2 );
1144   QCOMPARE( w.selectionRowHeight(), 0.0 );
1145   QCOMPARE( w.tableRowHeight( 0 ), 0.0 );
1146   QCOMPARE( w.tableRowHeight( 1 ), 14.0 );
1147   QCOMPARE( w.tableRowHeight( 2 ), 0.0 );
1148 
1149   w.selectionModel()->select( w.model()->index( 0, 0 ), QItemSelectionModel::ClearAndSelect );
1150   QCOMPARE( w.selectionRowHeight(), 0.0 );
1151   w.selectionModel()->select( w.model()->index( 1, 0 ), QItemSelectionModel::Select );
1152   QCOMPARE( w.selectionRowHeight(), -1.0 );
1153   w.selectionModel()->select( w.model()->index( 1, 0 ), QItemSelectionModel::ClearAndSelect );
1154   QCOMPARE( w.selectionRowHeight(), 14.0 );
1155   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::Select );
1156   QCOMPARE( w.selectionRowHeight(), -1.0 );
1157   w.setSelectionRowHeight( 15.0 );
1158   QCOMPARE( spy.count(), 3 );
1159   QCOMPARE( w.selectionRowHeight(), 15.0 );
1160   QCOMPARE( w.tableRowHeight( 0 ), 15.0 );
1161   QCOMPARE( w.tableRowHeight( 1 ), 15.0 );
1162   QCOMPARE( w.tableRowHeight( 2 ), 0.0 );
1163   w.selectionModel()->select( w.model()->index( 2, 2 ), QItemSelectionModel::Select );
1164   QCOMPARE( w.selectionRowHeight(), -1.0 );
1165 }
1166 
columnWidth()1167 void TestQgsTableEditor::columnWidth()
1168 {
1169   QgsTableEditorWidget w;
1170   QVERIFY( w.tableContents().isEmpty() );
1171 
1172   const QSignalSpy spy( &w, &QgsTableEditorWidget::tableChanged );
1173   w.setTableContents( QgsTableContents() << ( QgsTableRow() << QgsTableCell() << QgsTableCell() << QgsTableCell() )
1174                       << ( QgsTableRow() << QgsTableCell()  << QgsTableCell() << QgsTableCell() )
1175                       << ( QgsTableRow() << QgsTableCell() << QgsTableCell() << QgsTableCell() ) );
1176   QCOMPARE( spy.count(), 1 );
1177   w.setTableColumnWidth( 1, 14.0 );
1178 
1179   QCOMPARE( w.selectionColumnWidth(), 0.0 );
1180   QCOMPARE( w.tableColumnWidth( 0 ), 0.0 );
1181   QCOMPARE( w.tableColumnWidth( 1 ), 14.0 );
1182   QCOMPARE( w.tableColumnWidth( 2 ), 0.0 );
1183   w.selectionModel()->clearSelection();
1184   w.setSelectionColumnWidth( 15.0 );
1185   QCOMPARE( spy.count(), 2 );
1186   QCOMPARE( w.selectionColumnWidth(), 0.0 );
1187   QCOMPARE( w.tableColumnWidth( 0 ), 0.0 );
1188   QCOMPARE( w.tableColumnWidth( 1 ), 14.0 );
1189   QCOMPARE( w.tableColumnWidth( 2 ), 0.0 );
1190 
1191   w.selectionModel()->select( w.model()->index( 0, 0 ), QItemSelectionModel::ClearAndSelect );
1192   QCOMPARE( w.selectionColumnWidth(), 0.0 );
1193   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::Select );
1194   QCOMPARE( w.selectionColumnWidth(), -1.0 );
1195   w.selectionModel()->select( w.model()->index( 0, 1 ), QItemSelectionModel::ClearAndSelect );
1196   QCOMPARE( w.selectionColumnWidth(), 14.0 );
1197   w.selectionModel()->select( w.model()->index( 1, 0 ), QItemSelectionModel::Select );
1198   QCOMPARE( w.selectionColumnWidth(), -1.0 );
1199   w.setSelectionColumnWidth( 15.0 );
1200   QCOMPARE( spy.count(), 3 );
1201   QCOMPARE( w.selectionColumnWidth(), 15.0 );
1202   QCOMPARE( w.tableColumnWidth( 0 ), 15.0 );
1203   QCOMPARE( w.tableColumnWidth( 1 ), 15.0 );
1204   QCOMPARE( w.tableColumnWidth( 2 ), 0.0 );
1205   w.selectionModel()->select( w.model()->index( 2, 2 ), QItemSelectionModel::Select );
1206   QCOMPARE( w.selectionColumnWidth(), -1.0 );
1207 }
1208 
headers()1209 void TestQgsTableEditor::headers()
1210 {
1211   QgsTableEditorWidget w;
1212   QVERIFY( w.tableContents().isEmpty() );
1213 
1214   const QSignalSpy spy( &w, &QgsTableEditorWidget::tableChanged );
1215   w.setTableContents( QgsTableContents() << ( QgsTableRow() << QgsTableCell( 1 ) << QgsTableCell( 2 ) << QgsTableCell( 3 ) )
1216                       << ( QgsTableRow() << QgsTableCell( 4 )  << QgsTableCell( 5 ) << QgsTableCell( 6 ) ) );
1217   QCOMPARE( spy.count(), 1 );
1218 
1219   w.setIncludeTableHeader( true );
1220   QCOMPARE( w.tableHeaders(), QVariantList() << QVariant() << QVariant() << QVariant() );
1221 
1222   w.setTableHeaders( QVariantList() << QVariant( 11 ) << QVariant( 12 ) << QVariant( 13 ) );
1223   QCOMPARE( spy.count(), 1 );
1224   QCOMPARE( w.tableHeaders(), QVariantList() << QVariant( 11 ) << QVariant( 12 ) << QVariant( 13 ) );
1225   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content(), QVariant( 1 ) );
1226   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).content(), QVariant( 2 ) );
1227   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).content(), QVariant( 3 ) );
1228   QCOMPARE( w.tableContents().at( 1 ).at( 0 ).content(), QVariant( 4 ) );
1229   QCOMPARE( w.tableContents().at( 1 ).at( 1 ).content(), QVariant( 5 ) );
1230   QCOMPARE( w.tableContents().at( 1 ).at( 2 ).content(), QVariant( 6 ) );
1231 
1232   w.setIncludeTableHeader( false );
1233   QCOMPARE( spy.count(), 1 );
1234   QCOMPARE( w.tableHeaders(), QVariantList() );
1235   QCOMPARE( w.tableContents().at( 0 ).at( 0 ).content(), QVariant( 1 ) );
1236   QCOMPARE( w.tableContents().at( 0 ).at( 1 ).content(), QVariant( 2 ) );
1237   QCOMPARE( w.tableContents().at( 0 ).at( 2 ).content(), QVariant( 3 ) );
1238   QCOMPARE( w.tableContents().at( 1 ).at( 0 ).content(), QVariant( 4 ) );
1239   QCOMPARE( w.tableContents().at( 1 ).at( 1 ).content(), QVariant( 5 ) );
1240   QCOMPARE( w.tableContents().at( 1 ).at( 2 ).content(), QVariant( 6 ) );
1241 
1242 }
1243 
1244 
1245 QGSTEST_MAIN( TestQgsTableEditor )
1246 #include "testqgstableeditor.moc"
1247