Subversion Repositories Scribus

Rev

Rev 24826 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
16856 craig 1
/*
2
Copyright (C) 2011 Elvis Stansvik <elvstone@gmail.com>
3
 
4
For general Scribus (>=1.3.2) copyright and licensing information please refer
5
to the COPYING file provided with the program. Following this notice may exist
6
a copyright and/or license notice that predates the release of Scribus 1.3.2
7
for which a new license (GPL+exception) is in place.
8
*/
9
#ifndef PAGEITEM_TABLE_H
10
#define PAGEITEM_TABLE_H
11
 
24782 jghali 12
#include <tuple>
13
 
14
#include <QFlags>
16856 craig 15
#include <QList>
16
#include <QPointF>
17
#include <QRectF>
18
#include <QSet>
19
#include <QString>
20
 
21
#include "cellarea.h"
22
#include "pageitem.h"
23
#include "scribusapi.h"
24782 jghali 24
#include "scribusstructs.h"
16856 craig 25
#include "styles/tablestyle.h"
26
#include "tablecell.h"
27
#include "tablehandle.h"
28
 
29
class ScPainter;
30
class ScribusDoc;
31
class TablePainter;
32
 
33
/**
34
 * The PageItem_Table class represents a table.
35
 * <p>
36
 * A table is a group of cells ordered into rows and columns. Each table contains at least
37
 * one row and one column.
38
 * <p>
39
 * A table's dimensions can be changed by using <code>insertRows()</code>,
40
 * <code>insertColumns()</code>, <code>removeRows()</code>, or <code>removeColumns()</code>.
41
 * Use <code>cellAt()</code> to retrieve table cells.
42
 * <p>
43
 * Rows and columns can be resized by using <code>resizeRow()</code> and <code>resizeColumn()</code>.
44
 * The entire table can be resized by using <code>resize()</code>
45
 * <p>
46
 * Cells in the table can be merged by using <code>mergeCells()</code>. Cells that have been
47
 * previously merged can be split up again by using <code>splitCells()</code>.
48
 * <p>
49
 * The style of the table can be controlled by setting a named style for the table using
50
 * <code>setStyle()</code>. Formatting properties can also be set directly on the table.
51
 * Directly set properties overrides properties from the style.
52
 */
53
class SCRIBUS_API PageItem_Table : public PageItem
54
{
55
        Q_OBJECT
56
 
57
        Q_PROPERTY(int rows READ rows NOTIFY changed)
58
        Q_PROPERTY(int columns READ columns NOTIFY changed)
59
        Q_PROPERTY(QString fillColor READ fillColor WRITE setFillColor RESET unsetFillColor NOTIFY changed)
60
        Q_PROPERTY(TableBorder leftBorder READ leftBorder WRITE setLeftBorder RESET unsetLeftBorder NOTIFY changed)
61
        Q_PROPERTY(TableBorder rightBorder READ rightBorder WRITE setRightBorder RESET unsetRightBorder NOTIFY changed)
62
        Q_PROPERTY(TableBorder topBorder READ topBorder WRITE setTopBorder RESET unsetTopBorder NOTIFY changed)
63
        Q_PROPERTY(TableBorder bottomBorder READ bottomBorder WRITE setBottomBorder RESET unsetBottomBorder NOTIFY changed)
20633 jghali 64
        Q_PROPERTY(QString style READ styleName WRITE setStyle RESET unsetStyle NOTIFY changed)
16856 craig 65
 
66
public:
67
        /**
68
         * This enum specifies two different strategies for resizing rows and columns. With the
69
         * <code>MoveFollowing</code> resize strategy, all following rows or columns are moved
70
         * when a column is resized. With the <code>ResizeFollowing</code> strategy, the row or
71
         * column that immediately follows the resized row or column is resized to match, but
72
         * apart from that, all other rows or columns remain unaffected by the resize.
73
         */
74
        enum ResizeStrategy
75
        {
76
                MoveFollowing,
77
                ResizeFollowing
78
        };
79
 
80
        /// The minimum row height.
17302 fschmid 81
        static const double MinimumRowHeight;
16856 craig 82
 
83
        /// The minimum column width.
17302 fschmid 84
        static const double MinimumColumnWidth;
16856 craig 85
 
21944 craig 86
        Q_ENUM(ResizeStrategy HitTarget)
87
 
16856 craig 88
public:
89
        /// Construct a new table item with @a numRows rows and @a numColumns columns.
22598 craig 90
        PageItem_Table(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, int numRows = 1, int numColumns = 1);
16856 craig 91
 
92
        /// Destructor.
93
        ~PageItem_Table();
94
 
17327 fschmid 95
        /// Resizes the table to fit the frame.
96
        void adjustTable();
97
 
21132 jghali 98
        /// Return current text properties (current char + paragraph properties)
22832 craig 99
        virtual void currentTextProps(ParagraphStyle& parStyle) const override;
21132 jghali 100
 
21708 jghali 101
        /// Return the list of cell items
22832 craig 102
        virtual QList<PageItem*> getChildren() const override;
21708 jghali 103
 
22224 jghali 104
        /// Return the list of cell items
22832 craig 105
        virtual QList<PageItem*> getAllChildren() const override { return getChildren(); }
22224 jghali 106
 
16856 craig 107
        /// Returns the number of rows in the table.
108
        int rows() const { return m_rows; }
109
 
110
        /// Returns the number of columns in the table.
111
        int columns() const { return m_columns; }
112
 
113
        /**
114
         * Returns the width of the table.
115
         *
116
         * This is the width of the table grid, not including any borders along the left and right side.
117
         */
17302 fschmid 118
        double tableWidth() const { return m_columnPositions.last() + m_columnWidths.last(); }
16856 craig 119
 
120
        /**
121
         * Returns the height of the table.
122
         *
123
         * This is the height of the table grid, not including any borders along the top and left side.
124
         */
17302 fschmid 125
        double tableHeight() const { return m_rowPositions.last() + m_rowHeights.last(); }
16856 craig 126
 
127
        /**
128
         * Returns the offset of the table grid from the item origin.
129
         */
130
        QPointF gridOffset() const { return QPointF(maxLeftBorderWidth()/2, maxTopBorderWidth()/2); }
131
 
132
        /**
133
         * Returns the effective width of the table.
134
         *
135
         * The effective table width includes the width of the table grid plus half the width of the widest
136
         * borders found along its left and right side.
137
         */
17302 fschmid 138
        double effectiveWidth() const { return tableWidth() + (maxLeftBorderWidth() + maxRightBorderWidth()) / 2; }
16856 craig 139
 
140
        /**
141
         * Returns the effective height of the table.
142
         *
143
         * The effective table height includes the height of the table grid plus half the width of the widest
144
         * borders found along its top and bottom side.
145
         */
17302 fschmid 146
        double effectiveHeight() const { return tableHeight() + (maxTopBorderWidth() + maxBottomBorderWidth()) / 2; }
16856 craig 147
 
148
        /**
149
         * Resizes the table grid to @a width, @a height.
150
         *
151
         * The change in width and height will be distributed proportionally to columns and rows.
152
         *
153
         * If any row or column hits the limit MinimumRowHeight or MinimumColumnWidth, resizing in that
154
         * direction will stop for the entire table.
155
         */
17302 fschmid 156
        void resize(double width, double height);
16856 craig 157
 
158
        /**
159
         * Inserts @a numRows rows before the row at @a index.
160
         *
161
         * If @a index is rows(), a row is appended to the table.
162
         *
163
         * If @a index is less than 0 or greater than rows(), or if @a numRows is less than 1,
164
         * this method does nothing.
165
         */
166
        void insertRows(int index, int numRows);
167
 
168
        /**
169
         * Removes @a numRows rows from the table, starting with the row at @a index.
170
         *
171
         * If the specified range falls outside the table or the number of rows is
172
         * less than 1 then this method does nothing.
173
         */
174
        void removeRows(int index, int numRows);
175
 
176
        /**
177
         * Returns the height of @a row, or 0 if @a row does not exist.
178
         */
17302 fschmid 179
        double rowHeight(int row) const;
16856 craig 180
 
181
        /**
182
         * Returns the list of row heights for the table.
183
         */
22507 jghali 184
        const QList<double>& rowHeights() const { return m_rowHeights; }
16856 craig 185
 
186
        /**
187
         * Resizes @a row to @a height using resize strategy @a strategy.
188
         *
189
         * If @a row does not exists, this method does nothing.
190
         */
17302 fschmid 191
        void resizeRow(int row, double height, ResizeStrategy strategy = MoveFollowing);
16856 craig 192
 
193
        /**
194
         * Distributes the rows from @a startRow to @a endRow evenly.
195
         *
196
         * All rows in the range will have the same size while the height of the entire range will
197
         * remain unaffected.
198
         *
199
         * If the range is not in the table, this method does nothing.
200
         */
201
        void distributeRows(int startRow, int endRow);
202
 
203
        /**
204
         * Returns the position of @a row, or 0 if @a row does not exist.
205
         */
17302 fschmid 206
        double rowPosition(int row) const;
16856 craig 207
 
208
        /**
209
         * Returns the list of row positions for the table.
210
         */
22507 jghali 211
        const QList<double>& rowPositions() const { return m_rowPositions; }
16856 craig 212
 
213
        /**
214
         * Inserts @a numColumns columns before the column at @a index.
215
         *
216
         * If @a index is columns(), a column is appended to the table.
217
         *
218
         * If @a index is less than 0 or greater than columns(), or if @a numColumns is less than 1,
219
         * this method does nothing.
220
         */
221
        void insertColumns(int index, int numColumns);
222
 
223
        /**
224
         * Removes @a numColumns columns from the table, starting with the column at @a index.
225
         *
226
         * If the specified range falls outside the table or the number of columns is
227
         * less than 1 then this method does nothing.
228
         */
229
        void removeColumns(int index, int numColumns);
230
 
231
        /**
232
         * Returns the width of @a column, or 0 if @a column does not exist.
233
         */
17302 fschmid 234
        double columnWidth(int column) const;
16856 craig 235
 
236
        /**
237
         * Returns the list of column widths for the table.
238
         */
22507 jghali 239
        const QList<double>& columnWidths() const { return m_columnWidths; }
16856 craig 240
 
241
        /**
242
         * Resizes @a column to @a width using resize strategy @a strategy.
243
         *
244
         * If @a column does not exists, this method does nothing.
245
         */
17302 fschmid 246
        void resizeColumn(int column, double width, ResizeStrategy strategy = MoveFollowing);
16856 craig 247
 
248
        /**
249
         * Distributes the columns from @a startColumn to @a endColumn evenly.
250
         *
251
         * All columns in the range will have the same size while the width of the entire range will
252
         * remain unaffected.
253
         *
254
         * If the range is not in the table, this method does nothing.
255
         */
256
        void distributeColumns(int startColumn, int endColumn);
257
 
258
        /**
259
         * Returns the position of @a column, or 0 if @a column does not exist.
260
         */
17302 fschmid 261
        double columnPosition(int column) const;
16856 craig 262
 
263
        /**
264
         * Returns the list of column positions for the table.
265
         */
22507 jghali 266
        const QList<double>& columnPositions() const { return m_columnPositions; }
16856 craig 267
 
268
        /**
269
         * Merges the cell at the specified @a row and @a column with the adjacent cells into
270
         * one cell.
271
         *
272
         * The new cell will span @a numRows rows and @a numCols columns. If @a numRows or
273
         * @a numCols is less than the current number of rows or columns the cell spans then
274
         * this method does nothing.
275
         *
276
         * If any of the merged cells are already merged with other cells, the two areas of
277
         * merged cells will be united.
278
         */
279
        void mergeCells(int row, int column, int numRows, int numCols);
280
 
281
        /**
282
         * Splits the specified cell at @a row and @a column into an array of multiple cells with
283
         * dimensions specified by @a numRows and @a numCols.
284
         */
285
        void splitCell(int row, int column, int numRows, int numCols);
286
 
287
        /**
24782 jghali 288
         * Returns the set of table cells.
289
         */
290
        QSet<TableCell> cells() const;
291
 
292
        /**
16856 craig 293
         * Returns the set of selected cells.
294
         */
22507 jghali 295
        const QSet<TableCell>& selectedCells() const { return m_selection; }
16856 craig 296
 
297
        /**
298
         * Returns the set of selected rows.
299
         *
300
         * Any row that is spanned by one of the selected cells is considered selected.
301
         */
302
        QSet<int> selectedRows() const;
303
 
304
        /**
305
         * Returns the set of selected columns.
306
         *
307
         * Any column that is spanned by one of the selected cells is considered selected.
308
         */
309
        QSet<int> selectedColumns() const;
310
 
311
        /**
312
         * Adds the cell at @a row, @column to the selection.
313
         *
314
         * If there's no cell at @a row, @a column, this function does nothing.
315
         */
316
        void selectCell(int row, int column);
317
 
318
        /**
319
         * Adds the cells in the area between two cells to the selection.
320
         *
321
         * This functions first fetches the two cells at @a startRow, @a startColumn and
322
         * @a endRow, @a endColumn and then selects all cells that intersect the rectangular
323
         * area of cells that encloses the two cells.
324
         *
325
         * If any of the specified cell locations are outside the table, this function does nothing.
326
         */
327
        void selectCells(int startRow, int startColumn, int endRow, int endColumn);
328
 
329
        /**
22560 jghali 330
         * Adds the cells in specified column to the selection.
331
         *
332
         * If specified column is outside the table, this function does nothing.
333
         */
334
        void selectColumn(int column);
335
 
336
        /**
337
        * Adds the cells in specified row to the selection.
338
        *
339
        * If specified row is outside the table, this function does nothing.
340
        */
341
        void selectRow(int row);
342
 
343
        /**
16856 craig 344
         * Clears the cell selection.
345
         */
346
        void clearSelection();
347
 
348
        /**
22560 jghali 349
         * Test if item has an active cell selection
350
         */
351
        bool hasSelection() const { return m_selection.count() > 0; }
352
 
353
        /**
16856 craig 354
         * Returns the cell at @a row, @a column.
355
         *
356
         * If the cell is covered by a spanning cell, the spanning cell is returned. If the cell is
357
         * not in this table, an invalid cell is returned. The table may later mark cells returned
358
         * by this function as invalid, if the row or column containing the cell is removed.
359
         */
360
        TableCell cellAt(int row, int column) const;
361
 
362
        /**
363
         * Returns the cell at @a point, which is in canvas coordinates.
364
         *
365
         * If the cell at @a point is covered by a spanning cell, the spanning cell is returned.
366
         * If @a point is outside the table grid, an invalid cell is returned. The table may later
367
         * mark cells returned by this function as invalid, if the row or column containing the
368
         * cell is removed.
369
         */
370
        TableCell cellAt(const QPointF& point) const;
371
 
372
        /**
373
         * Returns the currently active cell.
374
         *
375
         * A table always has a valid active cell. This is the cell containing the cursor and that
376
         * will receive keyboard input during cell text editing.
377
         */
378
        TableCell activeCell() const { return m_activeCell; }
379
 
380
        /**
381
         * Moves left in the table, or do nothing if at the table end.
382
         */
383
        void moveLeft();
384
 
385
        /**
386
         * Moves right in the table, or do nothing if at the table end.
387
         */
388
        void moveRight();
389
 
390
        /**
391
         * Moves up in the table, or do nothing if at the table end.
392
         */
393
        void moveUp();
394
 
395
        /**
396
         * Moves down in the table, or do nothing if at the table end.
397
         */
398
        void moveDown();
399
 
400
        /**
401
         * Moves to @a cell, or the cell at row 0, column 0 if @a cell is invalid.
402
         */
403
        void moveTo(const TableCell& cell);
404
 
405
        /**
406
         * Performs a hit test at @a point, which is in canvas coordinates.
407
         *
408
         * The returned handle describes what was hit. @a threshold is a distance in points.
409
         * @a point is considered to hit a handle if it is within @a threshold from it.
410
         */
17302 fschmid 411
        TableHandle hitTest(const QPointF& point, double threshold) const;
16856 craig 412
 
413
        /// Resizes the table to fit the frame.
414
        void adjustTableToFrame();
415
 
416
        /// Resizes the frame to fit the table.
417
        void adjustFrameToTable();
418
 
419
        /// Sets the fill color of this table to @a color.
420
        void setFillColor(const QString& color);
421
 
422
        /// Unsets the fill color of this table.
423
        void unsetFillColor();
424
 
425
        /// Returns the fill color of this table.
426
        QString fillColor() const;
427
 
17311 fschmid 428
        /// Sets the fill shade of this table to @a color.
429
        void setFillShade(const double& shade);
430
 
431
        /// Unsets the fill shade of this table.
432
        void unsetFillShade();
433
 
434
        /// Returns the fill shade of this table.
435
        double fillShade() const;
436
 
16856 craig 437
        /// Sets the left border of this table to @a border.
438
        void setLeftBorder(const TableBorder& border);
439
 
440
        /// Unsets the left border of this table.
441
        void unsetLeftBorder();
442
 
443
        /// Returns the left border of this table.
444
        TableBorder leftBorder() const;
445
 
446
        /// Sets the right border of this table to @a border.
447
        void setRightBorder(const TableBorder& border);
448
 
449
        /// Unsets the right border of this table.
450
        void unsetRightBorder();
451
 
452
        /// Returns the right border of this table.
453
        TableBorder rightBorder() const;
454
 
455
        /// Sets the top border of this table to @a border.
456
        void setTopBorder(const TableBorder& border);
457
 
458
        /// Unsets the top border of this table.
459
        void unsetTopBorder();
460
 
461
        /// Returns the top border of this table.
462
        TableBorder topBorder() const;
463
 
464
        /// Sets the bottom border of this table to @a border.
465
        void setBottomBorder(const TableBorder& border);
466
 
467
        /// Unsets the bottom border of this table.
468
        void unsetBottomBorder();
469
 
470
        /// Returns the bottom border of this table.
471
        TableBorder bottomBorder() const;
472
 
24782 jghali 473
        /// Set tabme borders
474
        void setBorders(const TableBorder& border, TableSides selectedSides);
475
 
476
        /// Set cell borders
477
        void setCellBorders(const TableBorder& border, TableSides selectedSides);
478
 
479
        /// Set cell borders
480
        void setCellBorders(const QSet<TableCell>& cells, const TableBorder& border, TableSides selectedSides);
481
 
482
        /// Sets the cell fill color of this table to @a fillColor.
483
        void setCellFillColor(const QString& fillColor);
484
 
485
        /// Sets the cell fill color of this table to @a fillShade.
486
        void setCellFillShade(double fillShade);
487
 
488
        /// Sets the cell style of this table to @a cellStyle.
489
        void setCellStyle(const QString& cellStyle);
490
 
16856 craig 491
        /// Sets the table style of this table to @a style.
492
        void setStyle(const QString& style);
493
 
494
        /// Unsets the style of this table.
495
        void unsetStyle();
496
 
17336 fschmid 497
        /// Unsets direct formatting
498
        void unsetDirectFormatting();
499
 
16856 craig 500
        /// Returns the style of this table.
20633 jghali 501
        const TableStyle& style() const;
16856 craig 502
 
20633 jghali 503
        /// Returns the style name of this table.
504
        QString styleName() const;
505
 
16856 craig 506
        /// Updates the position and size of all cell text frames for this table.
507
        void updateCells() { updateCells(0, 0, rows() - 1, columns() - 1); }
508
 
509
        /// Updates the position and size of cell text frames for cells in the specified area.
510
        void updateCells(int startRow, int startColumn, int endRow, int endColumn);
511
 
512
        /// Returns <code>true</code> if the table is overflowing its frame.
513
        bool isOverflowing() const { return effectiveWidth() > width() || effectiveHeight() > height(); }
514
 
515
        /// Returns this item as a PageItem_Table.
22832 craig 516
        PageItem_Table* asTable() override { return this; }
16856 craig 517
 
518
        /// Returns <code>true</code>.
22832 craig 519
        bool isTable() const override { return true; }
16856 craig 520
 
521
        /// Returns PageItem::Table.
22832 craig 522
        ItemType realItemType() const override { return PageItem::Table; }
16856 craig 523
 
24417 jghali 524
        /// Return true if item is susceptible to contain text in a way or another
525
        bool isTextContainer() const override { return true; }
526
 
16856 craig 527
        /// Adds the applicable actions for this table to @a actionList.
22832 craig 528
        void applicableActions(QStringList& actionList) override;
16856 craig 529
 
530
        /// Returns a textual description of this item.
22832 craig 531
        QString infoDescription() const override { return QString(); }
16856 craig 532
 
16866 craig 533
        /// Returns the Cell Areas from this table
22507 jghali 534
        const QList<CellArea>& cellAreas() const { return m_cellAreas; }
16859 craig 535
 
16866 craig 536
        /// Returns the rows of the table for writing to SLA
22507 jghali 537
        const QList<QList<TableCell> >& cellRows() const { return m_cellRows; }
16866 craig 538
 
22222 jghali 539
        /// Set the layer for the item
22832 craig 540
        void setLayer(int layerId) override;
22222 jghali 541
 
542
        /// Set the masterpage the object is on
22832 craig 543
        void setMasterPage(int page, const QString& mpName) override;
22222 jghali 544
 
545
        /// Set the masterpage the object is on
22832 craig 546
        void setMasterPageName(const QString& mpName) override;
22222 jghali 547
 
548
        /// Set the page "owning" the object
22832 craig 549
        void setOwnerPage(int page) override;
22222 jghali 550
 
21423 jghali 551
        /// Collect named resource of table and its cells
22832 craig 552
        void getNamedResources(ResourceCollection& lists) const override;
21238 jghali 553
 
23376 jghali 554
        /// Replace named resource of table and its cells
555
        void replaceNamedResources(ResourceCollection& newNames) override;
556
 
21423 jghali 557
        /// creates valid layout information
22832 craig 558
        void layout() override;
21423 jghali 559
 
24782 jghali 560
        /** @brief Perform undo/redo action */
561
        void restore(UndoState *state, bool isUndo) override;
562
 
16856 craig 563
signals:
564
        /// This signal is emitted whenever the table changes.
565
        void changed();
566
        /// This signal is emitted whenever the cell selection changes.
567
        void selectionChanged();
568
 
569
private slots:
570
        /// Handles cell and table style changes in the document.
571
        void handleStyleChanged();
572
 
573
protected:
574
        /// Paints this item.
24739 jghali 575
        void DrawObj_Item(ScPainter *p, const QRectF& clipRect) override;
16856 craig 576
 
577
private:
578
        /// Enum describing types of changes on a table. For internal use.
579
        enum ChangeType
580
        {
581
                RowsInserted,    /**< Rows were inserted. */
582
                RowsRemoved,     /**< Rows were removed. */
583
                ColumnsInserted, /**< Columns were inserted. */
584
                ColumnsRemoved   /**< Columns were removed. */
585
        };
586
 
24782 jghali 587
        using TableBorderTuple = std::tuple<TableBorder, TableBorder, TableBorder, TableBorder, TableBorder>;
588
 
16856 craig 589
        /**
590
         * Initializes the table with @a numRows rows and @a numColumns columns.
591
         *
592
         * Should be called once, and once only, during table construction.
593
         */
594
        void initialize(int numRows, int numColumns);
595
 
596
        /// Activates the cell @a cell, or the cell at row 0, column 0 if @a cell is invalid.
597
        void activateCell(const TableCell& cell);
598
 
599
        /// Returns true if @a row is a row in this table.
600
        bool validRow(int row) const { return row >= 0 && row < m_rows; }
601
        /// Returns true if @a column is a column in this table.
602
        bool validColumn(int column) const { return column >= 0 && column < m_columns; }
603
        /// Returns true if there is a cell at @a row, @a column in this table.
604
        bool validCell(int row, int column) const { return validRow(row) && validColumn(column); }
605
 
606
        /// Returns the width of the widest border along the left side of this table.
17302 fschmid 607
        double maxLeftBorderWidth() const;
16856 craig 608
 
609
        /// Returns the width of the widest border along the right side of this table.
17302 fschmid 610
        double maxRightBorderWidth() const;
16856 craig 611
 
612
        /// Returns the width of the widest border along the top side of this table.
17302 fschmid 613
        double maxTopBorderWidth() const;
16856 craig 614
 
615
        /// Returns the width of the widest border along the bottom side of this table.
17302 fschmid 616
        double maxBottomBorderWidth() const;
16856 craig 617
 
618
        /// TODO: Turn these into strategies to be reused in resize gestures.
619
        /// Resizes @a row according to the MoveFollowing strategy and returns the new height.
17302 fschmid 620
        double resizeRowMoveFollowing(int row, double height);
16856 craig 621
        /// Resizes @a row according to the ResizeFollowing strategy and returns the new height.
17302 fschmid 622
        double resizeRowResizeFollowing(int row, double height);
16856 craig 623
        /// Resizes @a column according to the MoveFollowing strategy and returns the new width.
17302 fschmid 624
        double resizeColumnMoveFollowing(int row, double width);
16856 craig 625
        /// Resizes @a column according to the ResizeFollowing strategy and returns the new width.
17302 fschmid 626
        double resizeColumnResizeFollowing(int row, double width);
16856 craig 627
 
628
        /**
629
         * Updates row and column spans following a change in rows or columns.
630
         *
631
         * If @a changeType is <code>RowsInserted</code> or <code>ColumnsInserted</code>, @a index
632
         * and @a number specifies that @a number rows or columns were inserted before the row or
633
         * or column at @a index. Similarly, if @a changeType is <code>RowsRemoved</code> or
634
         * <code>ColumnsRemoved</code>, @a index and @a number specifies that @a number rows or
635
         * columns were removed, starting with the row or column at @a index.
636
         */
637
        void updateSpans(int index, int number, ChangeType changeType);
638
 
639
        /// Prints internal table information. For internal use.
640
        void debug() const;
641
 
642
        /// Table sanity check. Very slow. For internal use.
643
        void assertValid() const;
644
 
24782 jghali 645
        // Undo/redo setCellFillColor action
646
        void restoreCellBorders(SimpleState *state, bool isUndo);
647
 
648
        // Undo/redo setCellFillColor action
649
        void restoreCellFillColor(SimpleState *state, bool isUndo);
650
 
651
        // Undo/redo setCellFillColor action
652
        void restoreCellFillShade(SimpleState *state, bool isUndo);
653
 
654
        // Undo/redo setCellStyle action
655
        void restoreCellStyle(SimpleState *state, bool isUndo);
656
 
657
        // Undo/redo setFillColor action
658
        void restoreTableFillColor(SimpleState *state, bool isUndo);
659
 
660
        // Undo/redo unsetFillColor action
661
        void restoreTableFillColorReset(SimpleState *state, bool isUndo);
662
 
663
        // Undo/redo setFillShade action
664
        void restoreTableFillShade(SimpleState *state, bool isUndo);
665
 
666
        // Undo/redo unsetFillShade action
667
        void restoreTableFillShadeReset(SimpleState *state, bool isUndo);
668
 
669
        // Undo/redo setBorders action
670
        void restoreTableBorders(SimpleState *state, bool isUndo);
671
 
672
        // Undo/redo setLeftBorder action
673
        void restoreTableLeftBorder(SimpleState *state, bool isUndo);
674
 
675
        // Undo/redo unsetLeftBorder action
676
        void restoreTableLeftBorderReset(SimpleState *state, bool isUndo);
677
 
678
        // Undo/redo setRightBorder action
679
        void restoreTableRightBorder(SimpleState *state, bool isUndo);
680
 
681
        // Undo/redo unsetRightBorder action
682
        void restoreTableRightBorderReset(SimpleState *state, bool isUndo);
683
 
684
        // Undo/redo setBottomBorder action
685
        void restoreTableBottomBorder(SimpleState *state, bool isUndo);
686
 
687
        // Undo/redo unsetBottomBorder action
688
        void restoreTableBottomBorderReset(SimpleState *state, bool isUndo);
689
 
690
        // Undo/redo setTopBorder action
691
        void restoreTableTopBorder(SimpleState *state, bool isUndo);
692
 
693
        // Undo/redo unsetTopBorder action
694
        void restoreTableTopBorderReset(SimpleState *state, bool isUndo);
695
 
696
        // Undo/redo setStyle action
697
        void restoreTableStyle(SimpleState *state, bool isUndo);
698
 
699
        // Undo/redo unsetStyle action
700
        void restoreTableStyleReset(SimpleState *state, bool isUndo);
701
 
24810 craig 702
        // Undo/redo row height action
703
        void restoreTableRowHeight(SimpleState *state, bool isUndo);
704
 
25090 jghali 705
        // Undo/redo column width action
24810 craig 706
        void restoreTableColumnWidth(SimpleState *state, bool isUndo);
707
 
16856 craig 708
private:
16859 craig 709
        //<<Data we need to save
16856 craig 710
        /// List of rows of cells in the table.
711
        QList<QList<TableCell> > m_cellRows;
712
 
713
        /// Number of rows.
714
        int m_rows;
715
        /// Number of columns.
716
        int m_columns;
717
 
718
        /// Vertical positions of rows.
17302 fschmid 719
        QList<double> m_rowPositions;
16856 craig 720
        /// Height of rows.
17302 fschmid 721
        QList<double> m_rowHeights;
16856 craig 722
 
723
        /// Horizontal positions of columns.
17302 fschmid 724
        QList<double> m_columnPositions;
16856 craig 725
        /// Width of columns.
17302 fschmid 726
        QList<double> m_columnWidths;
16856 craig 727
 
728
        /// List of areas of merged cells.
729
        QList<CellArea> m_cellAreas;
730
 
16859 craig 731
        /// Style of the table.
732
        TableStyle m_style;
733
        //>>End of data we need to save
734
        //-----------------------------
735
        //<<Live working variables/data
16856 craig 736
        /// Set of selected cells.
737
        QSet<TableCell> m_selection;
738
 
739
        /// The table painter to paint the table with.
740
        TablePainter* m_tablePainter;
741
 
742
        /// Currently active cell.
743
        TableCell m_activeCell;
744
 
745
        /*
746
         * The two members below describe the active "logical position" on the table grid.
747
         * This position may or may not correspond with the position of the active cell.
748
         *
749
         * As an example, imagine the following scenario:
750
         *
751
         * +--------+--------+                            +--------+--------+
752
         * |        |        |                            |        | |      |
753
         * +--------+        |  --> User presses Tab -->  +--------+        |
754
         * | |      |        |                            |        |        |
755
         * +--------+--------+                            +--------+--------+
756
         *  Cursor in (1, 0)                               Cursor in (0, 1)
757
         *
758
         * The active cell is now the spanning cell at (0, 1). If we would use the row and
759
         * column of the active cell as the basis for keyboard navigation between cells,
760
         * then pressing Shift+Tab after the scenario above would bring the cursor into
761
         * cell (0, 0), not back to to (1, 0). Hence, in addition to the active cell, we
762
         * keep track of a "logical position". This is the logical position on the table
763
         * grid that is active. In the above scenario, the logical position would change
764
         * from (1, 0) to (1, 1).
765
         */
766
 
767
        /// The logical active row.
23820 craig 768
        int m_activeRow {0};
16856 craig 769
 
770
        /// The logical active column.
23820 craig 771
        int m_activeColumn {0};
16859 craig 772
        //>>End of live working variables/data
16856 craig 773
};
774
 
775
#endif // PAGEITEM_TABLE_H