⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qcompleter.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************//*!    \class QCompleter    \brief The QCompleter class provides completions based on an item model.    \since 4.2    You can use QCompleter to provide auto completions in any Qt    widget, such as QLineEdit and QComboBox.    When the user starts typing a word, QCompleter suggests possible ways of    completing the word, based on a word list. The word list is    provided as a QAbstractItemModel. (For simple applications, where    the word list is static, you can pass a QStringList to    QCompleter's constructor.)    \tableofcontents    \section1 Basic Usage    A QCompleter is used typically with a QLineEdit or QComboBox.    For example, here's how to provide auto completions from a simple    word list in a QLineEdit:    \code        QStringList wordList;        wordList << "alpha" << "omega" << "omicron" << "zeta";        QLineEdit *lineEdit = new QLineEdit(this);        QCompleter *completer = new QCompleter(wordList, this);        completer->setCaseSensitivity(Qt::CaseInsensitive);        lineEdit->setCompleter(completer);    \endcode    A QDirModel can be used to provide auto completion of file names.    For example:    \code        QCompleter *completer = new QCompleter(this);        completer->setModel(new QDirModel(completer));        lineEdit->setCompleter(completer);    \endcode    To set the model on which QCompleter should operate, call    setModel(). By default, QCompleter will attempt to match the \l    {completionPrefix}{completion prefix} (i.e., the word that the    user has started typing) against the Qt::EditRole data stored in    column 0 in the  model case sensitively. This can be changed    using setCompletionRole(), setCompletionColumn(), and    setCaseSensitivity().    If the model is sorted on the column and role that are used for completion,    you can call setModelSorting() with either    QCompleter::CaseSensitivelySortedModel or    QCompleter::CaseInsensitivelySortedModel as the argument. On large models,    this can lead to significant performance improvements, because QCompleter    can then use binary search instead of linear search.    The model can be a \l{QAbstractListModel}{list model},    a \l{QAbstractTableModel}{table model}, or a    \l{QAbstractItemModel}{tree model}. Completion on tree models    is slightly more involved and is covered in the \l{Handling    Tree Models} section below.    The completionMode() determines the mode used to provide completions to    the user.    \section1 Iterating Through Completions    To retrieve a single candidate string, call setCompletionPrefix()    with the text that needs to be completed and call    currentCompletion(). You can iterate through the list of    completions as below:    \code        for (int i = 0; completer->setCurrentRow(i); i++)            qDebug() << completer->currentCompletion() << " is match number " << i;    \endcode    completionCount() returns the total number of completions for the    current prefix. completionCount() should be avoided when possible,    since it requires a scan of the entire model.    \section1 The Completion Model    completionModel() return a list model that contains all possible    completions for the current completion prefix, in the order in which    they appear in the model. This model can be used to display the current    completions in a custom view. Calling setCompletionPrefix() automatically    refreshes the completion model.    \section1 Handling Tree Models    QCompleter can look for completions in tree models, assuming    that any item (or sub-item or sub-sub-item) can be unambiguously    represented as a string by specifying the path to the item. The    completion is then performed one level at a time.    Let's take the example of a user typing in a file system path.    The model is a (hierarchical) QDirModel. The completion    occurs for every element in the path. For example, if the current    text is \c C:\Wind, QCompleter might suggest \c Windows to    complete the current path element. Similarly, if the current text    is \c C:\Windows\Sy, QCompleter might suggest \c System.    For this kind of completion to work, QCompleter needs to be able to    split the path into a list of strings that are matched at each level.    For \c C:\Windows\Sy, it needs to be split as "C:", "Windows" and "Sy".    The default implementation of splitPath(), splits the completionPrefix    using QDir::separator() if the model is a QDirModel.    To provide completions, QCompleter needs to know the path from an index.    This is provided by pathFromIndex(). The default implementation of    pathFromIndex(), returns the data for the completionRole() for list models    and the absolute file path if the mode is a QDirModel.    \sa QAbstractItemModel, QLineEdit, QComboBox, {Completer Example}*/#include "qcompleter_p.h"#ifndef QT_NO_COMPLETER#include "QtGui/qscrollbar.h"#include "QtGui/qstringlistmodel.h"#include "QtGui/qdirmodel.h"#include "QtGui/qheaderview.h"#include "QtGui/qlistview.h"#include "QtGui/qapplication.h"#include "QtGui/qevent.h"#include "QtGui/qheaderview.h"#include "QtGui/qdesktopwidget.h"QCompletionModel::QCompletionModel(QCompleterPrivate *c, QObject *parent)    : QAbstractProxyModel(*new QCompletionModelPrivate, parent),      c(c), engine(0), showAll(false){    createEngine();}int QCompletionModel::columnCount(const QModelIndex &) const{    Q_D(const QCompletionModel);    return d->model->columnCount();}void QCompletionModel::setSourceModel(QAbstractItemModel *source){    bool hadModel = (sourceModel() != 0);    if (hadModel)        QObject::disconnect(sourceModel(), 0, this, 0);    QAbstractProxyModel::setSourceModel(source);    if (source) {        // TODO: Optimize updates in the source model        connect(source, SIGNAL(modelReset()), this, SLOT(invalidate()));        connect(source, SIGNAL(destroyed()), this, SLOT(modelDestroyed()));        connect(source, SIGNAL(layoutChanged()), this, SLOT(invalidate()));        connect(source, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(rowsInserted()));        connect(source, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(invalidate()));        connect(source, SIGNAL(columnsInserted(QModelIndex,int,int)), this, SLOT(invalidate()));        connect(source, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(invalidate()));        connect(source, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(invalidate()));    }    invalidate();}void QCompletionModel::createEngine(){    bool sortedEngine = false;    switch (c->sorting) {    case QCompleter::UnsortedModel:        sortedEngine = false;        break;    case QCompleter::CaseSensitivelySortedModel:        sortedEngine = c->cs == Qt::CaseSensitive;        break;    case QCompleter::CaseInsensitivelySortedModel:        sortedEngine = c->cs == Qt::CaseInsensitive;        break;    }    delete engine;    if (sortedEngine)        engine = new QSortedModelEngine(c);    else        engine = new QUnsortedModelEngine(c);}QModelIndex QCompletionModel::mapToSource(const QModelIndex& index) const{    Q_D(const QCompletionModel);    if (!index.isValid())        return QModelIndex();    int row;    QModelIndex parent = engine->curParent;    if (!showAll) {        if (!engine->matchCount())            return QModelIndex();        Q_ASSERT(index.row() < engine->matchCount());        QIndexMapper& rootIndices = engine->historyMatch.indices;        if (index.row() < rootIndices.count()) {            row = rootIndices[index.row()];            parent = QModelIndex();        } else {            row = engine->curMatch.indices[index.row() - rootIndices.count()];        }    } else {        row = index.row();    }    return d->model->index(row, index.column(), parent);}QModelIndex QCompletionModel::mapFromSource(const QModelIndex& idx) const{    if (!idx.isValid())        return QModelIndex();    int row = -1;    if (!showAll) {        if (!engine->matchCount())            return QModelIndex();        QIndexMapper& rootIndices = engine->historyMatch.indices;        if (idx.parent().isValid()) {            if (idx.parent() != engine->curParent)                return QModelIndex();        } else {            row = rootIndices.indexOf(idx.row());            if (row == -1 && engine->curParent.isValid())                return QModelIndex(); // source parent and our parent don't match        }        if (row == -1) {            QIndexMapper& indices = engine->curMatch.indices;            engine->filterOnDemand(idx.row() - indices.last());            row = indices.indexOf(idx.row()) + rootIndices.count();        }        if (row == -1)            return QModelIndex();    } else {        if (idx.parent() != engine->curParent)            return QModelIndex();        row = idx.row();    }    return createIndex(row, idx.column());}bool QCompletionModel::setCurrentRow(int row){    if (row < 0 || !engine->matchCount())        return false;    if (row >= engine->matchCount())        engine->filterOnDemand(row + 1 - engine->matchCount());    if (row >= engine->matchCount()) // invalid row        return false;    engine->curRow = row;    return true;}QModelIndex QCompletionModel::currentIndex(bool sourceIndex) const{    if (!engine->matchCount())        return QModelIndex();    int row = engine->curRow;    if (showAll)        row = engine->curMatch.indices[engine->curRow];    QModelIndex idx = createIndex(row, c->column);    if (!sourceIndex)        return idx;    return mapToSource(idx);}QModelIndex QCompletionModel::index(int row, int column, const QModelIndex& parent) const{    Q_D(const QCompletionModel);    if (row < 0 || column < 0 || column >= columnCount(parent) || parent.isValid())        return QModelIndex();    if (!showAll) {        if (!engine->matchCount())            return QModelIndex();        if (row >= engine->historyMatch.indices.count()) {            int want = row + 1 - engine->matchCount();            if (want > 0)                engine->filterOnDemand(want);            if (row >= engine->matchCount())                return QModelIndex();        }    } else {        if (row >= d->model->rowCount(engine->curParent))            return QModelIndex();    }    return createIndex(row, column);}int QCompletionModel::completionCount() const{    if (!engine->matchCount())        return 0;    engine->filterOnDemand(INT_MAX);    return engine->matchCount();}int QCompletionModel::rowCount(const QModelIndex &parent) const{    Q_D(const QCompletionModel);    if (parent.isValid())        return 0;    if (showAll) {        // Show all items below current parent, even if we have no valid matches        if (engine->curParts.count() != 1  && !engine->matchCount()            && !engine->curParent.isValid())            return 0;        return d->model->rowCount(engine->curParent);    }    return completionCount();}void QCompletionModel::setFiltered(bool filtered){    if (showAll == !filtered)        return;    showAll = !filtered;    resetModel();}bool QCompletionModel::hasChildren(const QModelIndex &parent) const{    Q_D(const QCompletionModel);    if (parent.isValid())        return false;    if (showAll)        return d->model->hasChildren(mapToSource(parent));    if (!engine->matchCount())        return false;    return true;}QVariant QCompletionModel::data(const QModelIndex& index, int role) const{    Q_D(const QCompletionModel);    return d->model->data(mapToSource(index), role);}void QCompletionModel::modelDestroyed(){    QAbstractProxyModel::setSourceModel(0); // switch to static empty model    invalidate();}void QCompletionModel::rowsInserted(){    invalidate();    emit rowsAdded();}void QCompletionModel::invalidate(){    engine->cache.clear();    filter(engine->curParts);}void QCompletionModel::filter(const QStringList& parts){    Q_D(QCompletionModel);    engine->filter(parts);    resetModel();    if (d->model->canFetchMore(engine->curParent))        d->model->fetchMore(engine->curParent);}void QCompletionModel::resetModel(){    if (rowCount() == 0) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -