1 /*************************************************************************** 2 rkoptionset - description 3 ------------------- 4 begin : Mon Oct 31 2011 5 copyright : (C) 2011, 2012 by Thomas Friedrichsmeier 6 email : thomas.friedrichsmeier@kdemail.net 7 ***************************************************************************/ 8 9 /*************************************************************************** 10 * * 11 * This program is free software; you can redistribute it and/or modify * 12 * it under the terms of the GNU General Public License as published by * 13 * the Free Software Foundation; either version 2 of the License, or * 14 * (at your option) any later version. * 15 * * 16 ***************************************************************************/ 17 18 #ifndef RKOPTIONSET_H 19 #define RKOPTIONSET_H 20 21 #include <rkcomponent.h> 22 23 #include <qmap.h> 24 #include <QDomElement> 25 #include <QTimer> 26 #include <QSet> 27 #include <QAbstractTableModel> 28 29 class RKAccordionTable; 30 class QTreeView; 31 class QPushButton; 32 class RKOptionSetDisplayModel; 33 class QStackedWidget; 34 35 /** An RKOptionSet provides a group of options for an arbitrary number of "rows". E.g. different line colors for each of a group of variables. 36 * 37 * @author Thomas Friedrichsmeier 38 */ 39 class RKOptionSet : public RKComponent { 40 Q_OBJECT 41 public: 42 RKOptionSet (const QDomElement &element, RKComponent *parent_component, QWidget *parent_widget); 43 ~RKOptionSet (); type()44 int type () override { return ComponentOptionSet; }; 45 bool isValid () override; 46 /** reimplemented from RKComponent */ 47 ComponentStatus recursiveStatus () override; 48 /** reimplemented from RKComponent */ 49 void changed () override; 50 private slots: 51 void governingPropertyChanged (RKComponentPropertyBase *property); 52 void columnPropertyChanged (RKComponentPropertyBase *property); 53 void currentRowPropertyChanged (RKComponentPropertyBase *property); 54 void serializationPropertyChanged (RKComponentPropertyBase *property); 55 void addRow (int where); 56 void removeRow (int which); 57 void currentRowChanged (int row); 58 void fetchDefaults (); 59 void slotUpdateUnfinishedRows (); 60 /** When keys in the key column change, all other columns have to be updated, accordingly. */ 61 void handleKeycolumnUpdate (); 62 protected: 63 friend class RKOptionSetDelegate; 64 void fetchPropertyValuesRecursive (PropertyValueMap *list, bool include_top_level=false, const QString &prefix=QString (), bool include_inactive_elements=false) const override; 65 friend class RKOptionSetDisplayModel; rowCount()66 int rowCount () const { return row_count->intValue (); }; 67 void setRowState (int row, bool finished, bool valid); 68 void storeRowSerialization (int row); 69 void applyContentsFromExternalColumn (RKComponentPropertyStringList* column, int row); 70 void moveRow (int old_index, int new_index); 71 72 RKComponentPropertyInt *current_row; 73 RKComponentPropertyInt *row_count; 74 /** Un-serializing an optionset's state is terribly complicated, if it isn't guaranteed to happen in a single batch. Therefore, we 75 * keep a dedicated property (serialization_of_set), which holds a _full_ serialization of the set's state. 76 * However, this representation is not kept up to date, for performance reasons. Rather it is generated only in fetchPropertyValuesRecursive(). */ 77 RKComponentPropertyBase *serialization_of_set; 78 79 /** for option sets which are "driven" (i.e. the user cannot simply add / remove rows, directly), this holds the key column, controlling addition / removal of rows in the set. 80 * if this length (or order) is changed in this row, it will also be changed in the other rows. */ 81 RKComponentPropertyStringList *keycolumn; 82 QStringList old_keys; 83 84 /** Map of properties (in the contents region) to columns which need to be updated, when the property changes. */ 85 QMultiMap<RKComponentPropertyBase *, RKComponentPropertyStringList *> columns_to_update; 86 struct ColumnInfo { 87 QString column_name; 88 QString column_label; 89 QString governor; 90 QString governor_modifier; 91 QString default_value; 92 int display_index; 93 bool external; 94 }; 95 /** Map of all columns to their meta info */ 96 QMap<RKComponentPropertyStringList *, ColumnInfo> column_map; 97 QList<RKComponentPropertyStringList*> visible_columns; 98 struct RowInfo { RowInfoRowInfo99 RowInfo (PropertyValueMap initial_values) : valid (false), finished (false), full_row_map (initial_values) {}; 100 bool valid; /**< has finished processing and is known to be valid */ 101 bool finished; /**< has finished processing */ 102 PropertyValueMap full_row_map; /**< complete status representation of this row, (see RKComponent::fetchPropertyValuesRecursive()) */ 103 }; 104 QList<RowInfo> rows; 105 PropertyValueMap default_row_state; 106 int n_unfinished_rows, n_invalid_rows; 107 int active_row; 108 /** backup of row state info for rows corresponding to keys which have been removed (in a driven set). These might get re-inserted, later. */ 109 QHash<QString, PropertyValueMap> former_row_states; 110 111 RKComponent *contents_container; 112 ComponentStatus last_known_status; 113 114 RKOptionSetDisplayModel* model; 115 RKAccordionTable *accordion; 116 117 QStackedWidget *switcher; 118 QWidget *updating_notice; 119 void updateUnfinishedRows (); 120 int return_to_row; 121 QTimer update_timer; 122 123 int min_rows; 124 int min_rows_if_any; 125 int max_rows; 126 127 bool updating; 128 /** Sets the contents from the values in given row */ 129 void setContentsForRow (int row); 130 void updateCurrentRowInDisplay (); 131 132 /** get the default value for the given column, row. */ 133 friend QString getDefaultValue (const ColumnInfo& ci, int row); 134 }; 135 136 class RKOptionSetDisplayModel : public QAbstractTableModel { 137 Q_OBJECT 138 private: 139 friend class RKOptionSet; 140 explicit RKOptionSetDisplayModel (RKOptionSet* parent); 141 virtual ~RKOptionSetDisplayModel (); 142 int rowCount (const QModelIndex & parent = QModelIndex()) const override; 143 int columnCount (const QModelIndex & parent = QModelIndex()) const override; 144 QVariant data (const QModelIndex& index, int role = Qt::DisplayRole) const override; 145 QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; 146 void triggerReset (); 147 QTimer reset_timer; 148 QStringList column_labels; 149 RKOptionSet *set; 150 151 QMimeData* mimeData (const QModelIndexList& indexes) const override; 152 QStringList mimeTypes () const override; 153 bool dropMimeData (const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) override; 154 Qt::ItemFlags flags (const QModelIndex& index) const override; 155 Qt::DropActions supportedDropActions () const override; 156 Qt::DropActions supportedDragActions () const override; 157 private slots: 158 void doResetNow (); 159 }; 160 161 #endif 162