qgslocatormodel.h 6.48 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
/***************************************************************************
                         qgslocatormodel.h
                         ------------------
    begin                : May 2017
    copyright            : (C) 2017 by Nyall Dawson
    email                : nyall dot dawson at gmail dot com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef QGSLOCATORMODEL_H
#define QGSLOCATORMODEL_H

#include "qgis_core.h"
#include "qgslocatorfilter.h"
#include <QAbstractListModel>
#include <QTimer>
#include <QSet>
#include <QSortFilterProxyModel>

class QgsLocator;
class QgsLocatorModel;
class QgsLocatorProxyModel;

/**
 * \class QgsLocatorModel
 * \ingroup core
 * An abstract list model for displaying the results of locator searches.
 *
 * Note that this class should generally be used with a QgsLocatorProxyModel
 * in order to ensure correct sorting of results by priority and match level.
 *
 * \since QGIS 3.0
 */
class CORE_EXPORT QgsLocatorModel : public QAbstractTableModel
{
    Q_OBJECT

  public:

    static const int NoGroup = 9999;

    //! Custom model roles
    enum Role
    {
      ResultDataRole = Qt::UserRole + 1, //!< QgsLocatorResult data
      ResultTypeRole, //!< Result type
      ResultFilterPriorityRole, //!< Result priority, used by QgsLocatorProxyModel for sorting roles.
      ResultScoreRole, //!< Result match score, used by QgsLocatorProxyModel for sorting roles.
      ResultFilterNameRole, //!< Associated filter name which created the result
      ResultFilterGroupSortingRole, //!< Group results within the same filter results
      ResultActionsRole, //!< The actions to be shown for the given result in a context menu
    };

    /**
     * Constructor for QgsLocatorModel.
     */
    QgsLocatorModel( QObject *parent SIP_TRANSFERTHIS = nullptr );

    /**
     * Resets the model and clears all existing results.
     * \see deferredClear()
     */
    void clear();

    /**
     * Resets the model and clears all existing results after a short delay, or whenever the next result is added to the model
     * (whichever occurs first). Using deferredClear() instead of clear() can avoid the visually distracting frequent clears
     * which may occur if the model is being updated quickly multiple times as a result of users typing in a search query.
     * \see deferredClear()
     */
    void deferredClear();

    int rowCount( const QModelIndex &parent = QModelIndex() ) const override;
    int columnCount( const QModelIndex &parent = QModelIndex() ) const override;
    QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const override;
    Qt::ItemFlags flags( const QModelIndex &index ) const override;
    QHash<int, QByteArray> roleNames() const override;

  public slots:

    /**
     * Adds a new \a result to the model.
     */
    void addResult( const QgsLocatorResult &result );

  private:

    enum ColumnCount
    {
      Name = 0,
      Description
    };

    struct Entry
    {
      QgsLocatorResult result;
      QString filterTitle;
      QgsLocatorFilter *filter = nullptr;
      QString groupTitle = QString();
      int groupSorting = 0;
    };

    QList<Entry> mResults;
    QSet<QString> mFoundResultsFromFilterNames;
    QMap<QgsLocatorFilter *, QStringList> mFoundResultsFilterGroups;
    bool mDeferredClear = false;
    QTimer mDeferredClearTimer;
};

/**
 * \class QgsLocatorAutomaticModel
 * \ingroup core
 * A QgsLocatorModel which has is associated directly with a
 * QgsLocator, and is automatically populated with results
 * from locator searches.
 *
 * Use this QgsLocatorModel subclass when you want the connections
 * between a QgsLocator and the model to be automatically created
 * for you. If more flexibility in model behavior is required,
 * use the base QgsLocatorModel class instead and setup the
 * connections manually.
 *
 * Note that this class should generally be used with a QgsLocatorProxyModel
 * in order to ensure correct sorting of results by priority and match level.
 *
 * \since QGIS 3.0
 */
class CORE_EXPORT QgsLocatorAutomaticModel : public QgsLocatorModel
{
    Q_OBJECT

  public:

    /**
     * Constructor for QgsLocatorAutomaticModel, linked with the specified \a locator.
     *
     * The \a locator is used as the model's parent.
    */
    explicit QgsLocatorAutomaticModel( QgsLocator *locator SIP_TRANSFERTHIS );

    /**
     * Returns a pointer to the locator utilized by this model.
     */
    QgsLocator *locator();

    /**
     * Enqueues a search for a specified \a string within the model.
     *
     * Note that the search may not begin immediately if an existing search request
     * is still running. In this case the existing search must be completely
     * terminated before the new search can begin. The model handles this
     * situation automatically, and will trigger a search for the new
     * search string as soon as possible.
     */
    void search( const QString &string );

    /**
     * Returns a new locator context for searches. The default implementation
     * returns a default constructed QgsLocatorContext. Subclasses can override
     * this method to implement custom context creation logic.
     */
    virtual QgsLocatorContext createContext();

  private slots:

    void searchFinished();

  private:

    QgsLocator *mLocator = nullptr;

    QString mNextRequestedString;
    bool mHasQueuedRequest = false;
};

/**
 * \class QgsLocatorProxyModel
 * \ingroup core
 * A sort proxy model for QgsLocatorModel, which automatically sorts
 * results by precedence.
 * \since QGIS 3.0
 */
class CORE_EXPORT QgsLocatorProxyModel : public QSortFilterProxyModel
{
    Q_OBJECT

  public:

    /**
     * Constructor for QgsLocatorProxyModel, with the specified \a parent object.
     */
    explicit QgsLocatorProxyModel( QObject *parent SIP_TRANSFERTHIS = nullptr );
    bool lessThan( const QModelIndex &left, const QModelIndex &right ) const override;
};

#endif // QGSLOCATORMODEL_H