Coverage Report

Created: 2026-09-28 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wt/src/Wt/WAbstractItemModel.h
Line
Count
Source
1
// This may look like C code, but it's really -*- C++ -*-
2
/*
3
 * Copyright (C) 2008 Emweb bv, Herent, Belgium.
4
 *
5
 * See the LICENSE file for terms of use.
6
 */
7
#ifndef WABSTRACT_ITEM_MODEL_H_
8
#define WABSTRACT_ITEM_MODEL_H_
9
10
#include <Wt/WObject.h>
11
#include <Wt/WModelIndex.h>
12
#include <Wt/WSignal.h>
13
#include <Wt/WGlobal.h>
14
#include <Wt/WAny.h>
15
16
namespace Wt {
17
18
  class WDropEvent;
19
20
/*! \class WAbstractItemModel Wt/WAbstractItemModel.h Wt/WAbstractItemModel.h
21
 *  \brief An abstract model for use with %Wt's view classes.
22
 *
23
 * This abstract model is used by several %Wt view widgets as data models.
24
 *
25
 * It may model data for both tree-like and table-like view
26
 * widgets. Data is therefore organized in a hierarchical structure of
27
 * tables, where every item stores data and items in column 0 can be
28
 * the parent of a nested table of data. Every data item is uniquely
29
 * identified by their row, column and parent index, and items may be
30
 * referenced using the helper class WModelIndex.
31
 *
32
 * Each item may provide data for one or more \link Wt::ItemDataRole
33
 * roles\endlink, and indicate options using \link Wt::ItemFlag
34
 * flags\endlink. The different roles can be used to model different
35
 * aspects of an item (its text value, an icon, style class), or to
36
 * hold auxiliary custom information. The flags provide information to
37
 * the View on possible interactivity.
38
 *
39
 * \if cpp
40
 * Side::Top level data have an \link WModelIndex::isValid() invalid\endlink
41
 * parent WModelIndex.
42
 * \endif
43
 * \if java
44
 * Side::Top level data have a \c null parent WModelIndex.
45
 * \endif
46
 *
47
 * \if cpp
48
 * The data itself is of type <b>Wt::any</b>, which can either be
49
 * empty, or hold any type of data. Depending on the role however,
50
 * view classes may expect certain types of data (e.g. a string for
51
 * Wt::ItemDataRole::StyleClass).
52
 *
53
 * Wt's standard view classes can display (Wt::ItemDataRole::Display)
54
 * the following data:
55
 *
56
 *  - strings of type WString or std::string
57
 *  - WDate, WTime, WDateTime, WLocalDateTime
58
 *  - standard C++ numeric types (int, double, etc...)
59
 *  - bool
60
 *
61
 * The view classes know how to interpret data of these types \link
62
 * Wt::asString() as a string\endlink or \link Wt::asNumber() as a
63
 * number\endlink.
64
 *
65
 * \elseif java
66
 *
67
 * The data itself is of type Object, which can either be \c null, or be
68
 * any type of data. Depending on the role however, view classes may
69
 * expect certain types of data (e.g. numerical types for charts) or
70
 * will convert the data to a string (e.g. for Wt::ItemDataRole::Display).
71
 *
72
 * \endif
73
 *
74
 * \if cpp
75
 * Conversion between native types and Wt::any is done like this:
76
 * <ul>
77
 *  <li>Conversion from <i>v</i> (of type <i>Type</i>) to Wt::any <i>a</i>
78
 *   (for setData() and setHeaderData())
79
 *    <pre>
80
 * Wt::any <i>a</i> = Wt::any(<i>v</i>);
81
 *    </pre>
82
 *   For example:
83
 *    <pre>
84
 * WDate d(1976,6,14);
85
 * model->setData(row, column, Wt::any(d));
86
 *    </pre>
87
 *
88
 *  </li>
89
 *  <li>Conversion from Wt::any <i>a</i> to <i>v</i> (of type <i>Type</i>)
90
     (for data() and headerData()):
91
 *    <pre>
92
 * <i>Type v</i> = Wt::any_cast<<i>Type</i>>(<i>a</i>);
93
 *    </pre>
94
 *   For example:
95
 *    <pre>
96
 * WDate d = Wt::any_cast<WDate>(model->data(row, column));
97
 *    </pre>
98
 *  </li>
99
 *  <li>Checking if a Wt::any <i>a</i> holds a value:</li>
100
 *    <pre>
101
 * if (!<i>a</i>.empty()) {
102
 *   ...
103
 * }
104
 *    </pre>
105
 *  </li>
106
 *  <li>Determining the value type of a Wt::any <i>a</i>, for example:</li>
107
 *    <pre>
108
 * if (<i>a</i>.type() == typeid(double)) {
109
 *   ...
110
 * }
111
 *    </pre>
112
 *  </li>
113
 * </ul>
114
 *
115
 * \endif
116
 *
117
 * To implement a custom model, you need to reimplement the following methods:
118
 *  - index() and parent() methods that allow one to navigate the model
119
 *  - columnCount() and rowCount() to specify the top level geometry and the
120
 *    nested geometry at every item
121
 *  - data() to return the data for an item
122
 *  - optionally, headerData() to return row and column header data
123
 *  - optionally, flags() to indicate data options
124
 *
125
 * \if cpp
126
 * A crucial point in implementing a hierarchical model is to decide
127
 * how to reference an index in terms of an internal pointer
128
 * (WModelIndex::internalPointer()) or internal id
129
 * (WModelIndex::internalId()). Other than the top-level index, which
130
 * is special since it is referenced using an \link
131
 * WModelIndex::isValid() invalid\endlink index, every index with
132
 * children must be identifiable using this number or pointer. For
133
 * example, in the WStandardItemModel, the internal pointer points to
134
 * the parent WStandardItem. For table models, the internal pointer
135
 * plays no role, since only the toplevel index has children.
136
 * \elseif java
137
 * A crucial point in implementing a hierarchical model is to decide
138
 * how to reference an index in terms of an internal pointer
139
 * (WModelIndex::internalPointer()).
140
 * Other than the top-level index, which is special since it is
141
 * referenced using an invalid index, every index with
142
 * children must be identifiable using this object. For
143
 * example, in the WStandardItemModel, the internal pointer points to
144
 * the parent WStandardItem. For table models, the internal pointer
145
 * plays no role, since only the toplevel index has children.
146
 * \endif
147
 *
148
 * If you want to support editing of the model, then you need to
149
 * indicate this support using a Wt::ItemFlag::Editable flag, and
150
 * reimplement setData(). View classes will use the
151
 * \link Wt::ItemDataRole::Edit ItemDataRole::Edit\endlink to read and update
152
 * the data for the editor.
153
 *
154
 * When the model's data has been changed, the model must emit the
155
 * dataChanged() signal.
156
 *
157
 * Finally, there is a generic interface for insertion of new data or
158
 * removal of data (changing the geometry), although this interface is
159
 * not yet used by any View class:
160
 *
161
 * - insertRows()
162
 * - insertColumns()
163
 * - removeRows()
164
 * - removeColumns()
165
 *
166
 * Alternatively, you can provide your own API for changing the
167
 * model. In either case it is important that you call the
168
 * corresponding protected member functions which will emit the
169
 * relevant signals so that views can adapt themselves to the new
170
 * geometry.
171
 *
172
 * \ingroup modelview
173
 */
174
class WT_API WAbstractItemModel : public WObject
175
{
176
public:
177
  /*! \brief Data map.
178
   *
179
   * A map of data, indexed by a role.
180
   */
181
#ifndef WT_TARGET_JAVA
182
  typedef std::map<ItemDataRole, cpp17::any> DataMap;
183
#else
184
  typedef std::treemap<ItemDataRole, cpp17::any> DataMap;
185
#endif
186
187
  /*! \brief Creates a new data model.
188
   */
189
  WAbstractItemModel();
190
191
  virtual ~WAbstractItemModel();
192
193
  /*! \brief Returns the number of columns.
194
   *
195
   * This returns the number of columns at index \p parent.
196
   *
197
   * \sa rowCount()
198
   */
199
  virtual int columnCount(const WModelIndex& parent = WModelIndex()) const = 0;
200
201
  /*! \brief Returns the number of rows.
202
   *
203
   * This returns the number of rows at index \p parent.
204
   *
205
   * \sa columnCount()
206
   */
207
  virtual int rowCount(const WModelIndex& parent = WModelIndex()) const = 0;
208
209
  // not yet used by views
210
  virtual bool canFetchMore(const WModelIndex& parent) const;
211
212
  // not yet used by views
213
  virtual void fetchMore(const WModelIndex& parent);
214
215
  /*! \brief Returns the flags for an item.
216
   *
217
   * The default implementation returns \link Wt::ItemFlag::Selectable
218
   * ItemFlag::Selectable\endlink.
219
   *
220
   * \sa Wt::ItemFlag
221
   */
222
  virtual WFlags<ItemFlag> flags(const WModelIndex& index) const;
223
224
  /*! \brief Returns the flags for a header.
225
   *
226
   * The default implementation returns no flags set.
227
   *
228
   * \sa Wt::HeaderFlag
229
   */
230
  virtual WFlags<HeaderFlag> headerFlags
231
    (int section, Orientation orientation = Orientation::Horizontal) const;
232
233
  /*! \brief Returns if there are children at an index.
234
   *
235
   * Returns \c true when rowCount(index) > 0 and columnCount(index) > 0.
236
   *
237
   * \sa rowCount(), columnCount()
238
   */
239
  virtual bool hasChildren(const WModelIndex& index) const;
240
241
  /*! \brief Returns the parent for a model index.
242
   *
243
   * An implementation should use createIndex() to create a model
244
   * index that corresponds to the parent of a given index.
245
   *
246
   * Note that the index itself may be stale (referencing a row/column
247
   * within the parent that is outside the model geometry), but its
248
   * parent (identified by the WModelIndex::internalPointer()) is
249
   * referencing an existing parent. A stale index can only be used
250
   * while the model geometry is being updated, i.e. during the
251
   * emission of the corresponding
252
   * [rows/columns](Being)[Removed/Inserted]() signals.
253
   *
254
   * \sa index()
255
   */
256
  virtual WModelIndex parent(const WModelIndex& index) const = 0;
257
258
  /*! \brief Returns data at a specified model index for the given role.
259
   *
260
   * You should check the \p role to decide what data to
261
   * return. Usually a View class will ask for data for several roles
262
   * which affect not only the contents
263
   * (Wt::ItemDataRole::Display) but also icons
264
   * (Wt::ItemDataRole::Decoration), URLs
265
   * (Wt::ItemDataRole::Link), and other visual aspects. If your
266
   * item does not specify data for a particular role, it should
267
   * simply return a Wt::cpp17::any().
268
   *
269
   * \sa flags(), headerData(), setData()
270
   */
271
  virtual cpp17::any data(const WModelIndex& index,
272
                       ItemDataRole role = ItemDataRole::Display)
273
    const = 0;
274
275
  /*! \brief Returns all data at a specific index.
276
   *
277
   * This is a convenience function that returns a map with data
278
   * corresponding to all standard roles.
279
   *
280
   * \sa data()
281
   */
282
  virtual DataMap itemData(const WModelIndex& index) const;
283
284
  /*! \brief Returns the row or column header data.
285
   *
286
   * When \p orientation is \link Wt::Orientation::Horizontal
287
   * Orientation::Horizontal\endlink, \p section is a column number, when
288
   * \p orientation is \link Wt::Orientation::Vertical Orientation::Vertical\endlink,
289
   * \p section is a row number.
290
   *
291
   * \sa data(), setHeaderData()
292
   */
293
  virtual cpp17::any headerData(int section,
294
                             Orientation orientation = Orientation::Horizontal,
295
                             ItemDataRole role = ItemDataRole::Display) const;
296
297
  /*! \brief Returns the child index for the given row and column.
298
   *
299
   * When implementing this method, you can use createIndex() to
300
   * create an index that corresponds to the item at \p row and
301
   * \p column within \p parent.
302
   *
303
   * If the location is invalid (out of bounds at the parent), then an
304
   * invalid index must be returned.
305
   *
306
   * \sa parent()
307
   */
308
  virtual WModelIndex index(int row, int column,
309
                            const WModelIndex& parent = WModelIndex())
310
    const = 0;
311
312
  /*! \brief Returns an index list for data items that match.
313
   *
314
   * Returns an index list of data items that match, starting at
315
   * start, and searching further in that column. If flags specifies
316
   * \link Wt::MatchFlag::Wrap MatchFlag::Wrap \endlink then the search wraps around
317
   * from the start. If hits is not -1, then at most that number of
318
   * hits are returned.
319
   */
320
  virtual WModelIndexList match(const WModelIndex& start,
321
                                ItemDataRole role,
322
                                const cpp17::any& value,
323
                                int hits = -1,
324
                                WFlags<MatchFlag> flags
325
                                = WFlags<MatchFlag>(MatchFlag::StartsWith
326
                                                    | MatchFlag::Wrap))
327
    const;
328
329
  /*! \brief Returns the data item at the given column and row.
330
   *
331
   * This is a convenience method, and is equivalent to:
332
   * \code
333
   * index(row, column, parent).data(role)
334
   * \endcode
335
   *
336
   * \sa index(), data()
337
   */
338
  cpp17::any data(int row, int column,
339
               ItemDataRole role = ItemDataRole::Display,
340
               const WModelIndex& parent = WModelIndex()) const;
341
342
  /*! \brief Returns if an index at the given position is valid
343
   *         (i.e. falls within the column-row bounds).
344
   *
345
   * Equivalent to:
346
   * \code
347
   * return row >= 0 && column >= 0
348
   *        && row < rowCount(parent) && column < columnCount(parent);
349
   * \endcode
350
   *
351
   * \sa rowCount(), columnCount()
352
   */
353
  virtual bool hasIndex(int row, int column,
354
                        const WModelIndex& parent = WModelIndex()) const;
355
356
  /*! \brief Inserts one or more columns.
357
   *
358
   * In models that support column insertion, this inserts \c count
359
   * columns, starting at \c column, and returns \c true if the
360
   * operation was successful. The new columns are inserted under \p
361
   * parent.
362
   *
363
   * The default implementation returns \c false.
364
   *
365
   * The model implementation must call beginInsertColumns() and
366
   * endInsertColumns() before and after the operation whenever its
367
   * geometry is changed by inserting columns. This emits signals for
368
   * views to properly react to these changes.
369
   *
370
   * \sa insertRows(), removeColumns(), beginInsertColumns(), endInsertColumns()
371
   */
372
  virtual bool insertColumns(int column, int count,
373
                             const WModelIndex& parent = WModelIndex());
374
375
  /*! \brief Inserts one or more rows.
376
   *
377
   * In models that support row insertion, this inserts \c count rows,
378
   * starting at \c row, and returns \c true if the operation was
379
   * successful. The new rows are inserted under \p parent.
380
   *
381
   * If parent had no children, then a single column is added with \c
382
   * count rows.
383
   *
384
   * The default implementation returns \c false.
385
   *
386
   * The model implementation must call beginInsertRows() and
387
   * endInsertRows() before and after the operation whenever its
388
   * geometry is changed by inserting rows. This emits signals for
389
   * views to properly react to these changes.
390
   *
391
   * \sa insertColumns(), removeRows(), beginInsertRows(), endInsertRows()
392
   */
393
  virtual bool insertRows(int row, int count,
394
                          const WModelIndex& parent = WModelIndex());
395
396
  /*! \brief Removes columns.
397
   *
398
   * Returns \c true if the operation was successful.
399
   *
400
   * The default implementation returns \c false.
401
   *
402
   * The model implementation must call beginRemoveColumns() and
403
   * endRemoveColumns() before and after the operation whenever its
404
   * geometry is changed by removing columns. This emits signals for
405
   * views to properly react to these changes.
406
   *
407
   * \sa removeRows(), insertColumns(), beginRemoveColumns(), endRemoveColumns()
408
   */
409
  virtual bool removeColumns(int column, int count,
410
                             const WModelIndex& parent = WModelIndex());
411
412
  /*! \brief Removes rows.
413
   *
414
   * Returns \c true if the operation was successful.
415
   *
416
   * The default implementation returns \c false.
417
   *
418
   * The model implementation must call beginRemoveRows() and
419
   * endRemoveRows() before and after the operation whenever its
420
   * geometry is changed by removing rows. This emits signals for
421
   * views to properly react to these changes.
422
   *
423
   * \sa removeColumns(), insertRows(), beginRemoveRows(), endRemoveRows()
424
   */
425
  virtual bool removeRows(int row, int count,
426
                          const WModelIndex& parent = WModelIndex());
427
428
  /*! \brief Sets data at the given model index.
429
   *
430
   * Returns \c true if the operation was successful.
431
   *
432
   * The default implementation returns \c false.
433
   *
434
   * The model implementation must emit the dataChanged() signal after
435
   * data was changed.
436
   *
437
   * \sa data()
438
   */
439
  virtual bool setData(const WModelIndex& index, const cpp17::any& value,
440
                       ItemDataRole role = ItemDataRole::Edit);
441
442
  /*! \brief Sets data at the given model index.
443
   *
444
   * This is a convenience function that sets data for all roles at once.
445
   *
446
   * \sa setData()
447
   */
448
  virtual bool setItemData(const WModelIndex& index, const DataMap& values);
449
450
  /*! \brief Sets header data for a column or row.
451
   *
452
   * Returns \c true if the operation was successful.
453
   *
454
   * \sa headerData()
455
   */
456
  virtual bool setHeaderData(int section, Orientation orientation,
457
                             const cpp17::any& value,
458
                             ItemDataRole role = ItemDataRole::Edit);
459
460
  /*! \brief Sets column header data.
461
   *
462
   * Returns \c true if the operation was successful.
463
   *
464
   * \sa setHeaderData(int, Orientation, const cpp17::any&, int)
465
   */
466
  bool setHeaderData(int section, const cpp17::any& value);
467
468
  /*! \brief Sorts the model according to a particular column.
469
   *
470
   * If the model supports sorting, then it should emit the
471
   * layoutAboutToBeChanged() signal, rearrange its items, and
472
   * afterwards emit the layoutChanged() signal.
473
   *
474
   * \sa layoutAboutToBeChanged(), layoutChanged()
475
   */
476
  virtual void sort(int column, SortOrder order = SortOrder::Ascending);
477
478
  /*! \brief Expands a column.
479
   *
480
   * Expands a column. This may only be called by a view when the
481
   * Wt::HeaderFlag::ColumnIsCollapsed flag is set.
482
   *
483
   * The default implementation does nothing.
484
   *
485
   * \sa WAggregateProxyModel
486
   */
487
  virtual void expandColumn(int column);
488
489
  /*! \brief Collapses a column.
490
   *
491
   * Collapses a column. This may only be called by a view when the
492
   * Wt::HeaderFlag::ColumnIsExpandedLeft or Wt::HeaderFlag::ColumnIsExpandedRight flag is set.
493
   *
494
   * The default implementation does nothing.
495
   *
496
   * \sa WAggregateProxyModel
497
   */
498
  virtual void collapseColumn(int column);
499
500
  /*! \brief Converts a model index to a raw pointer that remains valid
501
   *         while the model's layout is changed.
502
   *
503
   * Use this method to temporarily save model indexes while the model's
504
   * layout is changed by for example a sorting operation.
505
   *
506
   * The default implementation returns \c 0, which indicates that the
507
   * index cannot be converted to a raw pointer. If you reimplement
508
   * this method, you also need to reimplemnt fromRawIndex().
509
   *
510
   * \sa layoutAboutToBeChanged, sort(), fromRawIndex()
511
   */
512
  virtual void *toRawIndex(const WModelIndex& index) const;
513
514
  /*! \brief Converts a raw pointer to a model index.
515
   *
516
   * Use this method to create model index from temporary raw
517
   * pointers. It is the reciproce method of toRawIndex().
518
   *
519
   * You can return an invalid modelindex if the rawIndex no longer points
520
   * to a valid item because of the layout change.
521
   *
522
   * \sa toRawIndex()
523
   */
524
  virtual WModelIndex fromRawIndex(void *rawIndex) const;
525
526
  /*! \brief Returns a mime-type for dragging a set of indexes.
527
   *
528
   * This method returns a mime-type that describes dragging of a selection
529
   * of items.
530
   *
531
   * The drop event will indicate a \link WItemSelectionModel
532
   * selection model\endlink for this abstract item model as \link
533
   * WDropEvent::source() source\endlink.
534
   *
535
   * The default implementation returns a mime-type for generic
536
   * drag&drop support between abstract item models.
537
   *
538
   * \sa acceptDropMimeTypes()
539
   */
540
  virtual std::string mimeType() const;
541
542
  /*! \brief Returns a list of mime-types that could be accepted for a
543
   *         drop event.
544
   *
545
   * The default implementation only accepts drag&drop support between
546
   * abstract item models.
547
   *
548
   * \sa mimeType()
549
   */
550
  virtual std::vector<std::string> acceptDropMimeTypes() const;
551
552
  /*! \brief Handles a drop event.
553
   *
554
   * The default implementation only handles generic drag&drop between
555
   * abstract item models. Source item data is copied (but not the
556
   * source item's flags).
557
   *
558
   * This method is overloaded for handling drop events on top of items
559
   * or drop events between items (see Wt::DropLocation). This overload
560
   * handles drops on top of items, but note that due to historical
561
   * reasons it will also insert the items in between when called with
562
   * DropAction::Move.
563
   *
564
   * The location in the model is indicated by the \p row and
565
   * \p column within the \p parent index. If \p row is
566
   * -1, then the item is appended to the \p parent. Otherwise,
567
   * the item is inserted at or copied over the indicated item (and
568
   * subsequent rows). When \p action is a \link Wt::DropAction::Move
569
   * DropAction::Move\endlink, the original items are deleted from the
570
   * source model.
571
   *
572
   * You may want to reimplement this method if you want to handle
573
   * other mime-type data, or if you want to refine how the drop event
574
   * of an item selection must be interpreted.
575
   *
576
   * \note Currently, only row selections are handled by the default
577
   *       implementation.
578
   *
579
   * \sa mimeType(), WItemSelectionModel
580
   */
581
  virtual void dropEvent(const WDropEvent& e, DropAction action,
582
                         int row, int column, const WModelIndex& parent);
583
584
  /*! \brief Handles a drop event.
585
   *
586
   * The default implementation only handles generic drag&drop between
587
   * abstract item models. Source item data is copied (but not the
588
   * source item's flags).
589
   *
590
   * This method is overloaded for handling drop events on top of items
591
   * or drop events between items. This overload handles drops between
592
   * items. The drop was received relative to the \p index item and the \p side
593
   * parameter will only be Wt::Top or Wt::Bottom.
594
   *
595
   * You may want to reimplement this method if you want to handle
596
   * other mime-type data, or if you want to refine how the drop event
597
   * of an item selection must be interpreted.
598
   *
599
   * \note Currently, only row selections are handled by the default
600
   *       implementation.
601
   *
602
   * \sa mimeType(), WItemSelectionModel
603
   */
604
  virtual void dropEvent(const WDropEvent& e, DropAction action,
605
                         const WModelIndex& index, Wt::Side side);
606
607
  /*! \brief Inserts one column.
608
   *
609
   * This is a convenience method that adds a single column, and is
610
   * equivalent to:
611
   * \code
612
   * insertColumns(column, 1, parent);
613
   * \endcode
614
   *
615
   * Returns \c true if the operation was successful.
616
   *
617
   * \sa insertColumns()
618
   */
619
  bool insertColumn(int column, const WModelIndex& parent = WModelIndex());
620
621
  /*! \brief Inserts one row.
622
   *
623
   * This is a convenience method that adds a single row, and is
624
   * equivalent to:
625
   * \code
626
   * insertRows(row, 1, parent);
627
   * \endcode
628
   *
629
   * Returns \c true if the operation was successful.
630
   *
631
   * \sa insertRows()
632
   */
633
  bool insertRow(int row, const WModelIndex& parent = WModelIndex());
634
635
  /*! \brief Removes one column.
636
   *
637
   * This is a convenience method that removes a single column, and is
638
   * equivalent to:
639
   * \code
640
   * removeColumns(column, 1, parent);
641
   * \endcode
642
   *
643
   * Returns \c true if the operation was successful.
644
   *
645
   * \sa removeColumns()
646
   */
647
  bool removeColumn(int column, const WModelIndex& parent = WModelIndex());
648
649
  /*! \brief Removes one row.
650
   *
651
   * This is a convenience method that removes a single row, and is
652
   * equivalent to:
653
   * \code
654
   * removeRows(row, 1, parent);
655
   * \endcode
656
   *
657
   * Returns \c true if the operation was successful.
658
   *
659
   * \sa removeRows()
660
   */
661
  bool removeRow(int row, const WModelIndex& parent = WModelIndex());
662
663
  /*! \brief Sets data at the given row and column.
664
   *
665
   * This is a convience method, and is equivalent to:
666
   * \code
667
   * setData(index(row, column, parent), value, role);
668
   * \endcode
669
   *
670
   * Returns \c true if the operation was successful.
671
   *
672
   * \sa setData(), index()
673
   */
674
  bool setData(int row, int column, const cpp17::any& value,
675
               ItemDataRole role = ItemDataRole::Edit,
676
               const WModelIndex& parent = WModelIndex());
677
678
  /*! \brief %Signal emitted before a number of columns will be inserted.
679
   *
680
   * The first argument is the parent index. The two integer arguments
681
   * are the column numbers that the first and last column will have when
682
   * inserted.
683
   *
684
   * \sa columnsInserted(), beginInsertColumns()
685
   */
686
  virtual Signal<WModelIndex, int, int>& columnsAboutToBeInserted()
687
0
    { return columnsAboutToBeInserted_; }
688
689
  /*! \brief %Signal emitted before a number of columns will be removed.
690
   *
691
   * The first argument is the parent index. The two integer arguments
692
   * are the column numbers of the first and last column that will be
693
   * removed.
694
   *
695
   * \sa columnsRemoved(), beginRemoveColumns()
696
   */
697
  virtual Signal<WModelIndex, int, int>& columnsAboutToBeRemoved()
698
0
    { return columnsAboutToBeRemoved_; }
699
700
  /*! \brief %Signal emitted after a number of columns were inserted.
701
   *
702
   * The first argument is the parent index. The two integer arguments
703
   * are the column numbers of the first and last column that were
704
   * inserted.
705
   *
706
   * \sa columnsAboutToBeInserted(), endInsertColumns()
707
   */
708
  virtual Signal<WModelIndex, int, int>& columnsInserted()
709
0
    { return columnsInserted_; }
710
711
  /*! \brief %Signal emitted after a number of columns were removed.
712
   *
713
   * The first argument is the parent index. The two integer arguments
714
   * are the column numbers of the first and last column that were removed.
715
   *
716
   * \sa columnsAboutToBeRemoved(), endRemoveColumns()
717
   */
718
  virtual Signal<WModelIndex, int, int>& columnsRemoved()
719
0
    { return columnsRemoved_; }
720
721
  /*! \brief %Signal emitted before a number of rows will be inserted.
722
   *
723
   * The first argument is the parent index. The two integer arguments
724
   * are the row numbers that the first and last row will have when
725
   * inserted.
726
   *
727
   * \sa rowsInserted(), beginInsertRows()
728
   */
729
  virtual Signal<WModelIndex, int, int>& rowsAboutToBeInserted()
730
0
    { return rowsAboutToBeInserted_; }
731
732
  /*! \brief %Signal emitted before a number of rows will be removed.
733
   *
734
   * The first argument is the parent index. The two integer arguments
735
   * are the row numbers of the first and last row that will be
736
   * removed.
737
   *
738
   * \sa rowsRemoved(), beginRemoveRows()
739
   */
740
  virtual Signal<WModelIndex, int, int>& rowsAboutToBeRemoved()
741
0
    { return rowsAboutToBeRemoved_; }
742
743
  /*! \brief %Signal emitted after a number of rows were inserted.
744
   *
745
   * The first argument is the parent index. The two integer arguments
746
   * are the row numbers of the first and last row that were inserted.
747
   *
748
   * \sa rowsAboutToBeInserted(), endInsertRows()
749
   */
750
  virtual Signal<WModelIndex, int, int>& rowsInserted()
751
0
    { return rowsInserted_; }
752
753
  /*! \brief %Signal emitted after a number of rows were removed.
754
   *
755
   * The first argument is the parent index. The two integer arguments
756
   * are the row numbers of the first and last row that were removed.
757
   *
758
   * \sa rowsAboutToBeRemoved(), endRemoveRows()
759
   */
760
  virtual Signal<WModelIndex, int, int>& rowsRemoved()
761
0
    { return rowsRemoved_; }
762
763
  /*! \brief %Signal emitted when some data was changed.
764
   *
765
   * The two arguments are the model indexes of the top-left and bottom-right
766
   * data items that span the rectangle of changed data items.
767
   *
768
   * \sa setData()
769
   */
770
  virtual Signal<WModelIndex, WModelIndex>& dataChanged()
771
0
    { return dataChanged_; }
772
773
  /*! \brief %Signal emitted when some header data was changed.
774
   *
775
   * The first argument indicates the orientation of the header, and
776
   * the two integer arguments are the row or column numbers of the
777
   * first and last header item of which the value was changed.
778
   *
779
   * \sa setHeaderData()
780
   */
781
  virtual Signal<Orientation, int, int>& headerDataChanged()
782
0
    { return headerDataChanged_; }
783
784
  /*! \brief %Signal emitted when the layout is about to be changed.
785
   *
786
   * A layout change may reorder or add/remove rows in the model, but
787
   * columns are preserved. Model indexes are invalidated by a layout
788
   * change, but indexes may be ported across a layout change by using
789
   * the toRawIndex() and fromRawIndex() methods.
790
   *
791
   * \sa layoutChanged(), toRawIndex(), fromRawIndex()
792
   */
793
0
  virtual Signal<>& layoutAboutToBeChanged() { return layoutAboutToBeChanged_; }
794
795
  /*! \brief %Signal emitted when the layout is changed.
796
   *
797
   * \sa layoutAboutToBeChanged()
798
   */
799
0
  virtual Signal<>& layoutChanged() { return layoutChanged_; }
800
801
  /*! \brief %Signal emitted when the model was reset.
802
   *
803
   * A model reset invalidates all existing data, and the model may change
804
   * its entire geometry (column count, row count).
805
   *
806
   * \sa reset()
807
   */
808
0
  virtual Signal<>& modelReset() { return modelReset_; }
809
810
protected:
811
  /*! \brief Resets the model and invalidate any data.
812
   *
813
   * Informs any attached view that all data in the model was invalidated,
814
   * and the model's data should be reread.
815
   *
816
   * This causes the modelReset() signal to be emitted.
817
   */
818
  void reset();
819
820
  /*! \brief Creates a model index for the given row and column.
821
   *
822
   * Use this method to create a model index. \p ptr is an internal
823
   * pointer that may be used to identify the <b>parent</b> of the
824
   * corresponding item. For a flat table model, \p ptr can thus
825
   * always be 0.
826
   *
827
   * \sa WModelIndex::internalPointer()
828
   */
829
  virtual WModelIndex createIndex(int row, int column, void *ptr) const;
830
831
  /*! \brief Creates a model index for the given row and column.
832
   *
833
   * Use this method to create a model index. \p id is an internal id
834
   * that may be used to identify the <b>parent</b> of the
835
   * corresponding item. For a flat table model, \p ptr can thus
836
   * always be 0.
837
   *
838
   * \sa WModelIndex::internalId()
839
   */
840
  virtual WModelIndex createIndex(int row, int column, ::uint64_t id) const;
841
842
  /*! \brief Method to be called before inserting columns.
843
   *
844
   * If your model supports insertion of columns, then you should call
845
   * this method before inserting one or more columns, and
846
   * endInsertColumns() afterwards. These methods emit the necessary
847
   * signals to allow view classes to update themselves.
848
   *
849
   * \sa endInsertColumns(), insertColumns(), columnsAboutToBeInserted
850
   */
851
  void beginInsertColumns(const WModelIndex& parent, int first, int last);
852
853
  /*! \brief Method to be called before inserting rows.
854
   *
855
   * If your model supports insertion of rows, then you should call
856
   * this method before inserting one or more rows, and
857
   * endInsertRows() afterwards. These methods emit the necessary
858
   * signals to allow view classes to update themselves.
859
   *
860
   * \sa endInsertRows(), insertRows(), rowsAboutToBeInserted
861
   */
862
  void beginInsertRows(const WModelIndex& parent, int first, int last);
863
864
  /*! \brief Method to be called before removing columns.
865
   *
866
   * If your model supports removal of columns, then you should call
867
   * this method before removing one or more columns, and
868
   * endRemoveColumns() afterwards. These methods emit the necessary
869
   * signals to allow view classes to update themselves.
870
   *
871
   * \sa endRemoveColumns(), removeColumns(), columnsAboutToBeRemoved
872
   */
873
  void beginRemoveColumns(const WModelIndex& parent, int first, int last);
874
875
  /*! \brief Method to be called before removing rows.
876
   *
877
   * If your model supports removal of rows, then you should call this
878
   * method before removing one or more rows, and endRemoveRows()
879
   * afterwards. These methods emit the necessary signals to allow
880
   * view classes to update themselves.
881
   *
882
   * \sa endRemoveRows(), removeRows(), rowsAboutToBeRemoved
883
   */
884
  void beginRemoveRows(const WModelIndex& parent, int first, int last);
885
886
  /*! \brief Method to be called after inserting columns.
887
   *
888
   * \sa beginInsertColumns()
889
   */
890
  void endInsertColumns();
891
892
  /*! \brief Method to be called after inserting rows.
893
   *
894
   * \sa beginInsertRows()
895
   */
896
  void endInsertRows();
897
898
  /*! \brief Method to be called after removing columns.
899
   *
900
   * \sa beginRemoveColumns()
901
   */
902
  void endRemoveColumns();
903
904
  /*! \brief Method to be called after removing rows.
905
   *
906
   * \sa beginRemoveRows()
907
   */
908
  void endRemoveRows();
909
910
  /*! \brief Copy data to an index in this model.
911
   *
912
   * The source index can be any valid index. The destination
913
   * index must be part of this model.
914
   */
915
  virtual void copyData(const WModelIndex& sIndex,
916
                        const WModelIndex& dIndex);
917
918
private:
919
  int first_, last_;
920
  WModelIndex parent_;
921
922
  Signal<WModelIndex, int, int> columnsAboutToBeInserted_;
923
  Signal<WModelIndex, int, int> columnsAboutToBeRemoved_;
924
  Signal<WModelIndex, int, int> columnsInserted_;
925
  Signal<WModelIndex, int, int> columnsRemoved_;
926
  Signal<WModelIndex, int, int> rowsAboutToBeInserted_;
927
  Signal<WModelIndex, int, int> rowsAboutToBeRemoved_;
928
  Signal<WModelIndex, int, int> rowsInserted_;
929
  Signal<WModelIndex, int, int> rowsRemoved_;
930
  Signal<WModelIndex, WModelIndex> dataChanged_;
931
  Signal<Orientation, int, int> headerDataChanged_;
932
  Signal<> layoutAboutToBeChanged_;
933
  Signal<> layoutChanged_;
934
  Signal<> modelReset_;
935
936
  friend class WAbstractProxyModel;
937
};
938
939
}
940
941
#endif // WABSTRACT_ITEM_MODEL_H_