31 : QAbstractTableModel( parent )
33 mDeferredClearTimer.setInterval( 100 );
34 mDeferredClearTimer.setSingleShot(
true );
40 mDeferredClearTimer.stop();
41 mDeferredClear =
false;
45 mFoundResultsFromFilterNames.clear();
46 mFoundResultsFilterGroups.clear();
52 mDeferredClear =
true;
53 mDeferredClearTimer.start();
58 return mResults.size();
68 if ( !index.isValid() || index.row() < 0 || index.column() < 0 ||
69 index.row() >=
rowCount( QModelIndex() ) || index.column() >=
columnCount( QModelIndex() ) )
77 switch ( index.column() )
80 if ( !mResults.at( index.row() ).filter )
81 return mResults.at( index.row() ).result.displayString;
82 else if ( mResults.at( index.row() ).filter && mResults.at( index.row() ).groupSorting == 0 )
83 return mResults.at( index.row() ).filterTitle;
86 QString groupTitle = mResults.at( index.row() ).groupTitle;
87 groupTitle.prepend(
" " );
91 if ( !mResults.at( index.row() ).filter )
92 return mResults.at( index.row() ).result.description;
100 if ( index.column() == Name && !mResults.at( index.row() ).groupTitle.isEmpty() )
103 font.setItalic(
true );
112 case Qt::DecorationRole:
113 switch ( index.column() )
116 if ( !mResults.at( index.row() ).filter )
118 const QIcon icon = mResults.at( index.row() ).result.icon;
119 if ( !icon.isNull() )
131 if ( !mResults.at( index.row() ).filter )
132 return QVariant::fromValue( mResults.at( index.row() ).result );
138 return mResults.at( index.row() ).groupSorting;
141 if ( mResults.at( index.row() ).filter )
144 return ( mResults.at( index.row() ).result.score );
147 if ( !mResults.at( index.row() ).filter )
148 return mResults.at( index.row() ).result.filter->priority();
150 return mResults.at( index.row() ).filter->priority();
153 if ( !mResults.at( index.row() ).filter )
154 return mResults.at( index.row() ).result.filter->displayName();
156 return mResults.at( index.row() ).filterTitle;
159 if ( mResults.at( index.row() ).groupTitle.isEmpty() )
165 return QVariant::fromValue( mResults.at( index.row() ).result.actions );
173 if ( !index.isValid() || index.row() < 0 || index.column() < 0 ||
174 index.row() >=
rowCount( QModelIndex() ) || index.column() >=
columnCount( QModelIndex() ) )
175 return QAbstractTableModel::flags( index );
177 Qt::ItemFlags
flags = QAbstractTableModel::flags( index );
178 if ( mResults.at( index.row() ).filter )
180 flags =
flags & ~( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
187 QHash<int, QByteArray> roles;
195 roles[Qt::DisplayRole] =
"Text";
201 mDeferredClearTimer.stop();
202 if ( mDeferredClear )
204 mFoundResultsFromFilterNames.clear();
205 mFoundResultsFilterGroups.clear();
208 const int pos = mResults.size();
209 const bool addingFilter = !result.
filter->
displayName().isEmpty() && !mFoundResultsFromFilterNames.contains( result.
filter->
name() );
211 mFoundResultsFromFilterNames << result.
filter->
name();
213 const bool addingGroup = !result.
group.isEmpty() && ( !mFoundResultsFilterGroups.contains( result.
filter )
214 || !mFoundResultsFilterGroups.value( result.
filter ).contains( result.
group ) );
217 if ( !mFoundResultsFilterGroups.contains( result.
filter ) )
218 mFoundResultsFilterGroups[result.
filter] = QStringList();
219 mFoundResultsFilterGroups[result.
filter] << result.
group ;
221 if ( mDeferredClear )
227 beginInsertRows( QModelIndex(), pos, pos + (
static_cast<int>( addingFilter ) +
static_cast<int>( addingGroup ) ) );
233 entry.filter = result.
filter;
240 entry.groupTitle = result.
group;
243 entry.groupSorting = mFoundResultsFilterGroups[result.
filter].count();
244 entry.filter = result.
filter;
248 entry.result = result;
250 entry.groupSorting = result.
group.isEmpty() ?
NoGroup : mFoundResultsFilterGroups[result.
filter].indexOf( result.
group ) + 1;
253 if ( mDeferredClear )
258 mDeferredClear =
false;
268 , mLocator( locator )
270 Q_ASSERT( mLocator );
288 mNextRequestedString = string;
289 mHasQueuedRequest =
true;
304void QgsLocatorAutomaticModel::searchFinished()
306 if ( mHasQueuedRequest )
309 const QString nextSearch = mNextRequestedString;
310 mNextRequestedString.clear();
311 mHasQueuedRequest =
false;
325 : QSortFilterProxyModel( parent )
327 setDynamicSortFilter(
true );
328 setSortLocaleAware(
true );
329 setFilterCaseSensitivity( Qt::CaseInsensitive );
338 if ( leftFilterPriority != rightFilterPriority )
339 return leftFilterPriority < rightFilterPriority;
344 if ( leftFilter != rightFilter )
345 return QString::localeAwareCompare( leftFilter, rightFilter ) < 0;
350 if ( leftTypeRole != rightTypeRole )
351 return leftTypeRole < rightTypeRole;
356 if ( leftGroupRole != rightGroupRole )
357 return leftGroupRole < rightGroupRole;
363 return leftScore > rightScore;
366 leftFilter = sourceModel()->data( left, Qt::DisplayRole ).toString();
367 rightFilter = sourceModel()->data( right, Qt::DisplayRole ).toString();
368 return QString::localeAwareCompare( leftFilter, rightFilter ) < 0;
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
QgsLocator * locator()
Returns a pointer to the locator utilized by this model.
QgsLocatorAutomaticModel(QgsLocator *locator)
Constructor for QgsLocatorAutomaticModel, linked with the specified locator.
void search(const QString &string)
Enqueues a search for a specified string within the model.
virtual QgsLocatorContext createContext()
Returns a new locator context for searches.
Encapsulates the properties relating to the context of a locator search.
virtual QString displayName() const =0
Returns a translated, user-friendly name for the filter.
virtual QString name() const =0
Returns the unique name for the filter.
An abstract list model for displaying the results of locator searches.
int columnCount(const QModelIndex &parent=QModelIndex()) const override
void deferredClear()
Resets the model and clears all existing results after a short delay, or whenever the next result is ...
Qt::ItemFlags flags(const QModelIndex &index) const override
QHash< int, QByteArray > roleNames() const override
void addResult(const QgsLocatorResult &result)
Adds a new result to the model.
QgsLocatorModel(QObject *parent=nullptr)
Constructor for QgsLocatorModel.
void clear()
Resets the model and clears all existing results.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
@ ResultScoreRole
Result match score, used by QgsLocatorProxyModel for sorting roles.
@ ResultFilterNameRole
Associated filter name which created the result.
@ ResultDataRole
QgsLocatorResult data.
@ ResultActionsRole
The actions to be shown for the given result in a context menu.
@ ResultFilterPriorityRole
Result priority, used by QgsLocatorProxyModel for sorting roles.
@ ResultFilterGroupSortingRole
Group results within the same filter results.
@ ResultTypeRole
Result type.
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override
QgsLocatorProxyModel(QObject *parent=nullptr)
Constructor for QgsLocatorProxyModel, with the specified parent object.
Encapsulates properties of an individual matching result found by a QgsLocatorFilter.
QString group
Group the results by categories If left as empty string, this means that results are all shown withou...
QgsLocatorFilter * filter
Filter from which the result was obtained.
Handles the management of QgsLocatorFilter objects and async collection of search results from them.
void finished()
Emitted when locator has finished a query, either as a result of successful completion or early cance...
void foundResult(const QgsLocatorResult &result)
Emitted whenever a filter encounters a matching result after the fetchResults() method is called.
void fetchResults(const QString &string, const QgsLocatorContext &context, QgsFeedback *feedback=nullptr)
Triggers the background fetching of filter results for a specified search string.
bool isRunning() const
Returns true if a query is currently being executed by the locator.
void cancelWithoutBlocking()
Triggers cancellation of any current running query without blocking.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)