/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_ |