We now have a current svn snapshot of libqxt in our contrib dir, and
[quassel.git] / src / contrib / libqxt-2007-10-24 / src / gui / qxtstringvalidator.cpp
diff --git a/src/contrib/libqxt-2007-10-24/src/gui/qxtstringvalidator.cpp b/src/contrib/libqxt-2007-10-24/src/gui/qxtstringvalidator.cpp
new file mode 100644 (file)
index 0000000..d558a80
--- /dev/null
@@ -0,0 +1,340 @@
+/****************************************************************************
+**
+** Copyright (C) Qxt Foundation. Some rights reserved.
+**
+** This file is part of the QxtGui module of the Qt eXTension library
+**
+** This library is free software; you can redistribute it and/or modify it
+** under the terms of th Common Public License, version 1.0, as published by
+** IBM.
+**
+** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+** FITNESS FOR A PARTICULAR PURPOSE.
+**
+** You should have received a copy of the CPL along with this file.
+** See the LICENSE file and the cpl1.0.txt file included with the source
+** distribution for more information. If you did not receive a copy of the
+** license, contact the Qxt Foundation.
+**
+** <http://libqxt.sourceforge.net>  <foundation@libqxt.org>
+**
+****************************************************************************/
+
+#include "qxtstringvalidator.h"
+#include "qxtstringvalidator_p.h"
+
+#include <QDebug>
+#include <QAbstractItemModel>
+#include <QStringListModel>
+#include <QFlags>
+
+QxtStringValidatorPrivate::QxtStringValidatorPrivate() : isUserModel(false)
+        , model(0)
+        , cs(Qt::CaseSensitive)
+        , lookupRole(Qt::EditRole)
+        , userFlags(Qt::MatchWrap)
+        , lookupStartModelIndex(QModelIndex())
+{}
+
+QModelIndex QxtStringValidatorPrivate::lookupPartialMatch(const QString &value) const
+{
+    Qt::MatchFlags matchFlags = Qt::MatchStartsWith| userFlags;
+    if (cs == Qt::CaseSensitive)
+        matchFlags |= Qt::MatchCaseSensitive;
+
+    return lookup(value,matchFlags);
+}
+
+QModelIndex QxtStringValidatorPrivate::lookupExactMatch(const QString &value) const
+{
+    Qt::MatchFlags  matchFlags = Qt::MatchFixedString | userFlags;
+    if (cs == Qt::CaseSensitive)
+        matchFlags |= Qt::MatchCaseSensitive;
+
+    return lookup(value,matchFlags);
+}
+
+QModelIndex QxtStringValidatorPrivate::lookup(const QString &value,const Qt::MatchFlags  &matchFlags) const
+{
+    QModelIndex startIndex =  lookupStartModelIndex.isValid() ? lookupStartModelIndex : model->index(0,0);
+
+    QModelIndexList list = model->match(startIndex,lookupRole,value,1,matchFlags);
+
+    if (list.size() > 0)
+        return list[0];
+    return QModelIndex();
+}
+
+
+/*!
+    \class QxtStringValidator QxtStringValidator
+    \ingroup QxtGui
+    \brief The QxtStringValidator class provides validation on a QStringList or a QAbstractItemModel
+
+    It provides a String based validation in a stringlist or a custom model.
+    QxtStringValidator uses QAbstractItemModel::match() to validate the input.
+    For a partial match it returns QValidator::Intermediate and for a full match QValidator::Acceptable.
+
+    Example usage:
+    \code
+
+    QLineEdit * testLineEdit = new QLineEdit();
+
+    QStringList testList;
+    testList << "StringTestString" << "sTrInGCaSe"<< "StringTest"<< "String"<< "Foobar"<< "BarFoo"<< "QxtLib";
+
+    QxtStringValidator *validator = new QxtStringValidator(ui.lineEdit);
+    validator->setStringList(testList);
+
+    //change lookup case sensitivity
+    validator->setCaseSensitivity(Qt::CaseInsensitive);
+
+    testLineEdit->setValidator(validator);
+
+    \endcode
+ */
+
+/*!
+    Constructs a validator object with a parent object that accepts any string in the stringlist.
+*/
+QxtStringValidator::QxtStringValidator(QObject * parent) : QValidator(parent)
+{
+    QXT_INIT_PRIVATE(QxtStringValidator);
+}
+
+QxtStringValidator::~QxtStringValidator(void)
+{}
+
+/*!
+    Fixes up the string input if there is no exact match in the stringlist/model.
+    The first match in the stringlist/model is used to fix the input.
+*/
+void QxtStringValidator::fixup ( QString & input ) const
+{
+    qDebug()<<"Fixup called";
+
+    if (!qxt_d().model)
+        return;
+
+    if (qxt_d().lookupExactMatch(input).isValid())
+        return;
+
+    QModelIndex partialMatch = qxt_d().lookupPartialMatch(input);
+    if (partialMatch.isValid())
+        input = partialMatch.data(qxt_d().lookupRole).toString();
+
+}
+
+/*!
+    uses stringlist as new validation list
+    if a model was set before it is not deleted
+*/
+void QxtStringValidator::setStringList(const QStringList &stringList)
+{
+    //delete model only if it is a model created by us
+    if (qxt_d().model && !qxt_d().isUserModel)
+    {
+        delete qxt_d().model;
+        qxt_d().model = 0;
+    }
+
+    qxt_d().isUserModel = false;
+    qxt_d().lookupStartModelIndex = QModelIndex();
+    qxt_d().lookupRole = Qt::EditRole;
+    qxt_d().model = new QStringListModel(stringList,this);
+}
+
+/*!
+    Returns Acceptable if the string input matches a item in the stringlist.
+    Returns Intermediate if the string input matches a item in the stringlist partial or if input is empty.
+    Returns Invalid otherwise.
+
+    Note: A partial match means the beginning of the strings are matching:
+        qxtL matches qxtLib but not testqxtLib
+*/
+QValidator::State QxtStringValidator::validate ( QString & input, int & pos ) const
+{
+    Q_UNUSED(pos);
+
+    // no model or a empty model has only Acceptable values (like no validator was set)
+    if (!qxt_d().model)
+        return QValidator::Acceptable;
+
+    if (qxt_d().model->rowCount() == 0)
+        return QValidator::Acceptable;
+
+    if (input.isEmpty())
+        return QValidator::Intermediate;
+
+    if (qxt_d().lookupExactMatch(input).isValid())
+    {
+        qDebug()<<input<<" is QValidator::Acceptable";
+        return QValidator::Acceptable;
+    }
+
+    if (qxt_d().lookupPartialMatch(input).isValid())
+    {
+        qDebug()<<input<<" is QValidator::Intermediate";
+        return QValidator::Intermediate;
+    }
+
+    qDebug()<<input<<" is QValidator::Invalid";
+    return QValidator::Invalid;
+}
+
+
+/*!
+    Returns the startModelIndex.
+    Note: The return value will only we valid if the user has set the model with setLookupModel().
+    \sa setStartModelIndex()
+*/
+QModelIndex QxtStringValidator::startModelIndex() const
+{
+    if (qxt_d().isUserModel && qxt_d().model)
+    {
+        if (qxt_d().lookupStartModelIndex.isValid())
+            return qxt_d().lookupStartModelIndex;
+        else
+            return qxt_d().model->index(0,0);
+    }
+    return QModelIndex();
+}
+
+/*!
+    Returns if recursive lookup is enabled.
+    \sa setRecursiveLookup()
+*/
+bool QxtStringValidator::recursiveLookup() const
+{
+    if (qxt_d().userFlags & Qt::MatchRecursive)
+        return true;
+    return false;
+}
+
+/*!
+    Returns if wrapping lookup is enabled.
+    \sa setWrappingLookup()
+*/
+bool QxtStringValidator::wrappingLookup() const
+{
+    if (qxt_d().userFlags & Qt::MatchWrap)
+        return true;
+    return false;
+}
+
+/*!
+    Returns the used model if it was set by the user.
+    \sa setLookupModel()
+*/
+QAbstractItemModel * QxtStringValidator::lookupModel() const
+{
+    if (qxt_d().isUserModel)
+        return qxt_d().model;
+    return 0;
+}
+
+/*!
+    Returns Qt::CaseSensitive if the QxtStringValidator is matched case sensitively; otherwise returns Qt::CaseInsensitive.
+    \sa setCaseSensitivity().
+*/
+Qt::CaseSensitivity QxtStringValidator::caseSensitivity () const
+{
+    return qxt_d().cs;
+}
+
+/*!
+    Sets case sensitive matching to cs.
+    If cs is Qt::CaseSensitive, inp matches input but not INPUT.
+    The default is Qt::CaseSensitive.
+    \sa caseSensitivity().
+*/
+void QxtStringValidator::setCaseSensitivity ( Qt::CaseSensitivity caseSensitivity )
+{
+    qxt_d().cs = caseSensitivity;
+}
+
+/*!
+    Sets the index the search should start at
+    The default is QModelIndex(0,0).
+    Note: this is set to default when the model changes.
+    Changing the startModelIndex is only possible if the validator uses a userdefined model
+       and the modelindex comes from the used model
+    \sa startModelIndex()
+*/
+void QxtStringValidator::setStartModelIndex(const QModelIndex &index)
+{
+    if (index.model() == qxt_d().model)
+        qxt_d().lookupStartModelIndex = index;
+    else
+        qWarning()<<"ModelIndex from different model. Ignoring.";
+}
+
+/*!
+    If enabled QxtStringValidator searches the entire hierarchy of the model.
+    This is disabled by default.
+    \sa recursiveLookup()
+*/
+void QxtStringValidator::setRecursiveLookup(bool enable)
+{
+    if (enable)
+        qxt_d().userFlags |= Qt::MatchRecursive;
+    else
+        qxt_d().userFlags &= ~Qt::MatchRecursive;
+
+}
+
+/*!
+    If enabled QxtStringValidator performs a search that wraps around,
+    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.
+    This is set by default.
+    \sa wrappingLookup()
+*/
+void QxtStringValidator::setWrappingLookup(bool enable)
+{
+    if (enable)
+        qxt_d().userFlags |= Qt::MatchWrap;
+    else
+        qxt_d().userFlags &= ~Qt::MatchWrap;
+}
+
+/*!
+    Uses model as new validation model.
+    Note: The validator does not take ownership of the model.
+    sa\ lookupModel()
+*/
+void QxtStringValidator::setLookupModel(QAbstractItemModel *model)
+{
+    if (!qxt_d().isUserModel && qxt_d().model)
+    {
+        delete qxt_d().model;
+        qxt_d().model = 0;
+    }
+
+    qxt_d().lookupRole = Qt::EditRole;
+    qxt_d().isUserModel = true;
+    qxt_d().lookupStartModelIndex = QModelIndex();
+    qxt_d().model = QPointer<QAbstractItemModel>(model);
+}
+
+/*!
+    Sets the item role to be used to query the contents of items for validation.
+    Note: this is only possible if the model was set with setLookupModel()
+    This is set to default Value Qt::EditRole when the model changes
+    \sa lookupRole()
+*/
+void QxtStringValidator::setLookupRole(const int role)
+{
+    if (qxt_d().isUserModel)
+        qxt_d().lookupRole = role;
+}
+
+/*!
+    Returns the item role to be used to query the contents of items for validation.
+    \sa setLookupRole()
+*/
+int QxtStringValidator::lookupRole() const
+{
+    return qxt_d().lookupRole;
+}