SGL
gtable.h
1 /*
2  * File: gtable.h
3  * --------------
4  * This file exports the GTable class for a graphical editable 2D table.
5  *
6  * @author Marty Stepp
7  * @version 2021/04/03
8  * - removed dependency on custom collections
9  * @version 2018/08/23
10  * - renamed to gtable.h to replace Java version
11  * @version 2018/07/17
12  * - initial version, based on gtable.h
13  * @since 2018/07/17
14  */
15 
16 
17 #ifndef _gtable_h
18 #define _gtable_h
19 
20 #include <map>
21 #include <string>
22 #include <QAbstractItemModel>
23 #include <QBrush>
24 #include <QFont>
25 #include <QItemSelection>
26 #include <QStyledItemDelegate>
27 #include <QTableWidget>
28 
29 #include "grid.h"
30 #include "ginteractor.h"
31 #include "gobjects.h"
32 #include "gtypes.h"
33 
34 class _Internal_QTableWidget;
35 
52 class GTable : public GInteractor {
53 public:
62  COLUMN_HEADER_NONE, // headers will not show
63  COLUMN_HEADER_EXCEL, // A, B, ..., Z, AA, AB, ...
64  COLUMN_HEADER_NUMERIC // 1, 2, 3, ...
65  };
66 
74  GTable(int rows = 0, int columns = 0, double width = 0, double height = 0,
75  QWidget* parent = nullptr);
76 
77  ~GTable() override;
78 
83  virtual void autofitColumnWidths();
84 
88  virtual void clear();
89 
94  virtual void clearCell(int row, int column);
95 
99  virtual void clearFormatting();
100 
104  virtual void clearCellFormatting(int row, int column);
105 
110  virtual void clearSelection();
111 
115  virtual void fill(const string& text);
116 
121  virtual string get(int row, int column) const;
122 
127  virtual ColumnHeaderStyle getColumnHeaderStyle() const;
128 
134  virtual double getColumnWidth(int column) const;
135 
136  /* @inherit */
137  _Internal_QWidget* getInternalWidget() const override;
138 
144  virtual double getRowHeight(int row) const;
145 
150  virtual GridLocation getSelectedCell() const;
151 
157  virtual void getSelectedCell(int& row, int& column) const;
158 
163  virtual string getSelectedCellValue() const;
164 
169  virtual int getSelectedColumn() const;
170 
175  virtual int getSelectedRow() const;
176 
177  /* @inherit */
178  string getType() const override;
179 
180  /* @inherit */
181  QWidget* getWidget() const override;
182 
186  virtual bool hasSelectedCell() const;
187 
192  virtual int height() const;
193 
199  virtual bool inTableBounds(int row, int column) const;
200 
205  virtual bool isEditable() const;
206 
211  virtual int numCols() const;
212 
217  virtual int numRows() const;
218 
223  virtual void removeTableListener();
224 
225  /* @inherit */
226  void requestFocus() override;
227 
233  virtual void resize(int numRows, int numCols);
234 
239  virtual bool rowColumnHeadersVisible() const;
240 
248  virtual void select(int row, int column);
249 
254  virtual void set(int row, int column, const string& text);
255 
260  void setBackground(int rgb) override;
261 
266  void setBackground(const string& color) override;
267 
273  virtual void setCellAlignment(int row, int column, HorizontalAlignment alignment);
274 
281  virtual void setCellBackground(int row, int column, int color);
282 
289  virtual void setCellBackground(int row, int column, const string& color);
290 
297  virtual void setCellFont(int row, int column, const string& font);
298 
305  virtual void setCellForeground(int row, int column, int color);
306 
313  virtual void setCellForeground(int row, int column, const string& color);
314 
320  void setColor(int rgb) override;
321 
327  void setColor(const string& color) override;
328 
334  virtual void setColumnAlignment(int column, HorizontalAlignment alignment);
335 
342  virtual void setColumnBackground(int column, int color);
343 
350  virtual void setColumnBackground(int column, const string& color);
351 
358  virtual void setColumnFont(int column, const string& font);
359 
366  virtual void setColumnForeground(int column, int color);
367 
374  virtual void setColumnForeground(int column, const string& color);
375 
381  virtual void setColumnWidth(int column, double width);
382 
387  virtual void setColumnHeaderStyle(ColumnHeaderStyle style);
388 
393  virtual void setEditable(bool editable);
394 
401  virtual void setEditorValue(int row, int column, const string& text);
402 
406  void setFont(const QFont& font) override;
407 
412  void setFont(const string& font) override;
413 
419  void setForeground(int rgb) override;
420 
426  void setForeground(const string& color) override;
427 
432  virtual void setHorizontalAlignment(HorizontalAlignment alignment);
433 
439  virtual void setRowAlignment(int row, HorizontalAlignment alignment);
440 
447  virtual void setRowBackground(int row, int rgb);
448 
455  virtual void setRowBackground(int row, const string& color);
456 
463  virtual void setRowFont(int row, const string& font);
464 
471  virtual void setRowForeground(int row, int rgb);
472 
479  virtual void setRowForeground(int row, const string& color);
480 
485  virtual void setRowColumnHeadersVisible(bool visible);
486 
492  virtual void setRowHeight(int row, double width);
493 
498  virtual void setSelectedCellValue(const string& text);
499 
504  virtual void setTableListener(GEventListener func);
505 
510  virtual void setTableListener(GEventListenerVoid func);
511 
516  virtual int width() const;
517 
518 private:
519  Q_DISABLE_COPY(GTable)
520 
521  // Represents cascading styles on a cell, row, column, or table.
522  struct TableStyle {
523  int background;
524  int foreground;
525  string font;
526  HorizontalAlignment alignment;
527  // TODO: borders?
528 
529  TableStyle() {
530  background = 0;
531  foreground = 0;
532  font = "";
533  alignment = ALIGN_LEFT;
534  }
535 
536  bool isSet() const {
537  return background >= 0
538  && foreground >= 0
539  && !font.empty()
540  && alignment >= 0;
541  }
542 
543  void mergeWith(const TableStyle& other) {
544  if (other.background >= 0) {
545  background = other.background;
546  }
547  if (other.foreground >= 0) {
548  foreground = other.foreground;
549  }
550  if (!other.font.empty()) {
551  font = other.font;
552  }
553  if (other.alignment >= 0) {
554  alignment = other.alignment;
555  }
556  }
557 
558  TableStyle mergedWith(const TableStyle& other) {
559  TableStyle copy = *this;
560  copy.mergeWith(other);
561  return copy;
562  }
563 
564  static TableStyle unset() {
565  TableStyle style;
566  style.background = -1;
567  style.foreground = -1;
568  style.font = "";
569  style.alignment = (HorizontalAlignment) -1;
570  return style;
571  }
572  };
573 
574  // static variables for default formatting:
575  // background/foreground colors
576  // font
577  // alignment
578  static TableStyle _defaultCellStyle;
579 
580  // member variables
581  _Internal_QTableWidget* _iqtableview;
582  ColumnHeaderStyle _columnHeaderStyle;
583 
584  // styles on table, rows, columns, cells
585  std::map<int, TableStyle> _rowStyles;
586  std::map<int, TableStyle> _columnStyles;
587  TableStyle _globalCellStyle;
588 
589  void applyStyleToCell(int row, int column, const TableStyle& style);
590 
591  /*
592  * @throw ErrorException if the given row/column values are out of bounds.
593  */
594  void checkColumn(const string& member, int column) const;
595  void checkIndex(const string& member, int row, int column) const;
596  void checkRow(const string& member, int row) const;
597 
598  void ensureColumnStyle(int column);
599  void ensureDefaultFormatting() const; // const hack
600  void ensureGlobalCellStyle();
601  void ensureRowStyle(int row);
602  TableStyle getMergedStyleForCell(int row, int column);
603 
604  // Internal setters for cell formatting.
605  virtual void setCellAlignmentInternal(int row, int column, HorizontalAlignment alignment);
606  virtual void setCellBackgroundInternal(int row, int column, int color);
607  virtual void setCellFontInternal(int row, int column, const string& font);
608  virtual void setCellForegroundInternal(int row, int column, int color);
609 
610  static string toExcelColumnName(int col);
611  // static GridLocation toRowColumn(const string& excelColumnName);
612 
613  void updateColumnHeaders();
614 
615  friend class _Internal_QTableWidget;
616 };
617 
622 class _Internal_QItemDelegate : public QStyledItemDelegate {
623  Q_OBJECT
624 
625 public:
626  _Internal_QItemDelegate(QObject* parent = nullptr);
627  virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;
628  virtual void destroyEditor(QWidget* editor, const QModelIndex& index) const;
629  virtual QWidget* getEditor() const;
630 
631 private:
632  QWidget* _editor;
633 };
634 
635 
640 class _Internal_QTableWidget : public QTableWidget, public _Internal_QWidget {
641  Q_OBJECT
642 
643 public:
644  _Internal_QTableWidget(GTable* gtable, int rows, int columns, QWidget* parent = nullptr);
645  void detach() override;
646  bool edit(const QModelIndex& index, QAbstractItemView::EditTrigger trigger, QEvent* event) override;
647  virtual QWidget* getEditor() const;
648  virtual _Internal_QItemDelegate* getItemDelegate() const;
649  virtual bool isEditing() const;
650  void closeEditor(QWidget* editor, QAbstractItemDelegate::EndEditHint hint) override;
651  void keyPressEvent(QKeyEvent* event) override;
652  QSize sizeHint() const override;
653 
654 public slots:
655  void handleCellChange(int row, int column);
656  void handleCellDoubleClick(int row, int column);
657  void handleSelectionChange(const QItemSelection& selected, const QItemSelection& deselected);
658 
659 private:
660  GTable* _gtable;
661  _Internal_QItemDelegate* _delegate;
662  int _lastKeyPressed;
663 
664  void fireTableEvent(EventType eventType, const string& eventName, int row = -1, int col = -1);
665 
666  friend class GTable;
667 };
668 
669 #endif // _gtable_h
void setFont(const QFont &font) override
Sets the font used to display each cell&#39;s text.
Definition: gtable.cpp:579
virtual void clearFormatting()
Removes any per-cell/column/row formatting that has been applied to the table.
Definition: gtable.cpp:107
Definition: gtable.h:64
virtual double getRowHeight(int row) const
Returns the height of the given row index in pixels.
Definition: gtable.cpp:218
virtual void setEditorValue(int row, int column, string text)
Modifies the value in the cell that is currently being edited to store the given text.
Definition: gtable.cpp:566
virtual void setRowFont(int row, string font)
Sets the text font of the given row to the given font.
Definition: gtable.cpp:702
A GTable represents a graphical editable 2D table, like a mediocre facsimile of an Excel spreadsheet...
Definition: gtable.h:52
virtual int getSelectedColumn() const
Returns the column of the cell that is currently selected, or -1 if no cell is currently selected...
Definition: gtable.cpp:248
virtual void setCellFont(int row, int column, string font)
Sets the text font of the given cell to the given RGB color.
Definition: gtable.cpp:422
virtual void fill(string text)
Sets every cell in the table to have the given value.
Definition: gtable.cpp:174
virtual void setHorizontalAlignment(HorizontalAlignment alignment)
Sets the horizontal alignment of the text in all cells in the table.
Definition: gtable.cpp:642
virtual void setColumnWidth(int column, double width)
Sets the given column index to have the given width in pixels.
Definition: gtable.cpp:542
virtual bool hasSelectedCell() const
Returns true if a cell is currently selected.
Definition: gtable.cpp:264
virtual void setColumnAlignment(int column, HorizontalAlignment alignment)
Sets the horizontal alignment of the given column.
Definition: gtable.cpp:458
void setForeground(int rgb) override
Sets the color used for the text of each cell.
Definition: gtable.cpp:610
virtual void removeTableListener()
Removes the table listener from this button so that it will no longer call it when events occur...
Definition: gtable.cpp:289
virtual void setCellAlignment(int row, int column, HorizontalAlignment alignment)
Sets the horizontal alignment of the given cell.
Definition: gtable.cpp:394
virtual void setCellForeground(int row, int column, int color)
Sets the foreground/text color of the given cell to the given color.
Definition: gtable.cpp:433
virtual int numRows() const
Returns the number of rows in the table.
Definition: gtable.cpp:285
void requestFocus() override
Transfers keyboard focus to this interactor.
Definition: gtable.cpp:300
virtual bool rowColumnHeadersVisible() const
Returns whether row and column headers are shown in the table.
Definition: gtable.cpp:341
virtual int numCols() const
Returns the number of columns in the table.
Definition: gtable.cpp:281
virtual void autofitColumnWidths()
Changes widths of all columns to be perfectly large enough to fit their contents. ...
Definition: gtable.cpp:70
string getType() const override
Returns a string representing the class name of this interactor, such as "GButton" or "GCheckBox"...
Definition: gtable.cpp:256
virtual double getColumnWidth(int column) const
Returns the width of the given column index in pixels.
Definition: gtable.cpp:195
virtual void setRowHeight(int row, double width)
Sets the given row index to have the given height in pixels.
Definition: gtable.cpp:744
This abstract class is the superclass for all graphical interactors.
Definition: ginteractor.h:48
virtual void setColumnForeground(int column, int color)
Sets the foreground/text color of the given column to the given color.
Definition: gtable.cpp:507
GTable(int rows=0, int columns=0, double width=0, double height=0, QWidget* parent=nullptr)
Constructs a new table with the given dimensions and (optional) size.
Definition: gtable.cpp:43
virtual void setCellBackground(int row, int column, int color)
Sets the background color of the given cell to the given color.
Definition: gtable.cpp:407
virtual void setTableListener(GEventListener func)
Sets the given function to be called when events occur in this table.
Definition: gtable.cpp:761
virtual void setSelectedCellValue(string text)
Sets the text in the cell that is currently selected.
Definition: gtable.cpp:754
virtual void setColumnBackground(int column, int color)
Sets the background color of the given column to the given color.
Definition: gtable.cpp:473
virtual void clearCellFormatting(int row, int column)
Removes any formatting that has been applied to the given cell.
Definition: gtable.cpp:123
ColumnHeaderStyle
Styles of column header labels that can be shown.
Definition: gtable.h:61
virtual string getSelectedCellValue() const
Returns the text in the cell that is currently selected.
Definition: gtable.cpp:239
virtual void clearCell(int row, int column)
Sets the given cell to store an empty string value.
Definition: gtable.cpp:102
Definition: gtable.h:63
virtual void clear()
Sets all cells in the table to store an empty string value.
Definition: gtable.cpp:94
virtual int height() const
Returns the number of rows in the table.
Definition: gtable.cpp:269
virtual int getSelectedRow() const
Returns the row of the cell that is currently selected, or -1 if no cell is currently selected...
Definition: gtable.cpp:252
virtual int width() const
Returns the number of columns in the table.
Definition: gtable.cpp:816
virtual void setRowBackground(int row, int rgb)
Sets the background color of the given row to the given RGB color.
Definition: gtable.cpp:683
virtual void resize(int numRows, int numCols)
Modifies the table to have the given number of rows and columns.
Definition: gtable.cpp:311
virtual void setColumnHeaderStyle(ColumnHeaderStyle style)
Sets the column headers to use the given style.
Definition: gtable.cpp:526
virtual ColumnHeaderStyle getColumnHeaderStyle() const
Returns the column headers to use the given style.
Definition: gtable.cpp:191
void setBackground(int rgb) override
Sets the background color that appears behind each cell.
Definition: gtable.cpp:362
virtual bool isEditable() const
Returns whether cells of the table can be edited.
Definition: gtable.cpp:277
QWidget* getWidget() const override
Returns a direct pointer to the internal Qt widget being wrapped by this interactor.
Definition: gtable.cpp:260
virtual void setEditable(bool editable)
Sets whether cells of the table can be edited.
Definition: gtable.cpp:552
virtual void setRowAlignment(int row, HorizontalAlignment alignment)
Sets the horizontal alignment of the given row.
Definition: gtable.cpp:668
virtual bool inTableBounds(int row, int column) const
Returns true if the given 0-based row/column index is within the bounds of the table.
Definition: gtable.cpp:273
_Internal_QWidget* getInternalWidget() const override
Returns a direct pointer to the internal Qt widget being wrapped by this interactor.
Definition: gtable.cpp:200
void setColor(int rgb) override
Sets the color used for the text of each cell.
Definition: gtable.cpp:450
virtual void setColumnFont(int column, string font)
Sets the text font of the given column to the given RGB color.
Definition: gtable.cpp:492
virtual void setRowColumnHeadersVisible(bool visible)
Sets whether row and column headers should be shown in the table.
Definition: gtable.cpp:737
virtual void clearSelection()
Deselects any currently selected cell.
Definition: gtable.cpp:143
virtual void setRowForeground(int row, int rgb)
Sets the foreground/text color of the given row to the given color.
Definition: gtable.cpp:717
~GTable() override
Definition: gtable.cpp:57
virtual GridLocation getSelectedCell() const
Returns the row and column of the cell that is currently selected.
Definition: gtable.cpp:223
virtual void select(int row, int column)
Sets the given cell to become currently selected, replacing any previous selection.
Definition: gtable.cpp:346
Definition: gtable.h:62