1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file. Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qlistwidget.h"
43
44 #ifndef QT_NO_LISTWIDGET
45 #include <qitemdelegate.h>
46 #include <private/qlistview_p.h>
47 #include <private/qwidgetitemdata_p.h>
48 #include <private/qlistwidget_p.h>
49
50 QT_BEGIN_NAMESPACE
51
52 // workaround for VC++ 6.0 linker bug (?)
53 typedef bool(*LessThan)(const QPair<QListWidgetItem*,int>&,const QPair<QListWidgetItem*,int>&);
54
55 class QListWidgetMimeData : public QMimeData
56 {
57 Q_OBJECT
58 public:
59 QList<QListWidgetItem*> items;
60 };
61
62 QT_BEGIN_INCLUDE_NAMESPACE
63 #include "qlistwidget.moc"
64 QT_END_INCLUDE_NAMESPACE
65
QListModel(QListWidget * parent)66 QListModel::QListModel(QListWidget *parent)
67 : QAbstractListModel(parent)
68 {
69 }
70
~QListModel()71 QListModel::~QListModel()
72 {
73 clear();
74 }
75
clear()76 void QListModel::clear()
77 {
78 for (int i = 0; i < items.count(); ++i) {
79 if (items.at(i)) {
80 items.at(i)->d->theid = -1;
81 items.at(i)->view = 0;
82 delete items.at(i);
83 }
84 }
85 items.clear();
86 reset();
87 }
88
at(int row) const89 QListWidgetItem *QListModel::at(int row) const
90 {
91 return items.value(row);
92 }
93
remove(QListWidgetItem * item)94 void QListModel::remove(QListWidgetItem *item)
95 {
96 if (!item)
97 return;
98 int row = items.indexOf(item); // ### use index(item) - it's faster
99 Q_ASSERT(row != -1);
100 beginRemoveRows(QModelIndex(), row, row);
101 items.at(row)->d->theid = -1;
102 items.at(row)->view = 0;
103 items.removeAt(row);
104 endRemoveRows();
105 }
106
insert(int row,QListWidgetItem * item)107 void QListModel::insert(int row, QListWidgetItem *item)
108 {
109 if (!item)
110 return;
111
112 item->view = qobject_cast<QListWidget*>(QObject::parent());
113 if (item->view && item->view->isSortingEnabled()) {
114 // sorted insertion
115 QList<QListWidgetItem*>::iterator it;
116 it = sortedInsertionIterator(items.begin(), items.end(),
117 item->view->sortOrder(), item);
118 row = qMax(it - items.begin(), 0);
119 } else {
120 if (row < 0)
121 row = 0;
122 else if (row > items.count())
123 row = items.count();
124 }
125 beginInsertRows(QModelIndex(), row, row);
126 items.insert(row, item);
127 item->d->theid = row;
128 endInsertRows();
129 }
130
insert(int row,const QStringList & labels)131 void QListModel::insert(int row, const QStringList &labels)
132 {
133 const int count = labels.count();
134 if (count <= 0)
135 return;
136 QListWidget *view = qobject_cast<QListWidget*>(QObject::parent());
137 if (view && view->isSortingEnabled()) {
138 // sorted insertion
139 for (int i = 0; i < count; ++i) {
140 QListWidgetItem *item = new QListWidgetItem(labels.at(i));
141 insert(row, item);
142 }
143 } else {
144 if (row < 0)
145 row = 0;
146 else if (row > items.count())
147 row = items.count();
148 beginInsertRows(QModelIndex(), row, row + count - 1);
149 for (int i = 0; i < count; ++i) {
150 QListWidgetItem *item = new QListWidgetItem(labels.at(i));
151 item->d->theid = row;
152 item->view = qobject_cast<QListWidget*>(QObject::parent());
153 items.insert(row++, item);
154 }
155 endInsertRows();
156 }
157 }
158
take(int row)159 QListWidgetItem *QListModel::take(int row)
160 {
161 if (row < 0 || row >= items.count())
162 return 0;
163
164 beginRemoveRows(QModelIndex(), row, row);
165 items.at(row)->d->theid = -1;
166 items.at(row)->view = 0;
167 QListWidgetItem *item = items.takeAt(row);
168 endRemoveRows();
169 return item;
170 }
171
move(int srcRow,int dstRow)172 void QListModel::move(int srcRow, int dstRow)
173 {
174 if (srcRow == dstRow
175 || srcRow < 0 || srcRow >= items.count()
176 || dstRow < 0 || dstRow > items.count())
177 return;
178
179 if (!beginMoveRows(QModelIndex(), srcRow, srcRow, QModelIndex(), dstRow))
180 return;
181 if (srcRow < dstRow)
182 --dstRow;
183 items.move(srcRow, dstRow);
184 endMoveRows();
185 }
186
rowCount(const QModelIndex & parent) const187 int QListModel::rowCount(const QModelIndex &parent) const
188 {
189 return parent.isValid() ? 0 : items.count();
190 }
191
index(QListWidgetItem * item) const192 QModelIndex QListModel::index(QListWidgetItem *item) const
193 {
194 if (!item || !item->view || static_cast<const QListModel *>(item->view->model()) != this
195 || items.isEmpty())
196 return QModelIndex();
197 int row;
198 const int theid = item->d->theid;
199 if (theid >= 0 && theid < items.count() && items.at(theid) == item) {
200 row = theid;
201 } else { // we need to search for the item
202 row = items.lastIndexOf(item); // lastIndexOf is an optimization in favor of indexOf
203 if (row == -1) // not found
204 return QModelIndex();
205 item->d->theid = row;
206 }
207 return createIndex(row, 0, item);
208 }
209
index(int row,int column,const QModelIndex & parent) const210 QModelIndex QListModel::index(int row, int column, const QModelIndex &parent) const
211 {
212 if (hasIndex(row, column, parent))
213 return createIndex(row, column, items.at(row));
214 return QModelIndex();
215 }
216
data(const QModelIndex & index,int role) const217 QVariant QListModel::data(const QModelIndex &index, int role) const
218 {
219 if (!index.isValid() || index.row() >= items.count())
220 return QVariant();
221 return items.at(index.row())->data(role);
222 }
223
setData(const QModelIndex & index,const QVariant & value,int role)224 bool QListModel::setData(const QModelIndex &index, const QVariant &value, int role)
225 {
226 if (!index.isValid() || index.row() >= items.count())
227 return false;
228 items.at(index.row())->setData(role, value);
229 return true;
230 }
231
itemData(const QModelIndex & index) const232 QMap<int, QVariant> QListModel::itemData(const QModelIndex &index) const
233 {
234 QMap<int, QVariant> roles;
235 if (!index.isValid() || index.row() >= items.count())
236 return roles;
237 QListWidgetItem *itm = items.at(index.row());
238 for (int i = 0; i < itm->d->values.count(); ++i) {
239 roles.insert(itm->d->values.at(i).role,
240 itm->d->values.at(i).value);
241 }
242 return roles;
243 }
244
insertRows(int row,int count,const QModelIndex & parent)245 bool QListModel::insertRows(int row, int count, const QModelIndex &parent)
246 {
247 if (count < 1 || row < 0 || row > rowCount() || parent.isValid())
248 return false;
249
250 beginInsertRows(QModelIndex(), row, row + count - 1);
251 QListWidget *view = qobject_cast<QListWidget*>(QObject::parent());
252 QListWidgetItem *itm = 0;
253
254 for (int r = row; r < row + count; ++r) {
255 itm = new QListWidgetItem;
256 itm->view = view;
257 itm->d->theid = r;
258 items.insert(r, itm);
259 }
260
261 endInsertRows();
262 return true;
263 }
264
removeRows(int row,int count,const QModelIndex & parent)265 bool QListModel::removeRows(int row, int count, const QModelIndex &parent)
266 {
267 if (count < 1 || row < 0 || (row + count) > rowCount() || parent.isValid())
268 return false;
269
270 beginRemoveRows(QModelIndex(), row, row + count - 1);
271 QListWidgetItem *itm = 0;
272 for (int r = row; r < row + count; ++r) {
273 itm = items.takeAt(row);
274 itm->view = 0;
275 itm->d->theid = -1;
276 delete itm;
277 }
278 endRemoveRows();
279 return true;
280 }
281
flags(const QModelIndex & index) const282 Qt::ItemFlags QListModel::flags(const QModelIndex &index) const
283 {
284 if (!index.isValid() || index.row() >= items.count() || index.model() != this)
285 return Qt::ItemIsDropEnabled; // we allow drops outside the items
286 return items.at(index.row())->flags();
287 }
288
sort(int column,Qt::SortOrder order)289 void QListModel::sort(int column, Qt::SortOrder order)
290 {
291 if (column != 0)
292 return;
293
294 emit layoutAboutToBeChanged();
295
296 QVector < QPair<QListWidgetItem*,int> > sorting(items.count());
297 for (int i = 0; i < items.count(); ++i) {
298 QListWidgetItem *item = items.at(i);
299 sorting[i].first = item;
300 sorting[i].second = i;
301 }
302
303 LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
304 qSort(sorting.begin(), sorting.end(), compare);
305 QModelIndexList fromIndexes;
306 QModelIndexList toIndexes;
307 for (int r = 0; r < sorting.count(); ++r) {
308 QListWidgetItem *item = sorting.at(r).first;
309 toIndexes.append(createIndex(r, 0, item));
310 fromIndexes.append(createIndex(sorting.at(r).second, 0, sorting.at(r).first));
311 items[r] = sorting.at(r).first;
312 }
313 changePersistentIndexList(fromIndexes, toIndexes);
314
315 emit layoutChanged();
316 }
317
318 /**
319 * This function assumes that all items in the model except the items that are between
320 * (inclusive) start and end are sorted.
321 * With these assumptions, this function can ensure that the model is sorted in a
322 * much more efficient way than doing a naive 'sort everything'.
323 * (provided that the range is relatively small compared to the total number of items)
324 */
ensureSorted(int column,Qt::SortOrder order,int start,int end)325 void QListModel::ensureSorted(int column, Qt::SortOrder order, int start, int end)
326 {
327 if (column != 0)
328 return;
329
330 int count = end - start + 1;
331 QVector < QPair<QListWidgetItem*,int> > sorting(count);
332 for (int i = 0; i < count; ++i) {
333 sorting[i].first = items.at(start + i);
334 sorting[i].second = start + i;
335 }
336
337 LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
338 qSort(sorting.begin(), sorting.end(), compare);
339
340 QModelIndexList oldPersistentIndexes = persistentIndexList();
341 QModelIndexList newPersistentIndexes = oldPersistentIndexes;
342 QList<QListWidgetItem*> tmp = items;
343 QList<QListWidgetItem*>::iterator lit = tmp.begin();
344 bool changed = false;
345 for (int i = 0; i < count; ++i) {
346 int oldRow = sorting.at(i).second;
347 QListWidgetItem *item = tmp.takeAt(oldRow);
348 lit = sortedInsertionIterator(lit, tmp.end(), order, item);
349 int newRow = qMax(lit - tmp.begin(), 0);
350 lit = tmp.insert(lit, item);
351 if (newRow != oldRow) {
352 changed = true;
353 for (int j = i + 1; j < count; ++j) {
354 int otherRow = sorting.at(j).second;
355 if (oldRow < otherRow && newRow >= otherRow)
356 --sorting[j].second;
357 else if (oldRow > otherRow && newRow <= otherRow)
358 ++sorting[j].second;
359 }
360 for (int k = 0; k < newPersistentIndexes.count(); ++k) {
361 QModelIndex pi = newPersistentIndexes.at(k);
362 int oldPersistentRow = pi.row();
363 int newPersistentRow = oldPersistentRow;
364 if (oldPersistentRow == oldRow)
365 newPersistentRow = newRow;
366 else if (oldRow < oldPersistentRow && newRow >= oldPersistentRow)
367 newPersistentRow = oldPersistentRow - 1;
368 else if (oldRow > oldPersistentRow && newRow <= oldPersistentRow)
369 newPersistentRow = oldPersistentRow + 1;
370 if (newPersistentRow != oldPersistentRow)
371 newPersistentIndexes[k] = createIndex(newPersistentRow,
372 pi.column(), pi.internalPointer());
373 }
374 }
375 }
376
377 if (changed) {
378 emit layoutAboutToBeChanged();
379 items = tmp;
380 changePersistentIndexList(oldPersistentIndexes, newPersistentIndexes);
381 emit layoutChanged();
382 }
383 }
384
itemLessThan(const QPair<QListWidgetItem *,int> & left,const QPair<QListWidgetItem *,int> & right)385 bool QListModel::itemLessThan(const QPair<QListWidgetItem*,int> &left,
386 const QPair<QListWidgetItem*,int> &right)
387 {
388 return (*left.first) < (*right.first);
389 }
390
itemGreaterThan(const QPair<QListWidgetItem *,int> & left,const QPair<QListWidgetItem *,int> & right)391 bool QListModel::itemGreaterThan(const QPair<QListWidgetItem*,int> &left,
392 const QPair<QListWidgetItem*,int> &right)
393 {
394 return (*right.first) < (*left.first);
395 }
396
sortedInsertionIterator(const QList<QListWidgetItem * >::iterator & begin,const QList<QListWidgetItem * >::iterator & end,Qt::SortOrder order,QListWidgetItem * item)397 QList<QListWidgetItem*>::iterator QListModel::sortedInsertionIterator(
398 const QList<QListWidgetItem*>::iterator &begin,
399 const QList<QListWidgetItem*>::iterator &end,
400 Qt::SortOrder order, QListWidgetItem *item)
401 {
402 if (order == Qt::AscendingOrder)
403 return qLowerBound(begin, end, item, QListModelLessThan());
404 return qLowerBound(begin, end, item, QListModelGreaterThan());
405 }
406
itemChanged(QListWidgetItem * item)407 void QListModel::itemChanged(QListWidgetItem *item)
408 {
409 QModelIndex idx = index(item);
410 emit dataChanged(idx, idx);
411 }
412
mimeTypes() const413 QStringList QListModel::mimeTypes() const
414 {
415 const QListWidget *view = qobject_cast<const QListWidget*>(QObject::parent());
416 return view->mimeTypes();
417 }
418
internalMimeData() const419 QMimeData *QListModel::internalMimeData() const
420 {
421 return QAbstractItemModel::mimeData(cachedIndexes);
422 }
423
mimeData(const QModelIndexList & indexes) const424 QMimeData *QListModel::mimeData(const QModelIndexList &indexes) const
425 {
426 QList<QListWidgetItem*> itemlist;
427 for (int i = 0; i < indexes.count(); ++i)
428 itemlist << at(indexes.at(i).row());
429 const QListWidget *view = qobject_cast<const QListWidget*>(QObject::parent());
430
431 cachedIndexes = indexes;
432 QMimeData *mimeData = view->mimeData(itemlist);
433 cachedIndexes.clear();
434 return mimeData;
435 }
436
437 #ifndef QT_NO_DRAGANDDROP
dropMimeData(const QMimeData * data,Qt::DropAction action,int row,int column,const QModelIndex & index)438 bool QListModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
439 int row, int column, const QModelIndex &index)
440 {
441 Q_UNUSED(column);
442 QListWidget *view = qobject_cast<QListWidget*>(QObject::parent());
443 if (index.isValid())
444 row = index.row();
445 else if (row == -1)
446 row = items.count();
447
448 return view->dropMimeData(row, data, action);
449 }
450
supportedDropActions() const451 Qt::DropActions QListModel::supportedDropActions() const
452 {
453 const QListWidget *view = qobject_cast<const QListWidget*>(QObject::parent());
454 return view->supportedDropActions();
455 }
456 #endif // QT_NO_DRAGANDDROP
457
458 /*!
459 \class QListWidgetItem
460 \brief The QListWidgetItem class provides an item for use with the
461 QListWidget item view class.
462
463 \ingroup model-view
464
465 A QListWidgetItem represents a single item in a QListWidget. Each item can
466 hold several pieces of information, and will display them appropriately.
467
468 The item view convenience classes use a classic item-based interface rather
469 than a pure model/view approach. For a more flexible list view widget,
470 consider using the QListView class with a standard model.
471
472 List items can be inserted automatically into a list, when they are
473 constructed, by specifying the list widget:
474
475 \snippet doc/src/snippets/qlistwidget-using/mainwindow.cpp 2
476
477 Alternatively, list items can also be created without a parent widget, and
478 later inserted into a list using QListWidget::insertItem().
479
480 List items are typically used to display text() and an icon(). These are
481 set with the setText() and setIcon() functions. The appearance of the text
482 can be customized with setFont(), setForeground(), and setBackground().
483 Text in list items can be aligned using the setTextAlignment() function.
484 Tooltips, status tips and "What's This?" help can be added to list items
485 with setToolTip(), setStatusTip(), and setWhatsThis().
486
487 By default, items are enabled, selectable, checkable, and can be the source
488 of drag and drop operations.
489
490 Each item's flags can be changed by calling setFlags() with the appropriate
491 value (see Qt::ItemFlags). Checkable items can be checked, unchecked and
492 partially checked with the setCheckState() function. The corresponding
493 checkState() function indicates the item's current check state.
494
495 The isHidden() function can be used to determine whether the item is
496 hidden. To hide an item, use setHidden().
497
498
499 \section1 Subclassing
500
501 When subclassing QListWidgetItem to provide custom items, it is possible to
502 define new types for them enabling them to be distinguished from standard
503 items. For subclasses that require this feature, ensure that you call the
504 base class constructor with a new type value equal to or greater than
505 \l UserType, within \e your constructor.
506
507 \sa QListWidget, {Model/View Programming}, QTreeWidgetItem, QTableWidgetItem
508 */
509
510 /*!
511 \enum QListWidgetItem::ItemType
512
513 This enum describes the types that are used to describe list widget items.
514
515 \value Type The default type for list widget items.
516 \value UserType The minimum value for custom types. Values below UserType are
517 reserved by Qt.
518
519 You can define new user types in QListWidgetItem subclasses to ensure that
520 custom items are treated specially.
521
522 \sa type()
523 */
524
525 /*!
526 \fn int QListWidgetItem::type() const
527
528 Returns the type passed to the QListWidgetItem constructor.
529 */
530
531 /*!
532 \fn QListWidget *QListWidgetItem::listWidget() const
533
534 Returns the list widget containing the item.
535 */
536
537 /*!
538 \fn void QListWidgetItem::setSelected(bool select)
539 \since 4.2
540
541 Sets the selected state of the item to \a select.
542
543 \sa isSelected()
544 */
545
546 /*!
547 \fn bool QListWidgetItem::isSelected() const
548 \since 4.2
549
550 Returns true if the item is selected; otherwise returns false.
551
552 \sa setSelected()
553 */
554
555 /*!
556 \fn void QListWidgetItem::setHidden(bool hide)
557 \since 4.2
558
559 Hides the item if \a hide is true; otherwise shows the item.
560
561 \sa isHidden()
562 */
563
564 /*!
565 \fn bool QListWidgetItem::isHidden() const
566 \since 4.2
567
568 Returns true if the item is hidden; otherwise returns false.
569
570 \sa setHidden()
571 */
572
573 /*!
574 \fn QListWidgetItem::QListWidgetItem(QListWidget *parent, int type)
575
576 Constructs an empty list widget item of the specified \a type with the
577 given \a parent. If \a parent is not specified, the item will need to be
578 inserted into a list widget with QListWidget::insertItem().
579
580 This constructor inserts the item into the model of the parent that is
581 passed to the constructor. If the model is sorted then the behavior of the
582 insert is undetermined since the model will call the \c '<' operator method
583 on the item which, at this point, is not yet constructed. To avoid the
584 undetermined behavior, we recommend not to specify the parent and use
585 QListWidget::insertItem() instead.
586
587 \sa type()
588 */
QListWidgetItem(QListWidget * view,int type)589 QListWidgetItem::QListWidgetItem(QListWidget *view, int type)
590 : rtti(type), view(view), d(new QListWidgetItemPrivate(this)),
591 itemFlags(Qt::ItemIsSelectable
592 |Qt::ItemIsUserCheckable
593 |Qt::ItemIsEnabled
594 |Qt::ItemIsDragEnabled)
595 {
596 if (QListModel *model = (view ? qobject_cast<QListModel*>(view->model()) : 0))
597 model->insert(model->rowCount(), this);
598 }
599
600 /*!
601 \fn QListWidgetItem::QListWidgetItem(const QString &text, QListWidget *parent, int type)
602
603 Constructs an empty list widget item of the specified \a type with the
604 given \a text and \a parent. If the parent is not specified, the item will
605 need to be inserted into a list widget with QListWidget::insertItem().
606
607 This constructor inserts the item into the model of the parent that is
608 passed to the constructor. If the model is sorted then the behavior of the
609 insert is undetermined since the model will call the \c '<' operator method
610 on the item which, at this point, is not yet constructed. To avoid the
611 undetermined behavior, we recommend not to specify the parent and use
612 QListWidget::insertItem() instead.
613
614 \sa type()
615 */
QListWidgetItem(const QString & text,QListWidget * view,int type)616 QListWidgetItem::QListWidgetItem(const QString &text, QListWidget *view, int type)
617 : rtti(type), view(0), d(new QListWidgetItemPrivate(this)),
618 itemFlags(Qt::ItemIsSelectable
619 |Qt::ItemIsUserCheckable
620 |Qt::ItemIsEnabled
621 |Qt::ItemIsDragEnabled)
622 {
623 setData(Qt::DisplayRole, text);
624 this->view = view;
625 if (QListModel *model = (view ? qobject_cast<QListModel*>(view->model()) : 0))
626 model->insert(model->rowCount(), this);
627 }
628
629 /*!
630 \fn QListWidgetItem::QListWidgetItem(const QIcon &icon, const QString &text, QListWidget *parent, int type)
631
632 Constructs an empty list widget item of the specified \a type with the
633 given \a icon, \a text and \a parent. If the parent is not specified, the
634 item will need to be inserted into a list widget with
635 QListWidget::insertItem().
636
637 This constructor inserts the item into the model of the parent that is
638 passed to the constructor. If the model is sorted then the behavior of the
639 insert is undetermined since the model will call the \c '<' operator method
640 on the item which, at this point, is not yet constructed. To avoid the
641 undetermined behavior, we recommend not to specify the parent and use
642 QListWidget::insertItem() instead.
643
644 \sa type()
645 */
QListWidgetItem(const QIcon & icon,const QString & text,QListWidget * view,int type)646 QListWidgetItem::QListWidgetItem(const QIcon &icon,const QString &text,
647 QListWidget *view, int type)
648 : rtti(type), view(0), d(new QListWidgetItemPrivate(this)),
649 itemFlags(Qt::ItemIsSelectable
650 |Qt::ItemIsUserCheckable
651 |Qt::ItemIsEnabled
652 |Qt::ItemIsDragEnabled)
653 {
654 setData(Qt::DisplayRole, text);
655 setData(Qt::DecorationRole, icon);
656 this->view = view;
657 if (QListModel *model = (view ? qobject_cast<QListModel*>(view->model()) : 0))
658 model->insert(model->rowCount(), this);
659 }
660
661 /*!
662 Destroys the list item.
663 */
~QListWidgetItem()664 QListWidgetItem::~QListWidgetItem()
665 {
666 if (QListModel *model = (view ? qobject_cast<QListModel*>(view->model()) : 0))
667 model->remove(this);
668 delete d;
669 }
670
671 /*!
672 Creates an exact copy of the item.
673 */
clone() const674 QListWidgetItem *QListWidgetItem::clone() const
675 {
676 return new QListWidgetItem(*this);
677 }
678
679 /*!
680 Sets the data for a given \a role to the given \a value. Reimplement this
681 function if you need extra roles or special behavior for certain roles.
682
683 \sa Qt::ItemDataRole, data()
684 */
setData(int role,const QVariant & value)685 void QListWidgetItem::setData(int role, const QVariant &value)
686 {
687 bool found = false;
688 role = (role == Qt::EditRole ? Qt::DisplayRole : role);
689 for (int i = 0; i < d->values.count(); ++i) {
690 if (d->values.at(i).role == role) {
691 if (d->values.at(i).value == value)
692 return;
693 d->values[i].value = value;
694 found = true;
695 break;
696 }
697 }
698 if (!found)
699 d->values.append(QWidgetItemData(role, value));
700 if (QListModel *model = (view ? qobject_cast<QListModel*>(view->model()) : 0))
701 model->itemChanged(this);
702 }
703
704 /*!
705 Returns the item's data for a given \a role. Reimplement this function if
706 you need extra roles or special behavior for certain roles.
707
708 \sa Qt::ItemDataRole, setData()
709 */
data(int role) const710 QVariant QListWidgetItem::data(int role) const
711 {
712 role = (role == Qt::EditRole ? Qt::DisplayRole : role);
713 for (int i = 0; i < d->values.count(); ++i)
714 if (d->values.at(i).role == role)
715 return d->values.at(i).value;
716 return QVariant();
717 }
718
719 /*!
720 Returns true if this item's text is less then \a other item's text;
721 otherwise returns false.
722 */
operator <(const QListWidgetItem & other) const723 bool QListWidgetItem::operator<(const QListWidgetItem &other) const
724 {
725 const QVariant v1 = data(Qt::DisplayRole), v2 = other.data(Qt::DisplayRole);
726 return QAbstractItemModelPrivate::variantLessThan(v1, v2);
727 }
728
729 #ifndef QT_NO_DATASTREAM
730
731 /*!
732 Reads the item from stream \a in.
733
734 \sa write()
735 */
read(QDataStream & in)736 void QListWidgetItem::read(QDataStream &in)
737 {
738 in >> d->values;
739 }
740
741 /*!
742 Writes the item to stream \a out.
743
744 \sa read()
745 */
write(QDataStream & out) const746 void QListWidgetItem::write(QDataStream &out) const
747 {
748 out << d->values;
749 }
750 #endif // QT_NO_DATASTREAM
751
752 /*!
753 \since 4.1
754
755 Constructs a copy of \a other. Note that type() and listWidget() are not
756 copied.
757
758 This function is useful when reimplementing clone().
759
760 \sa data(), flags()
761 */
QListWidgetItem(const QListWidgetItem & other)762 QListWidgetItem::QListWidgetItem(const QListWidgetItem &other)
763 : rtti(Type), view(0),
764 d(new QListWidgetItemPrivate(this)),
765 itemFlags(other.itemFlags)
766 {
767 d->values = other.d->values;
768 }
769
770 /*!
771 Assigns \a other's data and flags to this item. Note that type() and
772 listWidget() are not copied.
773
774 This function is useful when reimplementing clone().
775
776 \sa data(), flags()
777 */
operator =(const QListWidgetItem & other)778 QListWidgetItem &QListWidgetItem::operator=(const QListWidgetItem &other)
779 {
780 d->values = other.d->values;
781 itemFlags = other.itemFlags;
782 return *this;
783 }
784
785 #ifndef QT_NO_DATASTREAM
786
787 /*!
788 \relates QListWidgetItem
789
790 Writes the list widget item \a item to stream \a out.
791
792 This operator uses QListWidgetItem::write().
793
794 \sa {Serializing Qt Data Types}
795 */
operator <<(QDataStream & out,const QListWidgetItem & item)796 QDataStream &operator<<(QDataStream &out, const QListWidgetItem &item)
797 {
798 item.write(out);
799 return out;
800 }
801
802 /*!
803 \relates QListWidgetItem
804
805 Reads a list widget item from stream \a in into \a item.
806
807 This operator uses QListWidgetItem::read().
808
809 \sa {Serializing Qt Data Types}
810 */
operator >>(QDataStream & in,QListWidgetItem & item)811 QDataStream &operator>>(QDataStream &in, QListWidgetItem &item)
812 {
813 item.read(in);
814 return in;
815 }
816
817 #endif // QT_NO_DATASTREAM
818
819 /*!
820 \fn Qt::ItemFlags QListWidgetItem::flags() const
821
822 Returns the item flags for this item (see \l{Qt::ItemFlags}).
823 */
824
825 /*!
826 \fn QString QListWidgetItem::text() const
827
828 Returns the list item's text.
829
830 \sa setText()
831 */
832
833 /*!
834 \fn QIcon QListWidgetItem::icon() const
835
836 Returns the list item's icon.
837
838 \sa setIcon(), {QAbstractItemView::iconSize}{iconSize}
839 */
840
841 /*!
842 \fn QString QListWidgetItem::statusTip() const
843
844 Returns the list item's status tip.
845
846 \sa setStatusTip()
847 */
848
849 /*!
850 \fn QString QListWidgetItem::toolTip() const
851
852 Returns the list item's tooltip.
853
854 \sa setToolTip() statusTip() whatsThis()
855 */
856
857 /*!
858 \fn QString QListWidgetItem::whatsThis() const
859
860 Returns the list item's "What's This?" help text.
861
862 \sa setWhatsThis() statusTip() toolTip()
863 */
864
865 /*!
866 \fn QFont QListWidgetItem::font() const
867
868 Returns the font used to display this list item's text.
869 */
870
871 /*!
872 \fn int QListWidgetItem::textAlignment() const
873
874 Returns the text alignment for the list item.
875
876 \sa Qt::AlignmentFlag
877 */
878
879 /*!
880 \fn QColor QListWidgetItem::backgroundColor() const
881 \obsolete
882
883 This function is deprecated. Use background() instead.
884 */
885
886 /*!
887 \fn QBrush QListWidgetItem::background() const
888 \since 4.2
889
890 Returns the brush used to display the list item's background.
891
892 \sa setBackground() foreground()
893 */
894
895 /*!
896 \fn QColor QListWidgetItem::textColor() const
897 \obsolete
898
899 Returns the color used to display the list item's text.
900
901 This function is deprecated. Use foreground() instead.
902 */
903
904 /*!
905 \fn QBrush QListWidgetItem::foreground() const
906 \since 4.2
907
908 Returns the brush used to display the list item's foreground (e.g. text).
909
910 \sa setForeground() background()
911 */
912
913 /*!
914 \fn Qt::CheckState QListWidgetItem::checkState() const
915
916 Returns the checked state of the list item (see \l{Qt::CheckState}).
917
918 \sa flags()
919 */
920
921 /*!
922 \fn QSize QListWidgetItem::sizeHint() const
923 \since 4.1
924
925 Returns the size hint set for the list item.
926 */
927
928 /*!
929 \fn void QListWidgetItem::setSizeHint(const QSize &size)
930 \since 4.1
931
932 Sets the size hint for the list item to be \a size. If no size hint is set,
933 the item delegate will compute the size hint based on the item data.
934 */
935
936 /*!
937 \fn void QListWidgetItem::setFlags(Qt::ItemFlags flags)
938
939 Sets the item flags for the list item to \a flags.
940
941 \sa Qt::ItemFlags
942 */
setFlags(Qt::ItemFlags aflags)943 void QListWidgetItem::setFlags(Qt::ItemFlags aflags) {
944 itemFlags = aflags;
945 if (QListModel *model = (view ? qobject_cast<QListModel*>(view->model()) : 0))
946 model->itemChanged(this);
947 }
948
949
950 /*!
951 \fn void QListWidgetItem::setText(const QString &text)
952
953 Sets the text for the list widget item's to the given \a text.
954
955 \sa text()
956 */
957
958 /*!
959 \fn void QListWidgetItem::setIcon(const QIcon &icon)
960
961 Sets the icon for the list item to the given \a icon.
962
963 \sa icon(), text(), {QAbstractItemView::iconSize}{iconSize}
964 */
965
966 /*!
967 \fn void QListWidgetItem::setStatusTip(const QString &statusTip)
968
969 Sets the status tip for the list item to the text specified by
970 \a statusTip. QListWidget mouseTracking needs to be enabled for this
971 feature to work.
972
973 \sa statusTip(), setToolTip(), setWhatsThis(), QWidget::setMouseTracking()
974 */
975
976 /*!
977 \fn void QListWidgetItem::setToolTip(const QString &toolTip)
978
979 Sets the tooltip for the list item to the text specified by \a toolTip.
980
981 \sa toolTip(), setStatusTip(), setWhatsThis()
982 */
983
984 /*!
985 \fn void QListWidgetItem::setWhatsThis(const QString &whatsThis)
986
987 Sets the "What's This?" help for the list item to the text specified by
988 \a whatsThis.
989
990 \sa whatsThis(), setStatusTip(), setToolTip()
991 */
992
993 /*!
994 \fn void QListWidgetItem::setFont(const QFont &font)
995
996 Sets the font used when painting the item to the given \a font.
997 */
998
999 /*!
1000 \fn void QListWidgetItem::setTextAlignment(int alignment)
1001
1002 Sets the list item's text alignment to \a alignment.
1003
1004 \sa Qt::AlignmentFlag
1005 */
1006
1007 /*!
1008 \fn void QListWidgetItem::setBackgroundColor(const QColor &color)
1009 \obsolete
1010
1011 This function is deprecated. Use setBackground() instead.
1012 */
1013
1014 /*!
1015 \fn void QListWidgetItem::setBackground(const QBrush &brush)
1016 \since 4.2
1017
1018 Sets the background brush of the list item to the given \a brush.
1019
1020 \sa background() setForeground()
1021 */
1022
1023 /*!
1024 \fn void QListWidgetItem::setTextColor(const QColor &color)
1025 \obsolete
1026
1027 This function is deprecated. Use setForeground() instead.
1028 */
1029
1030 /*!
1031 \fn void QListWidgetItem::setForeground(const QBrush &brush)
1032 \since 4.2
1033
1034 Sets the foreground brush of the list item to the given \a brush.
1035
1036 \sa foreground() setBackground()
1037 */
1038
1039 /*!
1040 \fn void QListWidgetItem::setCheckState(Qt::CheckState state)
1041
1042 Sets the check state of the list item to \a state.
1043
1044 \sa checkState()
1045 */
1046
setup()1047 void QListWidgetPrivate::setup()
1048 {
1049 Q_Q(QListWidget);
1050 q->QListView::setModel(new QListModel(q));
1051 // view signals
1052 QObject::connect(q, SIGNAL(pressed(QModelIndex)), q, SLOT(_q_emitItemPressed(QModelIndex)));
1053 QObject::connect(q, SIGNAL(clicked(QModelIndex)), q, SLOT(_q_emitItemClicked(QModelIndex)));
1054 QObject::connect(q, SIGNAL(doubleClicked(QModelIndex)),
1055 q, SLOT(_q_emitItemDoubleClicked(QModelIndex)));
1056 QObject::connect(q, SIGNAL(activated(QModelIndex)),
1057 q, SLOT(_q_emitItemActivated(QModelIndex)));
1058 QObject::connect(q, SIGNAL(entered(QModelIndex)), q, SLOT(_q_emitItemEntered(QModelIndex)));
1059 QObject::connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
1060 q, SLOT(_q_emitItemChanged(QModelIndex)));
1061 QObject::connect(q->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
1062 q, SLOT(_q_emitCurrentItemChanged(QModelIndex,QModelIndex)));
1063 QObject::connect(q->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
1064 q, SIGNAL(itemSelectionChanged()));
1065 QObject::connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
1066 q, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
1067 QObject::connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)), q, SLOT(_q_sort()));
1068 }
1069
_q_emitItemPressed(const QModelIndex & index)1070 void QListWidgetPrivate::_q_emitItemPressed(const QModelIndex &index)
1071 {
1072 Q_Q(QListWidget);
1073 emit q->itemPressed(listModel()->at(index.row()));
1074 }
1075
_q_emitItemClicked(const QModelIndex & index)1076 void QListWidgetPrivate::_q_emitItemClicked(const QModelIndex &index)
1077 {
1078 Q_Q(QListWidget);
1079 emit q->itemClicked(listModel()->at(index.row()));
1080 }
1081
_q_emitItemDoubleClicked(const QModelIndex & index)1082 void QListWidgetPrivate::_q_emitItemDoubleClicked(const QModelIndex &index)
1083 {
1084 Q_Q(QListWidget);
1085 emit q->itemDoubleClicked(listModel()->at(index.row()));
1086 }
1087
_q_emitItemActivated(const QModelIndex & index)1088 void QListWidgetPrivate::_q_emitItemActivated(const QModelIndex &index)
1089 {
1090 Q_Q(QListWidget);
1091 emit q->itemActivated(listModel()->at(index.row()));
1092 }
1093
_q_emitItemEntered(const QModelIndex & index)1094 void QListWidgetPrivate::_q_emitItemEntered(const QModelIndex &index)
1095 {
1096 Q_Q(QListWidget);
1097 emit q->itemEntered(listModel()->at(index.row()));
1098 }
1099
_q_emitItemChanged(const QModelIndex & index)1100 void QListWidgetPrivate::_q_emitItemChanged(const QModelIndex &index)
1101 {
1102 Q_Q(QListWidget);
1103 emit q->itemChanged(listModel()->at(index.row()));
1104 }
1105
_q_emitCurrentItemChanged(const QModelIndex & current,const QModelIndex & previous)1106 void QListWidgetPrivate::_q_emitCurrentItemChanged(const QModelIndex ¤t,
1107 const QModelIndex &previous)
1108 {
1109 Q_Q(QListWidget);
1110 QPersistentModelIndex persistentCurrent = current;
1111 QListWidgetItem *currentItem = listModel()->at(persistentCurrent.row());
1112 emit q->currentItemChanged(currentItem, listModel()->at(previous.row()));
1113
1114 //persistentCurrent is invalid if something changed the model in response
1115 //to the currentItemChanged signal emission and the item was removed
1116 if (!persistentCurrent.isValid()) {
1117 currentItem = 0;
1118 }
1119
1120 emit q->currentTextChanged(currentItem ? currentItem->text() : QString());
1121 emit q->currentRowChanged(persistentCurrent.row());
1122 }
1123
_q_sort()1124 void QListWidgetPrivate::_q_sort()
1125 {
1126 if (sortingEnabled)
1127 model->sort(0, sortOrder);
1128 }
1129
_q_dataChanged(const QModelIndex & topLeft,const QModelIndex & bottomRight)1130 void QListWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft,
1131 const QModelIndex &bottomRight)
1132 {
1133 if (sortingEnabled && topLeft.isValid() && bottomRight.isValid())
1134 listModel()->ensureSorted(topLeft.column(), sortOrder,
1135 topLeft.row(), bottomRight.row());
1136 }
1137
1138 /*!
1139 \class QListWidget
1140 \brief The QListWidget class provides an item-based list widget.
1141
1142 \ingroup model-view
1143
1144
1145 QListWidget is a convenience class that provides a list view similar to the
1146 one supplied by QListView, but with a classic item-based interface for
1147 adding and removing items. QListWidget uses an internal model to manage
1148 each QListWidgetItem in the list.
1149
1150 For a more flexible list view widget, use the QListView class with a
1151 standard model.
1152
1153 List widgets are constructed in the same way as other widgets:
1154
1155 \snippet doc/src/snippets/qlistwidget-using/mainwindow.cpp 0
1156
1157 The selectionMode() of a list widget determines how many of the items in
1158 the list can be selected at the same time, and whether complex selections
1159 of items can be created. This can be set with the setSelectionMode()
1160 function.
1161
1162 There are two ways to add items to the list: they can be constructed with
1163 the list widget as their parent widget, or they can be constructed with no
1164 parent widget and added to the list later. If a list widget already exists
1165 when the items are constructed, the first method is easier to use:
1166
1167 \snippet doc/src/snippets/qlistwidget-using/mainwindow.cpp 1
1168
1169 If you need to insert a new item into the list at a particular position,
1170 then it should be constructed without a parent widget. The insertItem()
1171 function should then be used to place it within the list. The list widget
1172 will take ownership of the item.
1173
1174 \snippet doc/src/snippets/qlistwidget-using/mainwindow.cpp 6
1175 \snippet doc/src/snippets/qlistwidget-using/mainwindow.cpp 7
1176
1177 For multiple items, insertItems() can be used instead. The number of items
1178 in the list is found with the count() function. To remove items from the
1179 list, use takeItem().
1180
1181 The current item in the list can be found with currentItem(), and changed
1182 with setCurrentItem(). The user can also change the current item by
1183 navigating with the keyboard or clicking on a different item. When the
1184 current item changes, the currentItemChanged() signal is emitted with the
1185 new current item and the item that was previously current.
1186
1187 \table 100%
1188 \row \o \inlineimage windowsxp-listview.png Screenshot of a Windows XP style list widget
1189 \o \inlineimage macintosh-listview.png Screenshot of a Macintosh style table widget
1190 \o \inlineimage plastique-listview.png Screenshot of a Plastique style table widget
1191 \row \o A \l{Windows XP Style Widget Gallery}{Windows XP style} list widget.
1192 \o A \l{Macintosh Style Widget Gallery}{Macintosh style} list widget.
1193 \o A \l{Plastique Style Widget Gallery}{Plastique style} list widget.
1194 \endtable
1195
1196 \sa QListWidgetItem, QListView, QTreeView, {Model/View Programming},
1197 {Config Dialog Example}
1198 */
1199
1200 /*!
1201 \fn void QListWidget::addItem(QListWidgetItem *item)
1202
1203 Inserts the \a item at the end of the list widget.
1204
1205 \warning A QListWidgetItem can only be added to a QListWidget once. Adding
1206 the same QListWidgetItem multiple times to a QListWidget will result in
1207 undefined behavior.
1208
1209 \sa insertItem()
1210 */
1211
1212 /*!
1213 \fn void QListWidget::addItem(const QString &label)
1214
1215 Inserts an item with the text \a label at the end of the list widget.
1216 */
1217
1218 /*!
1219 \fn void QListWidget::addItems(const QStringList &labels)
1220
1221 Inserts items with the text \a labels at the end of the list widget.
1222
1223 \sa insertItems()
1224 */
1225
1226 /*!
1227 \fn void QListWidget::itemPressed(QListWidgetItem *item)
1228
1229 This signal is emitted with the specified \a item when a mouse button is
1230 pressed on an item in the widget.
1231
1232 \sa itemClicked(), itemDoubleClicked()
1233 */
1234
1235 /*!
1236 \fn void QListWidget::itemClicked(QListWidgetItem *item)
1237
1238 This signal is emitted with the specified \a item when a mouse button is
1239 clicked on an item in the widget.
1240
1241 \sa itemPressed(), itemDoubleClicked()
1242 */
1243
1244 /*!
1245 \fn void QListWidget::itemDoubleClicked(QListWidgetItem *item)
1246
1247 This signal is emitted with the specified \a item when a mouse button is
1248 double clicked on an item in the widget.
1249
1250 \sa itemClicked(), itemPressed()
1251 */
1252
1253 /*!
1254 \fn void QListWidget::itemActivated(QListWidgetItem *item)
1255
1256 This signal is emitted when the \a item is activated. The \a item is
1257 activated when the user clicks or double clicks on it, depending on the
1258 system configuration. It is also activated when the user presses the
1259 activation key (on Windows and X11 this is the \gui Return key, on Mac OS
1260 X it is \key{Ctrl+0}).
1261 */
1262
1263 /*!
1264 \fn void QListWidget::itemEntered(QListWidgetItem *item)
1265
1266 This signal is emitted when the mouse cursor enters an item. The \a item is
1267 the item entered. This signal is only emitted when mouseTracking is turned
1268 on, or when a mouse button is pressed while moving into an item.
1269
1270 \sa QWidget::setMouseTracking()
1271 */
1272
1273 /*!
1274 \fn void QListWidget::itemChanged(QListWidgetItem *item)
1275
1276 This signal is emitted whenever the data of \a item has changed.
1277 */
1278
1279 /*!
1280 \fn void QListWidget::currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
1281
1282 This signal is emitted whenever the current item changes.
1283
1284 \a previous is the item that previously had the focus; \a current is the
1285 new current item.
1286 */
1287
1288 /*!
1289 \fn void QListWidget::currentTextChanged(const QString ¤tText)
1290
1291 This signal is emitted whenever the current item changes.
1292
1293 \a currentText is the text data in the current item. If there is no current
1294 item, the \a currentText is invalid.
1295 */
1296
1297 /*!
1298 \fn void QListWidget::currentRowChanged(int currentRow)
1299
1300 This signal is emitted whenever the current item changes.
1301
1302 \a currentRow is the row of the current item. If there is no current item,
1303 the \a currentRow is -1.
1304 */
1305
1306 /*!
1307 \fn void QListWidget::itemSelectionChanged()
1308
1309 This signal is emitted whenever the selection changes.
1310
1311 \sa selectedItems(), QListWidgetItem::isSelected(), currentItemChanged()
1312 */
1313
1314 /*!
1315 \since 4.3
1316
1317 \fn void QListWidget::removeItemWidget(QListWidgetItem *item)
1318
1319 Removes the widget set on the given \a item.
1320 */
1321
1322 /*!
1323 Constructs an empty QListWidget with the given \a parent.
1324 */
1325
QListWidget(QWidget * parent)1326 QListWidget::QListWidget(QWidget *parent)
1327 : QListView(*new QListWidgetPrivate(), parent)
1328 {
1329 Q_D(QListWidget);
1330 d->setup();
1331 }
1332
1333 /*!
1334 Destroys the list widget and all its items.
1335 */
1336
~QListWidget()1337 QListWidget::~QListWidget()
1338 {
1339 }
1340
1341 /*!
1342 Returns the item that occupies the given \a row in the list if one has been
1343 set; otherwise returns 0.
1344
1345 \sa row()
1346 */
1347
item(int row) const1348 QListWidgetItem *QListWidget::item(int row) const
1349 {
1350 Q_D(const QListWidget);
1351 if (row < 0 || row >= d->model->rowCount())
1352 return 0;
1353 return d->listModel()->at(row);
1354 }
1355
1356 /*!
1357 Returns the row containing the given \a item.
1358
1359 \sa item()
1360 */
1361
row(const QListWidgetItem * item) const1362 int QListWidget::row(const QListWidgetItem *item) const
1363 {
1364 Q_D(const QListWidget);
1365 return d->listModel()->index(const_cast<QListWidgetItem*>(item)).row();
1366 }
1367
1368
1369 /*!
1370 Inserts the \a item at the position in the list given by \a row.
1371
1372 \sa addItem()
1373 */
1374
insertItem(int row,QListWidgetItem * item)1375 void QListWidget::insertItem(int row, QListWidgetItem *item)
1376 {
1377 Q_D(QListWidget);
1378 if (item && !item->view)
1379 d->listModel()->insert(row, item);
1380 }
1381
1382 /*!
1383 Inserts an item with the text \a label in the list widget at the position
1384 given by \a row.
1385
1386 \sa addItem()
1387 */
1388
insertItem(int row,const QString & label)1389 void QListWidget::insertItem(int row, const QString &label)
1390 {
1391 Q_D(QListWidget);
1392 d->listModel()->insert(row, new QListWidgetItem(label));
1393 }
1394
1395 /*!
1396 Inserts items from the list of \a labels into the list, starting at the
1397 given \a row.
1398
1399 \sa insertItem(), addItem()
1400 */
1401
insertItems(int row,const QStringList & labels)1402 void QListWidget::insertItems(int row, const QStringList &labels)
1403 {
1404 Q_D(QListWidget);
1405 d->listModel()->insert(row, labels);
1406 }
1407
1408 /*!
1409 Removes and returns the item from the given \a row in the list widget;
1410 otherwise returns 0.
1411
1412 Items removed from a list widget will not be managed by Qt, and will need
1413 to be deleted manually.
1414
1415 \sa insertItem(), addItem()
1416 */
1417
takeItem(int row)1418 QListWidgetItem *QListWidget::takeItem(int row)
1419 {
1420 Q_D(QListWidget);
1421 if (row < 0 || row >= d->model->rowCount())
1422 return 0;
1423 return d->listModel()->take(row);
1424 }
1425
1426 /*!
1427 \property QListWidget::count
1428 \brief the number of items in the list including any hidden items.
1429 */
1430
count() const1431 int QListWidget::count() const
1432 {
1433 Q_D(const QListWidget);
1434 return d->model->rowCount();
1435 }
1436
1437 /*!
1438 Returns the current item.
1439 */
currentItem() const1440 QListWidgetItem *QListWidget::currentItem() const
1441 {
1442 Q_D(const QListWidget);
1443 return d->listModel()->at(currentIndex().row());
1444 }
1445
1446
1447 /*!
1448 Sets the current item to \a item.
1449
1450 Unless the selection mode is \l{QAbstractItemView::}{NoSelection},
1451 the item is also be selected.
1452 */
setCurrentItem(QListWidgetItem * item)1453 void QListWidget::setCurrentItem(QListWidgetItem *item)
1454 {
1455 setCurrentRow(row(item));
1456 }
1457
1458 /*!
1459 \since 4.4
1460 Set the current item to \a item, using the given \a command.
1461 */
setCurrentItem(QListWidgetItem * item,QItemSelectionModel::SelectionFlags command)1462 void QListWidget::setCurrentItem(QListWidgetItem *item, QItemSelectionModel::SelectionFlags command)
1463 {
1464 setCurrentRow(row(item), command);
1465 }
1466
1467 /*!
1468 \property QListWidget::currentRow
1469 \brief the row of the current item.
1470
1471 Depending on the current selection mode, the row may also be selected.
1472 */
1473
currentRow() const1474 int QListWidget::currentRow() const
1475 {
1476 return currentIndex().row();
1477 }
1478
setCurrentRow(int row)1479 void QListWidget::setCurrentRow(int row)
1480 {
1481 Q_D(QListWidget);
1482 QModelIndex index = d->listModel()->index(row);
1483 if (d->selectionMode == SingleSelection)
1484 selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect);
1485 else if (d->selectionMode == NoSelection)
1486 selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
1487 else
1488 selectionModel()->setCurrentIndex(index, QItemSelectionModel::SelectCurrent);
1489 }
1490
1491 /*!
1492 \since 4.4
1493
1494 Sets the current row to be the given \a row, using the given \a command,
1495 */
setCurrentRow(int row,QItemSelectionModel::SelectionFlags command)1496 void QListWidget::setCurrentRow(int row, QItemSelectionModel::SelectionFlags command)
1497 {
1498 Q_D(QListWidget);
1499 d->selectionModel->setCurrentIndex(d->listModel()->index(row), command);
1500 }
1501
1502 /*!
1503 Returns a pointer to the item at the coordinates \a p. The coordinates
1504 are relative to the list widget's \l{QAbstractScrollArea::}{viewport()}.
1505
1506 */
itemAt(const QPoint & p) const1507 QListWidgetItem *QListWidget::itemAt(const QPoint &p) const
1508 {
1509 Q_D(const QListWidget);
1510 return d->listModel()->at(indexAt(p).row());
1511
1512 }
1513
1514 /*!
1515 \fn QListWidgetItem *QListWidget::itemAt(int x, int y) const
1516 \overload
1517
1518 Returns a pointer to the item at the coordinates (\a x, \a y).
1519 The coordinates are relative to the list widget's
1520 \l{QAbstractScrollArea::}{viewport()}.
1521
1522 */
1523
1524
1525 /*!
1526 Returns the rectangle on the viewport occupied by the item at \a item.
1527 */
visualItemRect(const QListWidgetItem * item) const1528 QRect QListWidget::visualItemRect(const QListWidgetItem *item) const
1529 {
1530 Q_D(const QListWidget);
1531 QModelIndex index = d->listModel()->index(const_cast<QListWidgetItem*>(item));
1532 return visualRect(index);
1533 }
1534
1535 /*!
1536 Sorts all the items in the list widget according to the specified \a order.
1537 */
sortItems(Qt::SortOrder order)1538 void QListWidget::sortItems(Qt::SortOrder order)
1539 {
1540 Q_D(QListWidget);
1541 d->sortOrder = order;
1542 d->listModel()->sort(0, order);
1543 }
1544
1545 /*!
1546 \since 4.2
1547 \property QListWidget::sortingEnabled
1548 \brief whether sorting is enabled
1549
1550 If this property is true, sorting is enabled for the list; if the property
1551 is false, sorting is not enabled.
1552
1553 The default value is false.
1554 */
setSortingEnabled(bool enable)1555 void QListWidget::setSortingEnabled(bool enable)
1556 {
1557 Q_D(QListWidget);
1558 d->sortingEnabled = enable;
1559 }
1560
isSortingEnabled() const1561 bool QListWidget::isSortingEnabled() const
1562 {
1563 Q_D(const QListWidget);
1564 return d->sortingEnabled;
1565 }
1566
1567 /*!
1568 \internal
1569 */
sortOrder() const1570 Qt::SortOrder QListWidget::sortOrder() const
1571 {
1572 Q_D(const QListWidget);
1573 return d->sortOrder;
1574 }
1575
1576 /*!
1577 Starts editing the \a item if it is editable.
1578 */
1579
editItem(QListWidgetItem * item)1580 void QListWidget::editItem(QListWidgetItem *item)
1581 {
1582 Q_D(QListWidget);
1583 edit(d->listModel()->index(item));
1584 }
1585
1586 /*!
1587 Opens an editor for the given \a item. The editor remains open after
1588 editing.
1589
1590 \sa closePersistentEditor()
1591 */
openPersistentEditor(QListWidgetItem * item)1592 void QListWidget::openPersistentEditor(QListWidgetItem *item)
1593 {
1594 Q_D(QListWidget);
1595 QModelIndex index = d->listModel()->index(item);
1596 QAbstractItemView::openPersistentEditor(index);
1597 }
1598
1599 /*!
1600 Closes the persistent editor for the given \a item.
1601
1602 \sa openPersistentEditor()
1603 */
closePersistentEditor(QListWidgetItem * item)1604 void QListWidget::closePersistentEditor(QListWidgetItem *item)
1605 {
1606 Q_D(QListWidget);
1607 QModelIndex index = d->listModel()->index(item);
1608 QAbstractItemView::closePersistentEditor(index);
1609 }
1610
1611 /*!
1612 \since 4.1
1613
1614 Returns the widget displayed in the given \a item.
1615 */
itemWidget(QListWidgetItem * item) const1616 QWidget *QListWidget::itemWidget(QListWidgetItem *item) const
1617 {
1618 Q_D(const QListWidget);
1619 QModelIndex index = d->listModel()->index(item);
1620 return QAbstractItemView::indexWidget(index);
1621 }
1622
1623 /*!
1624 \since 4.1
1625
1626 Sets the \a widget to be displayed in the give \a item.
1627
1628 This function should only be used to display static content in the place of
1629 a list widget item. If you want to display custom dynamic content or
1630 implement a custom editor widget, use QListView and subclass QItemDelegate
1631 instead.
1632
1633 \sa {Delegate Classes}
1634 */
setItemWidget(QListWidgetItem * item,QWidget * widget)1635 void QListWidget::setItemWidget(QListWidgetItem *item, QWidget *widget)
1636 {
1637 Q_D(QListWidget);
1638 QModelIndex index = d->listModel()->index(item);
1639 QAbstractItemView::setIndexWidget(index, widget);
1640 }
1641
1642 /*!
1643 Returns true if \a item is selected; otherwise returns false.
1644
1645 \obsolete
1646
1647 This function is deprecated. Use QListWidgetItem::isSelected() instead.
1648 */
isItemSelected(const QListWidgetItem * item) const1649 bool QListWidget::isItemSelected(const QListWidgetItem *item) const
1650 {
1651 Q_D(const QListWidget);
1652 QModelIndex index = d->listModel()->index(const_cast<QListWidgetItem*>(item));
1653 return selectionModel()->isSelected(index);
1654 }
1655
1656 /*!
1657 Selects or deselects the given \a item depending on whether \a select is
1658 true of false.
1659
1660 \obsolete
1661
1662 This function is deprecated. Use QListWidgetItem::setSelected() instead.
1663 */
setItemSelected(const QListWidgetItem * item,bool select)1664 void QListWidget::setItemSelected(const QListWidgetItem *item, bool select)
1665 {
1666 Q_D(QListWidget);
1667 QModelIndex index = d->listModel()->index(const_cast<QListWidgetItem*>(item));
1668
1669 if (d->selectionMode == SingleSelection) {
1670 selectionModel()->select(index, select
1671 ? QItemSelectionModel::ClearAndSelect
1672 : QItemSelectionModel::Deselect);
1673 } else if (d->selectionMode != NoSelection) {
1674 selectionModel()->select(index, select
1675 ? QItemSelectionModel::Select
1676 : QItemSelectionModel::Deselect);
1677 }
1678
1679 }
1680
1681 /*!
1682 Returns a list of all selected items in the list widget.
1683 */
1684
selectedItems() const1685 QList<QListWidgetItem*> QListWidget::selectedItems() const
1686 {
1687 Q_D(const QListWidget);
1688 QModelIndexList indexes = selectionModel()->selectedIndexes();
1689 QList<QListWidgetItem*> items;
1690 for (int i = 0; i < indexes.count(); ++i)
1691 items.append(d->listModel()->at(indexes.at(i).row()));
1692 return items;
1693 }
1694
1695 /*!
1696 Finds items with the text that matches the string \a text using the given
1697 \a flags.
1698 */
1699
findItems(const QString & text,Qt::MatchFlags flags) const1700 QList<QListWidgetItem*> QListWidget::findItems(const QString &text, Qt::MatchFlags flags) const
1701 {
1702 Q_D(const QListWidget);
1703 QModelIndexList indexes = d->listModel()->match(model()->index(0, 0, QModelIndex()),
1704 Qt::DisplayRole, text, -1, flags);
1705 QList<QListWidgetItem*> items;
1706 for (int i = 0; i < indexes.size(); ++i)
1707 items.append(d->listModel()->at(indexes.at(i).row()));
1708 return items;
1709 }
1710
1711 /*!
1712 Returns true if the \a item is explicitly hidden; otherwise returns false.
1713
1714 \obsolete
1715
1716 This function is deprecated. Use QListWidgetItem::isHidden() instead.
1717 */
isItemHidden(const QListWidgetItem * item) const1718 bool QListWidget::isItemHidden(const QListWidgetItem *item) const
1719 {
1720 return isRowHidden(row(item));
1721 }
1722
1723 /*!
1724 If \a hide is true, the \a item will be hidden; otherwise it will be shown.
1725
1726 \obsolete
1727
1728 This function is deprecated. Use QListWidgetItem::setHidden() instead.
1729 */
setItemHidden(const QListWidgetItem * item,bool hide)1730 void QListWidget::setItemHidden(const QListWidgetItem *item, bool hide)
1731 {
1732 setRowHidden(row(item), hide);
1733 }
1734
1735 /*!
1736 Scrolls the view if necessary to ensure that the \a item is visible.
1737
1738 \a hint specifies where the \a item should be located after the operation.
1739 */
1740
scrollToItem(const QListWidgetItem * item,QAbstractItemView::ScrollHint hint)1741 void QListWidget::scrollToItem(const QListWidgetItem *item, QAbstractItemView::ScrollHint hint)
1742 {
1743 Q_D(QListWidget);
1744 QModelIndex index = d->listModel()->index(const_cast<QListWidgetItem*>(item));
1745 QListView::scrollTo(index, hint);
1746 }
1747
1748 /*!
1749 Removes all items and selections in the view.
1750
1751 \warning All items will be permanently deleted.
1752 */
clear()1753 void QListWidget::clear()
1754 {
1755 Q_D(QListWidget);
1756 selectionModel()->clear();
1757 d->listModel()->clear();
1758 }
1759
1760 /*!
1761 Returns a list of MIME types that can be used to describe a list of
1762 listwidget items.
1763
1764 \sa mimeData()
1765 */
mimeTypes() const1766 QStringList QListWidget::mimeTypes() const
1767 {
1768 return d_func()->listModel()->QAbstractListModel::mimeTypes();
1769 }
1770
1771 /*!
1772 Returns an object that contains a serialized description of the specified
1773 \a items. The format used to describe the items is obtained from the
1774 mimeTypes() function.
1775
1776 If the list of items is empty, 0 is returned instead of a serialized empty
1777 list.
1778 */
mimeData(const QList<QListWidgetItem * >) const1779 QMimeData *QListWidget::mimeData(const QList<QListWidgetItem*>) const
1780 {
1781 return d_func()->listModel()->internalMimeData();
1782 }
1783
1784 #ifndef QT_NO_DRAGANDDROP
1785 /*!
1786 Handles \a data supplied by an external drag and drop operation that ended
1787 with the given \a action in the given \a index. Returns true if \a data and
1788 \a action can be handled by the model; otherwise returns false.
1789
1790 \sa supportedDropActions()
1791 */
dropMimeData(int index,const QMimeData * data,Qt::DropAction action)1792 bool QListWidget::dropMimeData(int index, const QMimeData *data, Qt::DropAction action)
1793 {
1794 QModelIndex idx;
1795 int row = index;
1796 int column = 0;
1797 if (dropIndicatorPosition() == QAbstractItemView::OnItem) {
1798 // QAbstractListModel::dropMimeData will overwrite on the index if row == -1 and column == -1
1799 idx = model()->index(row, column);
1800 row = -1;
1801 column = -1;
1802 }
1803 return d_func()->listModel()->QAbstractListModel::dropMimeData(data, action , row, column, idx);
1804 }
1805
1806 /*! \reimp */
dropEvent(QDropEvent * event)1807 void QListWidget::dropEvent(QDropEvent *event) {
1808 Q_D(QListWidget);
1809 if (event->source() == this && d->movement != Static) {
1810 QListView::dropEvent(event);
1811 return;
1812 }
1813
1814 if (event->source() == this && (event->dropAction() == Qt::MoveAction ||
1815 dragDropMode() == QAbstractItemView::InternalMove)) {
1816 QModelIndex topIndex;
1817 int col = -1;
1818 int row = -1;
1819 if (d->dropOn(event, &row, &col, &topIndex)) {
1820 QList<QModelIndex> selIndexes = selectedIndexes();
1821 QList<QPersistentModelIndex> persIndexes;
1822 for (int i = 0; i < selIndexes.count(); i++)
1823 persIndexes.append(selIndexes.at(i));
1824
1825 if (persIndexes.contains(topIndex))
1826 return;
1827 qSort(persIndexes); // The dropped items will remain in the same visual order.
1828
1829 QPersistentModelIndex dropRow = model()->index(row, col, topIndex);
1830
1831 int r = row == -1 ? count() : (dropRow.row() >= 0 ? dropRow.row() : row);
1832 for (int i = 0; i < persIndexes.count(); ++i) {
1833 const QPersistentModelIndex &pIndex = persIndexes.at(i);
1834 d->listModel()->move(pIndex.row(), r);
1835 r = pIndex.row() + 1; // Dropped items are inserted contiguously and in the right order.
1836 }
1837
1838 event->accept();
1839 // Don't want QAbstractItemView to delete it because it was "moved" we already did it
1840 event->setDropAction(Qt::CopyAction);
1841 }
1842 }
1843
1844 QListView::dropEvent(event);
1845 }
1846
1847 /*!
1848 Returns the drop actions supported by this view.
1849
1850 \sa Qt::DropActions
1851 */
supportedDropActions() const1852 Qt::DropActions QListWidget::supportedDropActions() const
1853 {
1854 Q_D(const QListWidget);
1855 return d->listModel()->QAbstractListModel::supportedDropActions() | Qt::MoveAction;
1856 }
1857 #endif // QT_NO_DRAGANDDROP
1858
1859 /*!
1860 Returns a list of pointers to the items contained in the \a data object. If
1861 the object was not created by a QListWidget in the same process, the list
1862 is empty.
1863 */
items(const QMimeData * data) const1864 QList<QListWidgetItem*> QListWidget::items(const QMimeData *data) const
1865 {
1866 const QListWidgetMimeData *lwd = qobject_cast<const QListWidgetMimeData*>(data);
1867 if (lwd)
1868 return lwd->items;
1869 return QList<QListWidgetItem*>();
1870 }
1871
1872 /*!
1873 Returns the QModelIndex assocated with the given \a item.
1874 */
1875
indexFromItem(QListWidgetItem * item) const1876 QModelIndex QListWidget::indexFromItem(QListWidgetItem *item) const
1877 {
1878 Q_D(const QListWidget);
1879 return d->listModel()->index(item);
1880 }
1881
1882 /*!
1883 Returns a pointer to the QListWidgetItem assocated with the given \a index.
1884 */
1885
itemFromIndex(const QModelIndex & index) const1886 QListWidgetItem *QListWidget::itemFromIndex(const QModelIndex &index) const
1887 {
1888 Q_D(const QListWidget);
1889 if (d->isIndexValid(index))
1890 return d->listModel()->at(index.row());
1891 return 0;
1892 }
1893
1894 /*!
1895 \internal
1896 */
setModel(QAbstractItemModel *)1897 void QListWidget::setModel(QAbstractItemModel * /*model*/)
1898 {
1899 Q_ASSERT(!"QListWidget::setModel() - Changing the model of the QListWidget is not allowed.");
1900 }
1901
1902 /*!
1903 \reimp
1904 */
event(QEvent * e)1905 bool QListWidget::event(QEvent *e)
1906 {
1907 return QListView::event(e);
1908 }
1909
1910 QT_END_NAMESPACE
1911
1912 #include "moc_qlistwidget.cpp"
1913
1914 #endif // QT_NO_LISTWIDGET
1915