1 /*************************************************************************** 2 rkvareditmodel - description 3 ------------------- 4 begin : Mon Nov 05 2007 5 copyright : (C) 2007, 2010, 2011 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 RKVAREDITMODEL 19 #define RKVAREDITMODEL 20 21 #include <QAbstractTableModel> 22 #include <QItemSelectionRange> 23 #include <QList> 24 25 #include "rktextmatrix.h" 26 #include "../core/rkvariable.h" 27 #include "../core/rkmodificationtracker.h" 28 29 class RKVarEditMetaModel; 30 class RCommandChain; 31 class RKEditor; 32 class RKRowNames; 33 34 /** Base class for RKVarEditModel and RKVarEditMetaModel. Defines a common interface for copy and paste operations. Models might reimplement these functions for more efficiency. 35 @author Thomas Friedrichsmeier */ 36 class RKVarEditModelBase : public QAbstractTableModel { 37 public: RKVarEditModelBase(QObject * parent)38 explicit RKVarEditModelBase (QObject *parent) : QAbstractTableModel (parent) {}; ~RKVarEditModelBase()39 virtual ~RKVarEditModelBase () {}; 40 41 virtual RKTextMatrix getTextMatrix (const QItemSelectionRange& range) const = 0; 42 virtual void blankRange (const QItemSelectionRange& range) = 0; 43 virtual void setTextMatrix (const QModelIndex& offset, const RKTextMatrix& text, const QItemSelectionRange& confine_to = QItemSelectionRange ()) = 0; 44 45 virtual int trueRows () const = 0; 46 virtual int trueCols () const = 0; firstRealColumn()47 int firstRealColumn () const { return var_col_offset; }; 48 49 int var_col_offset; 50 }; 51 52 /** This class represents a collection of RKVariables of uniform length (typically a data.frame) suitable for editing in a model/view editor such as QTableView. Probably it will only ever support editing a single RKVariable, though, as it is not possible to ensure uniform length outside of a data.frame. For a data.frame use RKVarEditDataFrameModel . Since the real data storage is in RKVariable, it is ok (and recommended) to create separate models for separate editors/viewers, even if the objects in question are the same. */ 53 class RKVarEditModel : public RKVarEditModelBase, public RObjectListener { 54 Q_OBJECT 55 public: 56 explicit RKVarEditModel (QObject *parent); 57 ~RKVarEditModel (); 58 59 /** set the editor that is using this model. This is useful to find out, e.g. which window should be raised, when calling "Edit" on an object represented in this data-model. Also, the editor will be notified, if all objects in the model have been removed. */ setEditor(RKEditor * editor)60 void setEditor (RKEditor* editor) { myeditor = editor; }; 61 /** see setEditor () */ getEditor()62 RKEditor* getEditor () const { return myeditor; }; 63 64 /** Add an object to the model at the given index. Calls this only once, unless from an RKVarEditDataFrameModel. You should add at least one object, **before** you add this model to any view. 65 @param index position to insert at, or -1 to append the item 66 @param object the objects to insert */ 67 void addObject (int index, RKVariable* object); 68 /** Return a pointer to the meta model. The meta model is created the first time this function is called. */ 69 RKVarEditMetaModel* getMetaModel (); 70 71 // QAbstractTableModel implementations 72 bool insertRows (int row, int count, const QModelIndex& parent = QModelIndex()) override; 73 bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex()) override; 74 int rowCount (const QModelIndex& parent = QModelIndex()) const override; 75 int columnCount (const QModelIndex& parent = QModelIndex()) const override; 76 QVariant data (const QModelIndex& index, int role = Qt::DisplayRole) const override; 77 Qt::ItemFlags flags (const QModelIndex& index) const override; 78 bool setData (const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override; 79 QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; 80 81 RKTextMatrix getTextMatrix (const QItemSelectionRange& range) const override; 82 void blankRange (const QItemSelectionRange& range) override; 83 void setTextMatrix (const QModelIndex& offset, const RKTextMatrix& text, const QItemSelectionRange& confine_to = QItemSelectionRange ()) override; 84 trueCols()85 int trueCols () const override { return objects.size (); }; trueRows()86 int trueRows () const override { return (objects.isEmpty () ? 0 : objects[0]->getLength ()); }; lockHeader(bool lock)87 void lockHeader (bool lock) { header_locked = lock; }; 88 89 virtual void restoreObject (RObject* object, RCommandChain* chain); 90 91 void objectMetaChanged (RObject* changed) override; 92 void objectDataChanged (RObject* object, const RObject::ChangeSet *changes) override; 93 94 RKVariable* getObject (int index) const; 95 signals: 96 void modelDepleted (); 97 void hasDuplicates (const QStringList& dupes); 98 private slots: 99 void checkDuplicatesNow (); 100 void doResetNow (); 101 private: 102 bool reset_scheduled; 103 void scheduleReset (); 104 protected: 105 friend class RKVarEditMetaModel; 106 QList<RKVariable*> objects; 107 RKRowNames *rownames; 108 109 /** very simple convenience function to return the number of true cols + trailing cols */ apparentCols()110 int apparentCols () const { return (trueCols () + trailing_cols); }; 111 /** very simple convenience function to return the number of true rows + trailing rows */ apparentRows()112 int apparentRows () const { return (trueRows () + trailing_rows); }; 113 114 /** Receives notifications of object removals. Takes care of removing the object from the list. */ 115 void objectRemoved (RObject* object) override; 116 117 /** insert new columns at index. Default implementation does nothing. To be implemented in subclasses */ 118 virtual void doInsertColumns (int index, int count); 119 120 virtual void doInsertRowsInBackend (int row, int count); 121 virtual void doRemoveRowsInBackend (int row, int count); 122 123 /** Check whether there are any duplicate names in the model. Actual check is delayed until the next iteration of the event loop. If a duplicate is found, hasDuplicates(const QStringList&) is emitted. */ 124 void checkDuplicates (); 125 bool duplicate_check_triggered; 126 127 int trailing_rows; 128 int trailing_cols; 129 130 int edit_blocks; 131 bool header_locked; 132 133 RKVarEditMetaModel* meta_model; 134 RKEditor* myeditor; 135 }; 136 137 /** Represents the meta information portion belonging to an RKVarEditModel. Implemented in a separate class for technical reasons, only (so this info can be displayed in a separate QTableView). This model mostly acts as a slave of an RKVarEditModel. You will not need to call any functions directly except from the RKVarEditModel, or an item view. */ 138 class RKVarEditMetaModel : public RKVarEditModelBase { 139 Q_OBJECT 140 public: 141 enum Rows { 142 NameRow=0, 143 LabelRow, 144 TypeRow, 145 FormatRow, 146 LevelsRow, 147 RowCount = LevelsRow + 1 148 }; 149 150 // QAbstractTableModel implementations 151 int rowCount (const QModelIndex& parent = QModelIndex()) const override; 152 int columnCount (const QModelIndex& parent = QModelIndex()) const override; 153 QVariant data (const QModelIndex& index, int role = Qt::DisplayRole) const override; 154 Qt::ItemFlags flags (const QModelIndex& index) const override; 155 bool setData (const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override; 156 QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; 157 158 RKTextMatrix getTextMatrix (const QItemSelectionRange& range) const override; 159 void blankRange (const QItemSelectionRange& range) override; 160 void setTextMatrix (const QModelIndex& offset, const RKTextMatrix& text, const QItemSelectionRange& confine_to = QItemSelectionRange ()) override; 161 trueCols()162 int trueCols () const override { return data_model->trueCols (); }; trueRows()163 int trueRows () const override { return RowCount; }; 164 165 RObject::ValueLabels getValueLabels (int column) const; 166 void setValueLabels (int column, const RObject::ValueLabels& labels); 167 getObject(int index)168 RKVariable* getObject (int index) const { return data_model->getObject (index); }; getDataModel()169 RKVarEditModel* getDataModel () const { return data_model; }; 170 protected: 171 friend class RKVarEditModel; 172 RKVarEditMetaModel (RKVarEditModel* data_model); 173 ~RKVarEditMetaModel (); 174 175 void beginAddDataObject (int index); 176 void endAddDataObject (); 177 void beginRemoveDataObject (int index); 178 void endRemoveDataObject (); 179 void objectMetaChanged (int atcolumn); 180 181 RKVarEditModel* data_model; 182 }; 183 184 185 class RKVarEditDataFrameModel : public RKVarEditModel { 186 Q_OBJECT 187 public: 188 RKVarEditDataFrameModel (RContainerObject* dataframe, QObject* parent); 189 /** ctor that constructs a new empty data frame */ 190 RKVarEditDataFrameModel (const QString& validized_name, RContainerObject* parent_object, RCommandChain* chain, int initial_cols, QObject* parent); 191 ~RKVarEditDataFrameModel (); 192 193 bool insertColumns (int column, int count, const QModelIndex& parent = QModelIndex()) override; 194 bool removeColumns (int column, int count, const QModelIndex& parent = QModelIndex()) override; 195 getObject()196 RContainerObject* getObject () const { return dataframe; }; 197 198 void restoreObject (RObject* object, RCommandChain* chain) override; 199 signals: 200 void modelObjectDestroyed (); 201 protected: 202 void doInsertColumns (int index, int count) override; 203 /** reimplemented from RKVarEditModel to listen for the dataframe object as well */ 204 void objectRemoved (RObject* object) override; 205 /** receives notifications of new objects added to this data.frame */ 206 void childAdded (int index, RObject* parent) override; 207 /** receives notifications of object position changes inside this data.frame */ 208 void childMoved (int old_index, int new_index, RObject* parent) override; 209 210 void doInsertRowsInBackend (int row, int count) override; 211 void doRemoveRowsInBackend (int row, int count) override; 212 213 RContainerObject* dataframe; 214 215 void init (RContainerObject* dataframe); 216 void pushTable (RCommandChain* sync_chain); 217 }; 218 219 #endif 220