~valavanisalex/ubuntu/maverick/scidavis/fix-604811

« back to all changes in this revision

Viewing changes to scidavis/src/future/table/future_Table.h

  • Committer: Bazaar Package Importer
  • Author(s): Ruben Molina
  • Date: 2009-09-06 11:34:04 UTC
  • Revision ID: james.westby@ubuntu.com-20090906113404-4awaey82l3686w4q
Tags: upstream-0.2.3
ImportĀ upstreamĀ versionĀ 0.2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
    File                 : Table.h
 
3
    Project              : SciDAVis
 
4
    Description          : Aspect providing a spreadsheet table with column logic
 
5
    --------------------------------------------------------------------
 
6
    Copyright            : (C) 2006-2009 Tilman Benkert (thzs*gmx.net)
 
7
    Copyright            : (C) 2006-2009 Knut Franke (knut.franke*gmx.de)
 
8
    Copyright            : (C) 2006-2007 Ion Vasilief (ion_vasilief*yahoo.fr)
 
9
                           (replace * with @ in the email addresses) 
 
10
 
 
11
 ***************************************************************************/
 
12
 
 
13
/***************************************************************************
 
14
 *                                                                         *
 
15
 *  This program is free software; you can redistribute it and/or modify   *
 
16
 *  it under the terms of the GNU General Public License as published by   *
 
17
 *  the Free Software Foundation; either version 2 of the License, or      *
 
18
 *  (at your option) any later version.                                    *
 
19
 *                                                                         *
 
20
 *  This program is distributed in the hope that it will be useful,        *
 
21
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
 
22
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
 
23
 *  GNU General Public License for more details.                           *
 
24
 *                                                                         *
 
25
 *   You should have received a copy of the GNU General Public License     *
 
26
 *   along with this program; if not, write to the Free Software           *
 
27
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
 
28
 *   Boston, MA  02110-1301  USA                                           *
 
29
 *                                                                         *
 
30
 ***************************************************************************/
 
31
#ifndef FUTURE_TABLE_H
 
32
#define FUTURE_TABLE_H
 
33
 
 
34
#include "core/AbstractPart.h"
 
35
#ifndef LEGACY_CODE_0_2_x
 
36
#include "AbstractScriptingEngine.h"
 
37
#endif
 
38
#include "globals.h"
 
39
#include <QList>
 
40
#include <QStringList>
 
41
 
 
42
class TableView;
 
43
class QUndoStack;
 
44
class QMenu;
 
45
class Column;
 
46
class QPoint;
 
47
class QAction;
 
48
class AbstractColumn;
 
49
class ActionManager;
 
50
class TableStatistics;
 
51
 
 
52
namespace future
 
53
{
 
54
 
 
55
/*!\brief Aspect providing a spreadsheet table with column logic.
 
56
 *
 
57
This class (incl. Table::Private and its commands) is one aspect in the projet hierarchy
 
58
that represents a spreadsheet table with column logic. Table provides the public API while
 
59
Table::Private completely encapsulates the data. The table commands (derived from QUndoCommand) 
 
60
encapsulate all write operations which can be undone and redone, if the table has an undo stack 
 
61
associated with it (usually by the project root aspect).
 
62
 
 
63
The underlying private data object is not visible to any classes other then those meantioned
 
64
above with one exeption:
 
65
Pointers to columns can be passed around an manipulated directly. The owner Table (parent aspect
 
66
of the Column objects) will be notified by emission of signals and react accordingly. 
 
67
All public methods of Table and Column are undo aware. 
 
68
 
 
69
Table also manages its main view of class TableView. Table and TableView can call each others
 
70
API in both directions. User interaction ist party handled in TableView and translated into 
 
71
Table API calls (e.g., when a user edits a cell this will be handled by the delegate of
 
72
TableView and Table will not know whether a script or a user changed the data.). Other parts 
 
73
of the user interaction are handled by actions provides by Table, e.g., via a context menu.
 
74
 
 
75
Selections are handled by TableView and can be queried by Table. All selection based functions
 
76
do nothing unless the view exists. The view is created by the first call to view();
 
77
*/
 
78
#ifndef LEGACY_CODE_0_2_x
 
79
class Table : public AbstractPart, public scripted
 
80
#else
 
81
class Table : public AbstractPart
 
82
#endif
 
83
{
 
84
        Q_OBJECT
 
85
 
 
86
        public:
 
87
                class Private; // This could also be private, but then all commands need to be friend classes
 
88
                friend class Private;
 
89
 
 
90
#ifndef LEGACY_CODE_0_2_x
 
91
                Table(AbstractScriptingEngine *engine, int rows, int columns, const QString &name);
 
92
#else
 
93
                Table(void *engine, int rows, int columns, const QString &name);
 
94
                void setView(TableView * view);
 
95
                friend class ::TableStatistics;
 
96
#endif
 
97
                ~Table();
 
98
 
 
99
                //! Return an icon to be used for decorating my views.
 
100
                virtual QIcon icon() const;
 
101
                //! Return a new context menu.
 
102
                /**
 
103
                 * The caller takes ownership of the menu.
 
104
                 */
 
105
                virtual QMenu *createContextMenu() const;
 
106
                //! Construct a primary view on me.
 
107
                /**
 
108
                 * This method may be called multiple times during the life time of an Aspect, or it might not get
 
109
                 * called at all. Aspects must not depend on the existence of a view for their operation.
 
110
                 */
 
111
                virtual QWidget *view();
 
112
                
 
113
                //! Insert columns
 
114
                /**
 
115
                 * Ownership of the columns is transferred to this Table.
 
116
                 *
 
117
                 * If before == columnCount() this will do the same as appendColumns();
 
118
                 */
 
119
                void insertColumns(int before, QList<Column *> new_cols);
 
120
                //! Append columns
 
121
                /*
 
122
                 * Convenience function, same as:
 
123
                 * <code>
 
124
                 * insertColumns(columnCount(), new_cols);
 
125
                 * </code>
 
126
                 */
 
127
                void appendColumns(QList<Column*> new_cols) { insertColumns(columnCount(), new_cols); }
 
128
                void removeColumns(int first, int count);
 
129
                void removeColumn(Column * col);
 
130
                void removeRows(int first, int count);
 
131
                void insertRows(int before, int count);
 
132
                void appendRows(int count) { insertRows(rowCount(), count); }
 
133
                //! Set the number of rows of the table
 
134
                void setRowCount(int new_size);
 
135
                //! Return the total number of columns in the table
 
136
                int columnCount() const;
 
137
                //! Return the total number of rows in the table
 
138
                int rowCount() const;
 
139
                //! Return the number of columns matching the given designation
 
140
                int columnCount(SciDAVis::PlotDesignation pd) const;
 
141
                //! Return column number 'index'
 
142
                Column* column(int index) const;
 
143
                //! Return the column determined by the given name
 
144
                /**
 
145
                 * This method should not be used unless absolutely necessary. 
 
146
                 * Columns should be addressed by their index. 
 
147
                 * This method is mainly meant to be used in scripts.
 
148
                 */
 
149
                Column* column(const QString & name) const;
 
150
                int columnIndex(const Column * col) const;
 
151
                //! Set the number of columns
 
152
                void setColumnCount(int new_size);
 
153
                QVariant headerData(int section, Qt::Orientation orientation,int role) const;
 
154
 
 
155
                //! Create a menu with selection related operations
 
156
                /**
 
157
                 * \param append_to if a pointer to a QMenu is passed
 
158
                 * to the function, the actions are appended to
 
159
                 * it instead of the creation of a new menu.
 
160
                 */
 
161
                QMenu * createSelectionMenu(QMenu * append_to = 0);
 
162
                //! Create a menu with column related operations
 
163
                /**
 
164
                 * \param append_to if a pointer to a QMenu is passed
 
165
                 * to the function, the actions are appended to
 
166
                 * it instead of the creation of a new menu.
 
167
                 */
 
168
                QMenu * createColumnMenu(QMenu * append_to = 0);
 
169
                //! Create a menu with row related operations
 
170
                /**
 
171
                 * \param append_to if a pointer to a QMenu is passed
 
172
                 * to the function, the actions are appended to
 
173
                 * it instead of the creation of a new menu.
 
174
                 */
 
175
                QMenu * createRowMenu(QMenu * append_to = 0);
 
176
                //! Create a menu with table related operations
 
177
                /**
 
178
                 * \param append_to if a pointer to a QMenu is passed
 
179
                 * to the function, the actions are appended to
 
180
                 * it instead of the creation of a new menu.
 
181
                 */
 
182
                QMenu * createTableMenu(QMenu * append_to = 0);
 
183
                //! Fill the part specific menu for the main window including setting the title
 
184
                /**
 
185
                 * \return true on success, otherwise false (e.g. part has no actions).
 
186
                 */
 
187
                virtual bool fillProjectMenu(QMenu * menu);
 
188
                //! Fill the part specific tool bar for the main window including setting the title
 
189
                /**
 
190
                 * \return true on success, otherwise false (e.g. part has no actions to be shown in a toolbar).
 
191
                 */
 
192
                virtual bool fillProjectToolBar(QToolBar * bar);
 
193
 
 
194
                //! Determine the corresponding X column
 
195
                int colX(int col);
 
196
                //! Determine the corresponding Y column
 
197
                int colY(int col);
 
198
                //! Set a plot menu 
 
199
                /**
 
200
                 * The table takes ownership of the menu.
 
201
                 */
 
202
                void setPlotMenu(QMenu * menu);
 
203
                //! Open the sort dialog for the given columns
 
204
                void sortDialog(QList<Column*> cols);
 
205
                //! Set default for comment visibility for table views
 
206
                static void setDefaultCommentVisibility(bool visible) { d_default_comment_visibility = visible; }
 
207
                //! Return the default for comment visibility for table views
 
208
                static bool defaultCommentVisibility() { return d_default_comment_visibility; }
 
209
                //! Return the text displayed in the given cell
 
210
                QString text(int row, int col);
 
211
                void setSelectionAs(SciDAVis::PlotDesignation pd);
 
212
                void copy(Table * other);
 
213
 
 
214
                //! \name serialize/deserialize
 
215
                //@{
 
216
                //! Save as XML
 
217
                virtual void save(QXmlStreamWriter *) const;
 
218
                //! Load from XML
 
219
                virtual bool load(XmlStreamReader *);
 
220
                bool readColumnWidthElement(XmlStreamReader * reader);
 
221
                //@}
 
222
                
 
223
        public:
 
224
                static ActionManager * actionManager();
 
225
                static void initActionManager();
 
226
                static int defaultColumnWidth() { return default_column_width; }
 
227
                static void setDefaultColumnWidth(int width) { default_column_width = width; }
 
228
        private:
 
229
                static ActionManager * action_manager;
 
230
                // TODO: the default sizes are to be controlled by the global Table settings
 
231
                static int default_column_width;
 
232
                //! Private ctor for initActionManager() only
 
233
                Table();
 
234
 
 
235
        public slots:
 
236
                //! Clear the whole table
 
237
                void clear();
 
238
#ifndef LEGACY_CODE_0_2_x
 
239
                //! Clear all mask in the table
 
240
                void clearMasks();
 
241
#endif
 
242
 
 
243
                //! Append one column
 
244
                void addColumn();
 
245
                //! Append as many columns as are selected
 
246
                void addColumns();
 
247
                //! Append as many rows as are selected
 
248
                void addRows();
 
249
                void cutSelection();
 
250
                void copySelection();
 
251
                void pasteIntoSelection();
 
252
                void clearSelectedCells();
 
253
                void goToCell();
 
254
#ifndef LEGACY_CODE_0_2_x
 
255
                void maskSelection();
 
256
                void unmaskSelection();
 
257
#endif
 
258
                void setFormulaForSelection();
 
259
                void recalculateSelectedCells();
 
260
                void fillSelectedCellsWithRowNumbers();
 
261
                void fillSelectedCellsWithRandomNumbers();
 
262
                //! Open the sort dialog for all columns
 
263
                void sortTable();
 
264
                //! Insert columns depending on the selection
 
265
                void insertEmptyColumns();
 
266
                void removeSelectedColumns();
 
267
                void clearSelectedColumns();
 
268
                void clearSelectedRows();
 
269
                void setSelectedColumnsAsX();
 
270
                void setSelectedColumnsAsY();
 
271
                void setSelectedColumnsAsZ();
 
272
                void setSelectedColumnsAsXError();
 
273
                void setSelectedColumnsAsYError();
 
274
                void setSelectedColumnsAsNone();
 
275
                void normalizeColumns(QList< Column* > cols);
 
276
                void normalizeSelectedColumns();
 
277
                void normalizeSelection();
 
278
                void sortSelectedColumns();
 
279
                void statisticsOnSelectedColumns();
 
280
                void statisticsOnSelectedRows();
 
281
                //! Insert rows depending on the selection
 
282
                void insertEmptyRows();
 
283
                void removeSelectedRows();
 
284
                void selectAll();
 
285
                void dimensionsDialog();
 
286
                void editTypeAndFormatOfSelectedColumns();
 
287
                void editDescriptionOfCurrentColumn();
 
288
                void moveColumn(int from, int to);
 
289
                //! Sort the given list of column
 
290
                /*
 
291
                 * If 'leading' is a null pointer, each column is sorted separately.
 
292
                 */
 
293
                void sortColumns(Column * leading, QList<Column*> cols, bool ascending);
 
294
                //! Show a context menu for the selected cells
 
295
                /**
 
296
                 * \param pos global position of the event 
 
297
                */
 
298
                void showTableViewContextMenu(const QPoint& pos);
 
299
                //! Show a context menu for the selected columns
 
300
                /**
 
301
                 * \param pos global position of the event 
 
302
                */
 
303
                void showTableViewColumnContextMenu(const QPoint& pos);
 
304
                //! Show a context menu for the selected rows
 
305
                /**
 
306
                 * \param pos global position of the event 
 
307
                */
 
308
                void showTableViewRowContextMenu(const QPoint& pos);
 
309
 
 
310
        protected:
 
311
                //! Called after a new child has been inserted or added.
 
312
                /**
 
313
                 * Unlike the aspectAdded() signals, this method does not get called inside undo/redo actions;
 
314
                 * allowing subclasses to execute undo commands of their own.
 
315
                 */
 
316
                virtual void completeAspectInsertion(AbstractAspect * aspect, int index);
 
317
                //! Called before a child is removed.
 
318
                /**
 
319
                 * Unlike the aspectAboutToBeRemoved() signals, this method does not get called inside undo/redo actions;
 
320
                 * allowing subclasses to execute undo commands of their own.
 
321
                 */
 
322
                virtual void prepareAspectRemoval(AbstractAspect * aspect);
 
323
 
 
324
        public:
 
325
                //! This method should only be called by the view.
 
326
                /** This method does not change the view, it only changes the
 
327
                 * values that are saved when the table is saved. The view
 
328
                 * has to take care of reading and applying these values */
 
329
                void setColumnWidth(int col, int width);
 
330
                int columnWidth(int col) const;
 
331
 
 
332
        private:
 
333
                //! Internal function to connect all column signals
 
334
                void connectColumn(const Column* col);
 
335
                //! Internal function to disconnect a column
 
336
                void disconnectColumn(const Column* col);
 
337
 
 
338
        private slots:
 
339
                //! \name Column event handlers
 
340
                //@{
 
341
                void handleDescriptionChange(const AbstractAspect * aspect);
 
342
                void handleModeChange(const AbstractColumn * col);
 
343
                void handlePlotDesignationChange(const AbstractColumn * col);
 
344
                void handleDataChange(const AbstractColumn * col);
 
345
                void handleRowsAboutToBeInserted(const AbstractColumn * col, int before, int count);
 
346
                void handleRowsInserted(const AbstractColumn * col, int before, int count);
 
347
                void handleRowsAboutToBeRemoved(const AbstractColumn * col, int first, int count);
 
348
                void handleRowsRemoved(const AbstractColumn * col, int first, int count);
 
349
                //@}
 
350
                void adjustActionNames();
 
351
 
 
352
        signals:
 
353
                void columnsAboutToBeInserted(int before, QList<Column*> new_cols);
 
354
                void columnsInserted(int first, int count);
 
355
                void columnsAboutToBeReplaced(int first, int count);
 
356
                void columnsReplaced(int first, int count);
 
357
                void columnsAboutToBeRemoved(int first, int count);
 
358
                void columnsRemoved(int first, int count);
 
359
                void rowsAboutToBeInserted(int before, int count);
 
360
                void rowsInserted(int first, int count);
 
361
                void rowsAboutToBeRemoved(int first, int count);
 
362
                void rowsRemoved(int first, int count);
 
363
                void dataChanged(int top, int left, int bottom, int right);
 
364
                void headerDataChanged(Qt::Orientation orientation, int first, int last);
 
365
#ifdef LEGACY_CODE_0_2_x
 
366
                void recalculate();
 
367
                void requestRowStatistics();
 
368
                void requestColumnStatistics();
 
369
#endif
 
370
 
 
371
        private:
 
372
                void createActions();
 
373
                void connectActions();
 
374
                void addActionsToView();
 
375
                QMenu * d_plot_menu;
 
376
                static bool d_default_comment_visibility;
 
377
 
 
378
                //! \name selection related actions
 
379
                //@{
 
380
                QAction * action_cut_selection;
 
381
                QAction * action_copy_selection;
 
382
                QAction * action_paste_into_selection;
 
383
#ifndef LEGACY_CODE_0_2_x
 
384
                QAction * action_mask_selection;
 
385
                QAction * action_unmask_selection;
 
386
#endif
 
387
                QAction * action_set_formula;
 
388
                QAction * action_clear_selection;
 
389
                QAction * action_recalculate;
 
390
                QAction * action_fill_row_numbers;
 
391
                QAction * action_fill_random;
 
392
                QAction * action_normalize_selection;
 
393
                //@}
 
394
                //! \name table related actions
 
395
                //@{
 
396
                QAction * action_toggle_comments;
 
397
                QAction * action_toggle_tabbar;
 
398
                QAction * action_select_all;
 
399
                QAction * action_add_column;
 
400
                QAction * action_clear_table;
 
401
#ifndef LEGACY_CODE_0_2_x
 
402
                QAction * action_clear_masks;
 
403
#endif
 
404
                QAction * action_sort_table;
 
405
                QAction * action_go_to_cell;
 
406
                QAction * action_dimensions_dialog;
 
407
                QAction * action_formula_mode;
 
408
                //@}
 
409
                //! \name column related actions
 
410
                //@{
 
411
                QAction * action_insert_columns;
 
412
                QAction * action_remove_columns;
 
413
                QAction * action_clear_columns;
 
414
                QAction * action_add_columns;
 
415
                QAction * action_set_as_x;
 
416
                QAction * action_set_as_y;
 
417
                QAction * action_set_as_z;
 
418
                QAction * action_set_as_xerr;
 
419
                QAction * action_set_as_yerr;
 
420
                QAction * action_set_as_none;
 
421
                QAction * action_normalize_columns;
 
422
                QAction * action_sort_columns;
 
423
                QAction * action_statistics_columns;
 
424
                QAction * action_type_format;
 
425
                QAction * action_edit_description;
 
426
                //@}
 
427
                //! \name row related actions
 
428
                //@{
 
429
                QAction * action_insert_rows;
 
430
                QAction * action_remove_rows;
 
431
                QAction * action_clear_rows;
 
432
                QAction * action_add_rows;
 
433
                QAction * action_statistics_rows;
 
434
                //@}
 
435
 
 
436
                TableView *d_view;
 
437
                Private *d_table_private;
 
438
};
 
439
 
 
440
/**
 
441
  This private class manages column based data (i.e., 1D vector based 
 
442
  data such as x-values and y-values for a plot) for a Table. Its
 
443
  API is to be called by Table and table commands only. Table 
 
444
  may only call the reading functions to ensure that undo/redo
 
445
  is possible for all data changing operations.
 
446
 
 
447
  Each column is represented by a Column object and can be directly 
 
448
  accessed by the pointer returned by column(). Most of the column 
 
449
  manipulation is done directly to the columns. The signals of
 
450
  the columns are connected to various handlers in Table which
 
451
  acts according to all changes made to the columns.
 
452
 
 
453
  The Column objects are managed as child aspects by Table.
 
454
 
 
455
  Every column has two filters as children: An input filter that
 
456
  can convert a string (e.g., entered by the user in a cell) to
 
457
  the column's data type and an output filter that delivers
 
458
  the correct string representation to display in a table.
 
459
 
 
460
  The number of columns in the Table will always be equal to
 
461
  d_columns.size(). The number of rows is generally indepenent
 
462
  of the number of rows in the wrapped columns. It is however
 
463
  always adjusted to be large enough to display the longest column. 
 
464
  When columns are inserted, resized etc., the table is resized 
 
465
  automatically.
 
466
  */
 
467
class Table::Private
 
468
{
 
469
        public:
 
470
                Private(Table *owner) : d_owner(owner), d_column_count(0), d_row_count(0) {}
 
471
                //! Replace columns completely
 
472
                /**
 
473
                 * \param first the first column to be replaced
 
474
                 * \param new_cols list of the columns that replace the old ones
 
475
                 * This does not delete the replaced columns.
 
476
                 */
 
477
                void replaceColumns(int first, QList<Column*> new_cols);
 
478
                //! Insert columns before column number 'before'
 
479
                /**
 
480
                 * If 'first' is equal to the number of columns,
 
481
                 * the columns will be appended.
 
482
                 * \param before index of the column to insert before
 
483
                 * \param cols a list of column data objects
 
484
                 */
 
485
                void insertColumns(int before, QList<Column*> cols);
 
486
                //! Remove Columns
 
487
                /**
 
488
                 * This does not delete the removed columns because this
 
489
                 * must be handled by the undo/redo system.
 
490
                 * \param first index of the first column to be removed
 
491
                 * \param count number of columns to remove
 
492
                 */
 
493
                void removeColumns(int first, int count);
 
494
                //! Append columns to the table
 
495
                /**
 
496
                 * \sa insertColumns()
 
497
                 */
 
498
                void appendColumns(QList<Column*> cols);
 
499
                //! Move a column to another position
 
500
                void moveColumn(int from, int to);
 
501
                //! Return the number of columns in the table
 
502
                int columnCount() const { return d_column_count; }
 
503
                //! Return the number of rows in the table
 
504
                int rowCount() const { return d_row_count; }
 
505
                //! Set the number of rows of the table
 
506
                void setRowCount(int count);
 
507
                //! Return the full column header string
 
508
                QString columnHeader(int col);
 
509
                //! Return the number of columns with a given plot designation
 
510
                int numColsWithPD(SciDAVis::PlotDesignation pd);
 
511
                //! Return column number 'index'
 
512
                Column* column(int index) const;
 
513
                //! Return the index of the given column in the table.
 
514
                /**
 
515
                 * \return the index or -1 if the column is not in the table
 
516
                 */
 
517
                int columnIndex(const Column * col) const 
 
518
                { 
 
519
                        for(int i=0; i<d_columns.size(); i++)
 
520
                                if(d_columns.at(i) == col) return i;
 
521
                        return -1;
 
522
                }
 
523
                QString name() const { return d_owner->name(); }
 
524
                QVariant headerData(int section, Qt::Orientation orientation,int role) const;
 
525
 
 
526
                //! Update the vertical header labels
 
527
                /**
 
528
                 * This must be called whenever rows are added
 
529
                 * or removed.
 
530
                 * \param start_row first row that needs to be updated
 
531
                 */
 
532
                void updateVerticalHeader(int start_row);
 
533
                //! Update the horizontal header labels
 
534
                /**
 
535
                 * This must be called whenever columns are added or
 
536
                 * removed and when comments, labels, and column types
 
537
                 * change.
 
538
                 * \param start_col first column that needs to be updated
 
539
                 * \param end_col last column that needs to be updated
 
540
                 */
 
541
                void updateHorizontalHeader(int start_col, int end_col);
 
542
                void setColumnWidth(int col, int width) { d_column_widths[col] = width; }
 
543
                int columnWidth(int col) const { return d_column_widths.at(col); }
 
544
 
 
545
        private:
 
546
                //! The owner aspect
 
547
                Table *d_owner;
 
548
                //! The number of columns
 
549
                int d_column_count;
 
550
                //! The maximum number of rows of all columns
 
551
                int d_row_count;
 
552
                //! Vertical header data
 
553
                QStringList d_vertical_header_data;
 
554
                //! Horizontal header data
 
555
                QStringList d_horizontal_header_data;
 
556
                //! List of pointers to the column data vectors
 
557
                QList<Column *> d_columns;      
 
558
                //! Internal function to put together the column header
 
559
                /**
 
560
                 * Don't use this outside updateHorizontalHeader()
 
561
                 */
 
562
                void composeColumnHeader(int col, const QString& label);
 
563
                //! Columns widths
 
564
                QList<int> d_column_widths;
 
565
};
 
566
 
 
567
} // namespace
 
568
 
 
569
#endif
 
570