File indexing completed on 2024-10-13 04:14:11
0001 /* This file is part of the KDE project 0002 Copyright (C) 2002 Lucijan Busch <lucijan@gmx.at> 0003 Copyright (C) 2003 Daniel Molkentin <molkentin@kde.org> 0004 Copyright (C) 2003-2016 Jarosław Staniek <staniek@kde.org> 0005 Copyright (C) 2014 Michał Poteralski <michalpoteralskikde@gmail.com> 0006 0007 This program is free software; you can redistribute it and/or 0008 modify it under the terms of the GNU Library General Public 0009 License as published by the Free Software Foundation; either 0010 version 2 of the License, or (at your option) any later version. 0011 0012 This program is distributed in the hope that it will be useful, 0013 but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 Library General Public License for more details. 0016 0017 You should have received a copy of the GNU Library General Public License 0018 along with this program; see the file COPYING. If not, write to 0019 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0020 * Boston, MA 02110-1301, USA. 0021 0022 Original Author: Till Busch <till@bux.at> 0023 Original Project: buX (www.bux.at) 0024 */ 0025 0026 #ifndef KDB_TABLEVIEWDATA_H 0027 #define KDB_TABLEVIEWDATA_H 0028 0029 #include "KDbField.h" 0030 #include "KDbUtils.h" 0031 #include "KDbRecordData.h" 0032 #include "KDbOrderByColumn.h" 0033 0034 class KDbCursor; 0035 class KDbRecordEditBuffer; 0036 class KDbResultInfo; 0037 class KDbTableViewColumn; 0038 0039 typedef KDbUtils::AutodeletedList<KDbRecordData*> KDbTableViewDataBase; 0040 typedef KDbTableViewDataBase::ConstIterator KDbTableViewDataConstIterator; 0041 typedef KDbTableViewDataBase::Iterator KDbTableViewDataIterator; 0042 0043 //! A list of records to allow configurable sorting and more. 0044 /*! @todo improve API */ 0045 class KDB_EXPORT KDbTableViewData : public QObject, protected KDbTableViewDataBase 0046 { 0047 Q_OBJECT 0048 public: 0049 //! Non-db-aware version 0050 KDbTableViewData(); 0051 0052 //! Db-aware version. The cursor is not owned by the data. 0053 explicit KDbTableViewData(KDbCursor *c); 0054 0055 /*! Defines two-column table usually used with comboboxes. 0056 First column is invisible and contains key values. 0057 Second column and contains user-visible value. 0058 @param keys a list of keys 0059 @param values a list of text values (must be of the same length as keys list) 0060 @param keyType a type for keys 0061 @param valueType a type for values 0062 0063 @todo make this more generic: allow to add more columns! */ 0064 KDbTableViewData( 0065 const QList<QVariant> &keys, const QList<QVariant> &values, 0066 KDbField::Type keyType = KDbField::Text, KDbField::Type valueType = KDbField::Text); 0067 0068 /*! Like above constructor, but keys and values are not provided. 0069 You can do this later by calling append(KDbRecordData*) method. 0070 (KDbRecordData object must have exactly two columns) */ 0071 KDbTableViewData(KDbField::Type keyType, KDbField::Type valueType); 0072 0073 ~KDbTableViewData() override; 0074 0075 /*! Preloads all records provided by cursor (only for db-aware version). */ 0076 bool preloadAllRecords(); 0077 0078 /*! Sets sorting for @a column. If @a column is -1, sorting is disabled. */ 0079 void setSorting(int column, KDbOrderByColumn::SortOrder order = KDbOrderByColumn::SortOrder::Ascending); 0080 0081 /*! @return the column number by which the data is sorted, 0082 or -1 if sorting is disabled. 0083 Initial sorted column number for data after instantiating object is -1. */ 0084 int sortColumn() const; 0085 0086 /*! @return sorting order. This is independent of whether the data is actually sorted. 0087 sortColumn() should be checked first to see if sorting for any column is enabled 0088 (by default it is not). */ 0089 KDbOrderByColumn::SortOrder sortOrder() const; 0090 0091 //! Sorts this data using previously set order. 0092 void sort(); 0093 0094 /*! Adds column @a col. 0095 Warning: @a col will be owned by this object, and deleted on its destruction. */ 0096 void addColumn(KDbTableViewColumn* col); 0097 0098 //! @return Index of visible column @a visibleIndex on global list. 0099 int globalIndexOfVisibleColumn(int visibleIndex) const; 0100 0101 //! @return Index on list of visible columns for column @a globalIndex 0102 //! or -1 if column at @a globalIndex is not visible. 0103 int visibleColumnIndex(int globalIndex) const; 0104 0105 /*! @return true if this db-aware data set. */ 0106 /*! @todo virtual? */ 0107 bool isDBAware() const; 0108 0109 /*! For db-aware data set only: table name is returned; 0110 equivalent to cursor()->query()->parentTable()->name(). */ 0111 QString dbTableName() const; 0112 0113 KDbCursor* cursor() const; 0114 0115 int columnCount() const; 0116 0117 //! @return number of visible columns 0118 int visibleColumnCount() const; 0119 0120 //! @return column at index @a index (visible or not) 0121 KDbTableViewColumn* column(int c); 0122 0123 //! @return visible column at index @a index 0124 KDbTableViewColumn* visibleColumn(int index); 0125 0126 //! @return list of all columns 0127 QList<KDbTableViewColumn*>* columns(); 0128 0129 //! @return list of visible columns 0130 QList<KDbTableViewColumn*>* visibleColumns(); 0131 0132 /*! @return true if data is not editable. Can be set using setReadOnly() 0133 but it's still true if database cursor returned by cursor() 0134 is not 0 and has read-only connection. */ 0135 virtual bool isReadOnly() const; 0136 0137 /*! Sets readOnly flag for this data. 0138 If @a set is true, insertingEnabled flag will be cleared automatically. 0139 @see isInsertingEnabled() */ 0140 virtual void setReadOnly(bool set); 0141 0142 /*! @return true if data inserting is enabled (the default). */ 0143 virtual bool isInsertingEnabled() const; 0144 0145 /*! Sets insertingEnabled flag. If true, empty record is available 0146 If @a set is true, read-only flag will be cleared automatically. 0147 @see setReadOnly() */ 0148 virtual void setInsertingEnabled(bool set); 0149 0150 /*! Clears and initializes internal record edit buffer for incoming editing. 0151 Creates buffer using recordEditBuffer(false) (false means not db-aware type) 0152 if our data is not db-aware, 0153 or db-aware buffer if data is db-aware (isDBAware()==true). 0154 @see KDbRecordEditBuffer */ 0155 void clearRecordEditBuffer(); 0156 0157 /*! Updates internal record edit buffer: currently edited column @a col (number @a colnum) 0158 has now assigned new value of @a newval. 0159 Uses column's caption to address the column in buffer 0160 if the buffer is of simple type, or db-aware buffer if (isDBAware()==true). 0161 (then fields are addressed with KDbField, instead of caption strings). 0162 If @a allowSignals is true (the default), aboutToChangeCell() signal is emitted. 0163 @a visibleValueForLookupField allows to pass visible value (usually a text) 0164 for a lookup field (only reasonable if col->visibleLookupColumnInfo != 0). 0165 Note that @a newval may be changed in aboutToChangeCell() signal handler. 0166 If either @a record or @a col or @a newval is @c nullptr, @c false is returned. 0167 @see KDbRecordEditBuffer */ 0168 bool updateRecordEditBufferRef(KDbRecordData *record, 0169 int colnum, KDbTableViewColumn* col, QVariant* newval, 0170 bool allowSignals = true, 0171 QVariant *visibleValueForLookupField = nullptr); 0172 0173 /*! Added for convenience. Like above but @a newval is passed by value. */ 0174 bool updateRecordEditBuffer(KDbRecordData *record, int colnum, KDbTableViewColumn* col, 0175 const QVariant &newval, bool allowSignals = true); 0176 0177 /*! Added for convenience. Like above but it's assumed that @a record record's columns 0178 are ordered like in table view, not like in form view. Don't use this with form views. */ 0179 bool updateRecordEditBuffer(KDbRecordData *record, int colnum, 0180 const QVariant &newval, bool allowSignals = true); 0181 0182 //! @return record edit buffer for currently edited record. Can be 0 or empty. 0183 KDbRecordEditBuffer* recordEditBuffer() const; 0184 0185 /*! @return last operation's result information (always not null). */ 0186 const KDbResultInfo& result() const; 0187 0188 bool saveRecordChanges(KDbRecordData *record, bool repaint = false); 0189 0190 bool saveNewRecord(KDbRecordData *record, bool repaint = false); 0191 0192 bool deleteRecord(KDbRecordData *record, bool repaint = false); 0193 0194 /*! Deletes records (by number) passed with @a recordsToDelete. 0195 Currently, this method is only for non data-aware tables. */ 0196 void deleteRecords(const QList<int> &recordsToDelete, bool repaint = false); 0197 0198 /*! Deletes all records. Works either for db-aware and non db-aware tables. 0199 Column's definition is not changed. 0200 For db-aware version, all records are removed from a database. 0201 Record-edit buffer is cleared. 0202 0203 If @a repaint is true, reloadRequested() signal 0204 is emitted after deleting (if at least one record was deleted), 0205 so presenters can repaint their contents. 0206 0207 @return true on success. */ 0208 virtual bool deleteAllRecords(bool repaint = false); 0209 0210 /*! @internal method, used mostly by specialized classes like KexiTableView. 0211 Clears internal record structures. Record-edit buffer is cleared. 0212 Does not touch data @ database backend. 0213 Use deleteAllRecords() to safely delete all records. */ 0214 virtual void clearInternal(bool processEvents = true); 0215 0216 /*! Inserts new @a record at index @a index. 0217 @a record will be owned by this data object. 0218 Note: Reasonable only for not not-db-aware version. */ 0219 void insertRecord(KDbRecordData *record, int index, bool repaint = false); 0220 0221 //! @todo add this as well? void insertRecord(KDbRecordData *record, KDbRecordData *aboveRecord) 0222 0223 //! @return index of autoincremented column. The result is cached. 0224 //! @todo what about multiple autoinc columns? 0225 //! @todo what about changing column order? 0226 int autoIncrementedColumn() const; 0227 0228 //! Emits reloadRequested() signal to reload presenters. 0229 void reload() { 0230 emit reloadRequested(); 0231 } 0232 0233 inline KDbRecordData* at(int index) { 0234 return KDbTableViewDataBase::at(index); 0235 } 0236 inline virtual int count() const { 0237 return KDbTableViewDataBase::count(); 0238 } 0239 inline bool isEmpty() const { 0240 return KDbTableViewDataBase::isEmpty(); 0241 } 0242 inline KDbRecordData* first() { 0243 return KDbTableViewDataBase::first(); 0244 } 0245 inline KDbRecordData* last() { 0246 return KDbTableViewDataBase::last(); 0247 } 0248 inline int indexOf(const KDbRecordData* record, int from = 0) const { 0249 return KDbTableViewDataBase::indexOf(const_cast<KDbRecordData*>(record), from); 0250 } 0251 inline void removeFirst() { 0252 KDbTableViewDataBase::removeFirst(); 0253 } 0254 inline void removeLast() { 0255 KDbTableViewDataBase::removeLast(); 0256 } 0257 inline void append(KDbRecordData* record) { 0258 KDbTableViewDataBase::append(record); 0259 } 0260 inline void prepend(KDbRecordData* record) { 0261 KDbTableViewDataBase::prepend(record); 0262 } 0263 inline KDbTableViewDataConstIterator constBegin() const { 0264 return KDbTableViewDataBase::constBegin(); 0265 } 0266 inline KDbTableViewDataConstIterator constEnd() const { 0267 return KDbTableViewDataBase::constEnd(); 0268 } 0269 inline KDbTableViewDataIterator begin() { 0270 return KDbTableViewDataBase::begin(); 0271 } 0272 inline KDbTableViewDataIterator end() { 0273 return KDbTableViewDataBase::end(); 0274 } 0275 0276 /*! @return true if ROWID information is stored within every record. 0277 Only reasonable for db-aware version. ROWID information is available 0278 if KDbDriverBehavior::ROW_ID_FIELD_RETURNS_LAST_AUTOINCREMENTED_VALUE == false 0279 for a KDb database driver and a table has no primary key defined. 0280 Phisically, ROWID information is stored after last KDbRecordData's element, 0281 so every KDbRecordData's length is expanded by one. */ 0282 bool containsRecordIdInfo() const; 0283 0284 //! Creates a single record data with proper number of columns. 0285 KDbRecordData* createItem() const; 0286 0287 //! @return reusable i18n'd message 0288 //! "Please correct data in this record or use the \"Cancel record changes\" function." 0289 static QString messageYouCanImproveData(); 0290 0291 public Q_SLOTS: 0292 //! @internal Clean up. 0293 void deleteLater(); 0294 0295 Q_SIGNALS: 0296 void destroying(); 0297 0298 /*! Emitted before change of the single, currently edited cell. 0299 Connect this signal to your slot and set @a result->success to false 0300 to disallow this change. You can also change @a newValue to other value, 0301 or change other columns in @a record. */ 0302 void aboutToChangeCell(KDbRecordData *record, int colnum, QVariant* newValue, 0303 KDbResultInfo* result); 0304 0305 /*! Emitted before inserting of a new, current record. 0306 Connect this signal to your slot and set @a result->success to false 0307 to disallow this inserting. You can also change columns in @a record. */ 0308 void aboutToInsertRecord(KDbRecordData *record, KDbResultInfo* result, bool repaint); 0309 0310 /*! Emitted before changing of an edited, current record. 0311 Connect this signal to your slot and set @a result->success to false 0312 to disallow this change. You can also change columns in @a record. */ 0313 void aboutToUpdateRecord(KDbRecordData *record, KDbRecordEditBuffer* buffer, 0314 KDbResultInfo* result); 0315 0316 void recordUpdated(KDbRecordData*); //!< Current record has been updated 0317 0318 void recordInserted(KDbRecordData*, bool repaint); //!< A record has been inserted 0319 0320 //! A record has been inserted at @a index position (not db-aware data only) 0321 void recordInserted(KDbRecordData*, int index, bool repaint); 0322 0323 /*! Emitted before deleting of a current record. 0324 Connect this signal to your slot and set @a result->success to false 0325 to disallow this deleting. */ 0326 void aboutToDeleteRecord(KDbRecordData *record, KDbResultInfo* result, bool repaint); 0327 0328 //! Current record has been deleted 0329 void recordDeleted(); 0330 0331 //! Records have been deleted 0332 void recordsDeleted(const QList<int> &recordsToDelete); 0333 0334 //! Displayed data needs to be reloaded in all presenters. 0335 void reloadRequested(); 0336 0337 void recordRepaintRequested(KDbRecordData*); 0338 0339 protected: 0340 //! Used by KDbTableViewColumn::setVisible() 0341 void columnVisibilityChanged(const KDbTableViewColumn &column); 0342 0343 private: 0344 //! @internal for saveRecordChanges() and saveNewRecord() 0345 bool saveRecord(KDbRecordData *record, bool insert, bool repaint); 0346 0347 friend class KDbTableViewColumn; 0348 0349 Q_DISABLE_COPY(KDbTableViewData) 0350 class Private; 0351 Private * const d; 0352 }; 0353 0354 //! Sends information about data @a data to debug output @a dbg. 0355 //! @since 3.1 0356 KDB_EXPORT QDebug operator<<(QDebug dbg, const KDbTableViewData &data); 0357 0358 #endif