Ok, the long awaited config wizard is here (at least in a very basic state). There...
[quassel.git] / src / contrib / libqxt-2007-10-24 / src / gui / qxtstringvalidator.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) Qxt Foundation. Some rights reserved.
4 **
5 ** This file is part of the QxtGui module of the Qt eXTension library
6 **
7 ** This library is free software; you can redistribute it and/or modify it
8 ** under the terms of th Common Public License, version 1.0, as published by
9 ** IBM.
10 **
11 ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
12 ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
13 ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
14 ** FITNESS FOR A PARTICULAR PURPOSE.
15 **
16 ** You should have received a copy of the CPL along with this file.
17 ** See the LICENSE file and the cpl1.0.txt file included with the source
18 ** distribution for more information. If you did not receive a copy of the
19 ** license, contact the Qxt Foundation.
20 **
21 ** <http://libqxt.sourceforge.net>  <foundation@libqxt.org>
22 **
23 ****************************************************************************/
24
25 #include "qxtstringvalidator.h"
26 #include "qxtstringvalidator_p.h"
27
28 #include <QDebug>
29 #include <QAbstractItemModel>
30 #include <QStringListModel>
31 #include <QFlags>
32
33 QxtStringValidatorPrivate::QxtStringValidatorPrivate() : isUserModel(false)
34         , model(0)
35         , cs(Qt::CaseSensitive)
36         , lookupRole(Qt::EditRole)
37         , userFlags(Qt::MatchWrap)
38         , lookupStartModelIndex(QModelIndex())
39 {}
40
41 QModelIndex QxtStringValidatorPrivate::lookupPartialMatch(const QString &value) const
42 {
43     Qt::MatchFlags matchFlags = Qt::MatchStartsWith| userFlags;
44     if (cs == Qt::CaseSensitive)
45         matchFlags |= Qt::MatchCaseSensitive;
46
47     return lookup(value,matchFlags);
48 }
49
50 QModelIndex QxtStringValidatorPrivate::lookupExactMatch(const QString &value) const
51 {
52     Qt::MatchFlags  matchFlags = Qt::MatchFixedString | userFlags;
53     if (cs == Qt::CaseSensitive)
54         matchFlags |= Qt::MatchCaseSensitive;
55
56     return lookup(value,matchFlags);
57 }
58
59 QModelIndex QxtStringValidatorPrivate::lookup(const QString &value,const Qt::MatchFlags  &matchFlags) const
60 {
61     QModelIndex startIndex =  lookupStartModelIndex.isValid() ? lookupStartModelIndex : model->index(0,0);
62
63     QModelIndexList list = model->match(startIndex,lookupRole,value,1,matchFlags);
64
65     if (list.size() > 0)
66         return list[0];
67     return QModelIndex();
68 }
69
70
71 /*!
72     \class QxtStringValidator QxtStringValidator
73     \ingroup QxtGui
74     \brief The QxtStringValidator class provides validation on a QStringList or a QAbstractItemModel
75
76     It provides a String based validation in a stringlist or a custom model.
77     QxtStringValidator uses QAbstractItemModel::match() to validate the input.
78     For a partial match it returns QValidator::Intermediate and for a full match QValidator::Acceptable.
79
80     Example usage:
81     \code
82
83     QLineEdit * testLineEdit = new QLineEdit();
84
85     QStringList testList;
86     testList << "StringTestString" << "sTrInGCaSe"<< "StringTest"<< "String"<< "Foobar"<< "BarFoo"<< "QxtLib";
87
88     QxtStringValidator *validator = new QxtStringValidator(ui.lineEdit);
89     validator->setStringList(testList);
90
91     //change lookup case sensitivity
92     validator->setCaseSensitivity(Qt::CaseInsensitive);
93
94     testLineEdit->setValidator(validator);
95
96     \endcode
97  */
98
99 /*!
100     Constructs a validator object with a parent object that accepts any string in the stringlist.
101 */
102 QxtStringValidator::QxtStringValidator(QObject * parent) : QValidator(parent)
103 {
104     QXT_INIT_PRIVATE(QxtStringValidator);
105 }
106
107 QxtStringValidator::~QxtStringValidator(void)
108 {}
109
110 /*!
111     Fixes up the string input if there is no exact match in the stringlist/model.
112     The first match in the stringlist/model is used to fix the input.
113 */
114 void QxtStringValidator::fixup ( QString & input ) const
115 {
116     qDebug()<<"Fixup called";
117
118     if (!qxt_d().model)
119         return;
120
121     if (qxt_d().lookupExactMatch(input).isValid())
122         return;
123
124     QModelIndex partialMatch = qxt_d().lookupPartialMatch(input);
125     if (partialMatch.isValid())
126         input = partialMatch.data(qxt_d().lookupRole).toString();
127
128 }
129
130 /*!
131     uses stringlist as new validation list
132     if a model was set before it is not deleted
133 */
134 void QxtStringValidator::setStringList(const QStringList &stringList)
135 {
136     //delete model only if it is a model created by us
137     if (qxt_d().model && !qxt_d().isUserModel)
138     {
139         delete qxt_d().model;
140         qxt_d().model = 0;
141     }
142
143     qxt_d().isUserModel = false;
144     qxt_d().lookupStartModelIndex = QModelIndex();
145     qxt_d().lookupRole = Qt::EditRole;
146     qxt_d().model = new QStringListModel(stringList,this);
147 }
148
149 /*!
150     Returns Acceptable if the string input matches a item in the stringlist.
151     Returns Intermediate if the string input matches a item in the stringlist partial or if input is empty.
152     Returns Invalid otherwise.
153
154     Note: A partial match means the beginning of the strings are matching:
155         qxtL matches qxtLib but not testqxtLib
156 */
157 QValidator::State QxtStringValidator::validate ( QString & input, int & pos ) const
158 {
159     Q_UNUSED(pos);
160
161     // no model or a empty model has only Acceptable values (like no validator was set)
162     if (!qxt_d().model)
163         return QValidator::Acceptable;
164
165     if (qxt_d().model->rowCount() == 0)
166         return QValidator::Acceptable;
167
168     if (input.isEmpty())
169         return QValidator::Intermediate;
170
171     if (qxt_d().lookupExactMatch(input).isValid())
172     {
173         qDebug()<<input<<" is QValidator::Acceptable";
174         return QValidator::Acceptable;
175     }
176
177     if (qxt_d().lookupPartialMatch(input).isValid())
178     {
179         qDebug()<<input<<" is QValidator::Intermediate";
180         return QValidator::Intermediate;
181     }
182
183     qDebug()<<input<<" is QValidator::Invalid";
184     return QValidator::Invalid;
185 }
186
187
188 /*!
189     Returns the startModelIndex.
190     Note: The return value will only we valid if the user has set the model with setLookupModel().
191     \sa setStartModelIndex()
192 */
193 QModelIndex QxtStringValidator::startModelIndex() const
194 {
195     if (qxt_d().isUserModel && qxt_d().model)
196     {
197         if (qxt_d().lookupStartModelIndex.isValid())
198             return qxt_d().lookupStartModelIndex;
199         else
200             return qxt_d().model->index(0,0);
201     }
202     return QModelIndex();
203 }
204
205 /*!
206     Returns if recursive lookup is enabled.
207     \sa setRecursiveLookup()
208 */
209 bool QxtStringValidator::recursiveLookup() const
210 {
211     if (qxt_d().userFlags & Qt::MatchRecursive)
212         return true;
213     return false;
214 }
215
216 /*!
217     Returns if wrapping lookup is enabled.
218     \sa setWrappingLookup()
219 */
220 bool QxtStringValidator::wrappingLookup() const
221 {
222     if (qxt_d().userFlags & Qt::MatchWrap)
223         return true;
224     return false;
225 }
226
227 /*!
228     Returns the used model if it was set by the user.
229     \sa setLookupModel()
230 */
231 QAbstractItemModel * QxtStringValidator::lookupModel() const
232 {
233     if (qxt_d().isUserModel)
234         return qxt_d().model;
235     return 0;
236 }
237
238 /*!
239     Returns Qt::CaseSensitive if the QxtStringValidator is matched case sensitively; otherwise returns Qt::CaseInsensitive.
240     \sa setCaseSensitivity().
241 */
242 Qt::CaseSensitivity QxtStringValidator::caseSensitivity () const
243 {
244     return qxt_d().cs;
245 }
246
247 /*!
248     Sets case sensitive matching to cs.
249     If cs is Qt::CaseSensitive, inp matches input but not INPUT.
250     The default is Qt::CaseSensitive.
251     \sa caseSensitivity().
252 */
253 void QxtStringValidator::setCaseSensitivity ( Qt::CaseSensitivity caseSensitivity )
254 {
255     qxt_d().cs = caseSensitivity;
256 }
257
258 /*!
259     Sets the index the search should start at
260     The default is QModelIndex(0,0).
261     Note: this is set to default when the model changes.
262     Changing the startModelIndex is only possible if the validator uses a userdefined model
263        and the modelindex comes from the used model
264     \sa startModelIndex()
265 */
266 void QxtStringValidator::setStartModelIndex(const QModelIndex &index)
267 {
268     if (index.model() == qxt_d().model)
269         qxt_d().lookupStartModelIndex = index;
270     else
271         qWarning()<<"ModelIndex from different model. Ignoring.";
272 }
273
274 /*!
275     If enabled QxtStringValidator searches the entire hierarchy of the model.
276     This is disabled by default.
277     \sa recursiveLookup()
278 */
279 void QxtStringValidator::setRecursiveLookup(bool enable)
280 {
281     if (enable)
282         qxt_d().userFlags |= Qt::MatchRecursive;
283     else
284         qxt_d().userFlags &= ~Qt::MatchRecursive;
285
286 }
287
288 /*!
289     If enabled QxtStringValidator performs a search that wraps around,
290     so that when the search reaches the last item in the model, it begins again at the first item and continues until all items have been examined.
291     This is set by default.
292     \sa wrappingLookup()
293 */
294 void QxtStringValidator::setWrappingLookup(bool enable)
295 {
296     if (enable)
297         qxt_d().userFlags |= Qt::MatchWrap;
298     else
299         qxt_d().userFlags &= ~Qt::MatchWrap;
300 }
301
302 /*!
303     Uses model as new validation model.
304     Note: The validator does not take ownership of the model.
305     sa\ lookupModel()
306 */
307 void QxtStringValidator::setLookupModel(QAbstractItemModel *model)
308 {
309     if (!qxt_d().isUserModel && qxt_d().model)
310     {
311         delete qxt_d().model;
312         qxt_d().model = 0;
313     }
314
315     qxt_d().lookupRole = Qt::EditRole;
316     qxt_d().isUserModel = true;
317     qxt_d().lookupStartModelIndex = QModelIndex();
318     qxt_d().model = QPointer<QAbstractItemModel>(model);
319 }
320
321 /*!
322     Sets the item role to be used to query the contents of items for validation.
323     Note: this is only possible if the model was set with setLookupModel()
324     This is set to default Value Qt::EditRole when the model changes
325     \sa lookupRole()
326 */
327 void QxtStringValidator::setLookupRole(const int role)
328 {
329     if (qxt_d().isUserModel)
330         qxt_d().lookupRole = role;
331 }
332
333 /*!
334     Returns the item role to be used to query the contents of items for validation.
335     \sa setLookupRole()
336 */
337 int QxtStringValidator::lookupRole() const
338 {
339     return qxt_d().lookupRole;
340 }