Emit layout change hint from QStringListModel.
[profile/ivi/qtbase.git] / src / corelib / itemmodels / qstringlistmodel.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
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 Digia.  For licensing terms and
14 ** conditions see http://qt.digia.com/licensing.  For further information
15 ** use the contact form at http://qt.digia.com/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 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights.  These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file.  Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 /*
43     A simple model that uses a QStringList as its data source.
44 */
45
46 #include "qstringlistmodel.h"
47
48 #include <QtCore/qvector.h>
49
50 #ifndef QT_NO_STRINGLISTMODEL
51
52 QT_BEGIN_NAMESPACE
53
54 /*!
55     \class QStringListModel
56     \inmodule QtCore
57     \brief The QStringListModel class provides a model that supplies strings to views.
58
59     \ingroup model-view
60
61     QStringListModel is an editable model that can be used for simple
62     cases where you need to display a number of strings in a view
63     widget, such as a QListView or a QComboBox.
64
65     The model provides all the standard functions of an editable
66     model, representing the data in the string list as a model with
67     one column and a number of rows equal to the number of items in
68     the list.
69
70     Model indexes corresponding to items are obtained with the
71     \l{QAbstractListModel::index()}{index()} function, and item flags
72     are obtained with flags().  Item data is read with the data()
73     function and written with setData().  The number of rows (and
74     number of items in the string list) can be found with the
75     rowCount() function.
76
77     The model can be constructed with an existing string list, or
78     strings can be set later with the setStringList() convenience
79     function. Strings can also be inserted in the usual way with the
80     insertRows() function, and removed with removeRows(). The contents
81     of the string list can be retrieved with the stringList()
82     convenience function.
83
84     An example usage of QStringListModel:
85
86     \snippet qstringlistmodel/main.cpp 0
87
88     \sa QAbstractListModel, QAbstractItemModel, {Model Classes}
89 */
90
91 /*!
92     Constructs a string list model with the given \a parent.
93 */
94
95 QStringListModel::QStringListModel(QObject *parent)
96     : QAbstractListModel(parent)
97 {
98 }
99
100 /*!
101     Constructs a string list model containing the specified \a strings
102     with the given \a parent.
103 */
104
105 QStringListModel::QStringListModel(const QStringList &strings, QObject *parent)
106     : QAbstractListModel(parent), lst(strings)
107 {
108 }
109
110 /*!
111     Returns the number of rows in the model. This value corresponds to the
112     number of items in the model's internal string list.
113
114     The optional \a parent argument is in most models used to specify
115     the parent of the rows to be counted. Because this is a list if a
116     valid parent is specified, the result will always be 0.
117
118     \sa insertRows(), removeRows(), QAbstractItemModel::rowCount()
119 */
120
121 int QStringListModel::rowCount(const QModelIndex &parent) const
122 {
123     if (parent.isValid())
124         return 0;
125
126     return lst.count();
127 }
128
129 /*!
130     Returns data for the specified \a role, from the item with the
131     given \a index.
132
133     If the view requests an invalid index, an invalid variant is returned.
134
135     \sa setData()
136 */
137
138 QVariant QStringListModel::data(const QModelIndex &index, int role) const
139 {
140     if (index.row() < 0 || index.row() >= lst.size())
141         return QVariant();
142
143     if (role == Qt::DisplayRole || role == Qt::EditRole)
144         return lst.at(index.row());
145
146     return QVariant();
147 }
148
149 /*!
150     Returns the flags for the item with the given \a index.
151
152     Valid items are enabled, selectable, editable, drag enabled and drop enabled.
153
154     \sa QAbstractItemModel::flags()
155 */
156
157 Qt::ItemFlags QStringListModel::flags(const QModelIndex &index) const
158 {
159     if (!index.isValid())
160         return QAbstractItemModel::flags(index) | Qt::ItemIsDropEnabled;
161
162     return QAbstractItemModel::flags(index) | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
163 }
164
165 /*!
166     Sets the data for the specified \a role in the item with the given
167     \a index in the model, to the provided \a value.
168
169     The dataChanged() signal is emitted if the item is changed.
170
171     \sa Qt::ItemDataRole, data()
172 */
173
174 bool QStringListModel::setData(const QModelIndex &index, const QVariant &value, int role)
175 {
176     if (index.row() >= 0 && index.row() < lst.size()
177         && (role == Qt::EditRole || role == Qt::DisplayRole)) {
178         lst.replace(index.row(), value.toString());
179         emit dataChanged(index, index);
180         return true;
181     }
182     return false;
183 }
184
185 /*!
186     Inserts \a count rows into the model, beginning at the given \a row.
187
188     The \a parent index of the rows is optional and is only used for
189     consistency with QAbstractItemModel. By default, a null index is
190     specified, indicating that the rows are inserted in the top level of
191     the model.
192
193     \sa QAbstractItemModel::insertRows()
194 */
195
196 bool QStringListModel::insertRows(int row, int count, const QModelIndex &parent)
197 {
198     if (count < 1 || row < 0 || row > rowCount(parent))
199         return false;
200
201     beginInsertRows(QModelIndex(), row, row + count - 1);
202
203     for (int r = 0; r < count; ++r)
204         lst.insert(row, QString());
205
206     endInsertRows();
207
208     return true;
209 }
210
211 /*!
212     Removes \a count rows from the model, beginning at the given \a row.
213
214     The \a parent index of the rows is optional and is only used for
215     consistency with QAbstractItemModel. By default, a null index is
216     specified, indicating that the rows are removed in the top level of
217     the model.
218
219     \sa QAbstractItemModel::removeRows()
220 */
221
222 bool QStringListModel::removeRows(int row, int count, const QModelIndex &parent)
223 {
224     if (count <= 0 || row < 0 || (row + count) > rowCount(parent))
225         return false;
226
227     beginRemoveRows(QModelIndex(), row, row + count - 1);
228
229     for (int r = 0; r < count; ++r)
230         lst.removeAt(row);
231
232     endRemoveRows();
233
234     return true;
235 }
236
237 static bool ascendingLessThan(const QPair<QString, int> &s1, const QPair<QString, int> &s2)
238 {
239     return s1.first < s2.first;
240 }
241
242 static bool decendingLessThan(const QPair<QString, int> &s1, const QPair<QString, int> &s2)
243 {
244     return s1.first > s2.first;
245 }
246
247 /*!
248   \reimp
249 */
250 void QStringListModel::sort(int, Qt::SortOrder order)
251 {
252     emit layoutAboutToBeChanged(QList<QPersistentModelIndex>(), VerticalSortHint);
253
254     QList<QPair<QString, int> > list;
255     for (int i = 0; i < lst.count(); ++i)
256         list.append(QPair<QString, int>(lst.at(i), i));
257
258     if (order == Qt::AscendingOrder)
259         qSort(list.begin(), list.end(), ascendingLessThan);
260     else
261         qSort(list.begin(), list.end(), decendingLessThan);
262
263     lst.clear();
264     QVector<int> forwarding(list.count());
265     for (int i = 0; i < list.count(); ++i) {
266         lst.append(list.at(i).first);
267         forwarding[list.at(i).second] = i;
268     }
269
270     QModelIndexList oldList = persistentIndexList();
271     QModelIndexList newList;
272     for (int i = 0; i < oldList.count(); ++i)
273         newList.append(index(forwarding.at(oldList.at(i).row()), 0));
274     changePersistentIndexList(oldList, newList);
275
276     emit layoutChanged(QList<QPersistentModelIndex>(), VerticalSortHint);
277 }
278
279 /*!
280     Returns the string list used by the model to store data.
281 */
282 QStringList QStringListModel::stringList() const
283 {
284     return lst;
285 }
286
287 /*!
288     Sets the model's internal string list to \a strings. The model will
289     notify any attached views that its underlying data has changed.
290
291     \sa dataChanged()
292 */
293 void QStringListModel::setStringList(const QStringList &strings)
294 {
295     emit beginResetModel();
296     lst = strings;
297     emit endResetModel();
298 }
299
300 /*!
301   \reimp
302 */
303 Qt::DropActions QStringListModel::supportedDropActions() const
304 {
305     return QAbstractItemModel::supportedDropActions() | Qt::MoveAction;
306 }
307
308 QT_END_NAMESPACE
309
310 #endif // QT_NO_STRINGLISTMODEL