QGIS API Documentation 3.32.0-Lima (311a8cb8a6)
qgslayermetadataresultsmodel.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgslayermetadataresultsmodel.cpp - QgsLayerMetadataResultsModel
3
4 ---------------------
5 begin : 1.9.2022
6 copyright : (C) 2022 by ale
7 email : [your-email-here]
8 ***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
17#include "qgsfeedback.h"
18#include "qgsapplication.h"
21#include "qgsiconutils.h"
22#include "qgsproviderregistry.h"
23#include "qgsprovidermetadata.h"
24#include <QIcon>
25
27 : QAbstractTableModel( parent )
28 , mSearchContext( searchContext )
29{
30 qRegisterMetaType< QgsLayerMetadataSearchResults>( "QgsLayerMetadataSearchResults" );
31 qRegisterMetaType< QgsLayerMetadataProviderResult>( "QgsLayerMetadataProviderResult" );
32}
33
35{
36 cancel();
37}
38
39int QgsLayerMetadataResultsModel::rowCount( const QModelIndex &parent ) const
40{
41 return parent.isValid() ? 0 : mResult.metadata().count();
42}
43
44int QgsLayerMetadataResultsModel::columnCount( const QModelIndex &parent ) const
45{
46 return parent.isValid() ? 0 : 5;
47}
48
49QVariant QgsLayerMetadataResultsModel::data( const QModelIndex &index, int role ) const
50{
51 if ( index.isValid() && index.row() < mResult.metadata().count( ) )
52 {
53 switch ( role )
54 {
55 case Qt::ItemDataRole::DisplayRole:
56 {
57 switch ( index.column() )
58 {
59 case Sections::Identifier:
60 return mResult.metadata().at( index.row() ).identifier( );
61 case Sections::Title:
62 return mResult.metadata().at( index.row() ).title();
63 case Sections::Abstract:
64 return mResult.metadata().at( index.row() ).abstract();
65 case Sections::DataProviderName:
66 {
67 const QString providerName { mResult.metadata().at( index.row() ).dataProviderName() };
69 return md ? md->description() : providerName;
70 }
71 case Sections::GeometryType:
72 {
73 const QList<QgsLayerMetadataProviderResult> metadata = mResult.metadata();
74 const QgsLayerMetadataProviderResult &md { metadata.at( index.row() ) };
75 if ( md.layerType() == Qgis::LayerType::Raster )
76 return tr( "Raster" );
77 return md.geometryType() == Qgis::GeometryType::Unknown ? QgsWkbTypes::geometryDisplayString( Qgis::GeometryType::Null ) : QgsWkbTypes::geometryDisplayString( md.geometryType() );
78 }
79 default:
80 return QVariant();
81 }
82 break;
83 }
84 case Qt::ItemDataRole::ToolTipRole:
85 {
86 const QgsLayerMetadataFormatter formatter { mResult.metadata().at( index.row() ) };
87 return tr( R"HTML(<html><body><!-- metadata headers ---><h3>Identification</h3>%1</body></html>)HTML" )
88 .arg(
89 formatter.identificationSectionHtml() );
90 break;
91 }
92 case Qt::ItemDataRole::DecorationRole:
93 {
94 if ( index.column() == 0 )
95 {
96 const QList<QgsLayerMetadataProviderResult> metadata = mResult.metadata();
97 const QgsLayerMetadataProviderResult &md { metadata.at( index.row() ) };
98 if ( md.layerType() == Qgis::LayerType::Raster )
99 return QgsApplication::getThemeIcon( QStringLiteral( "mIconRaster.svg" ) );
100 return QgsIconUtils::iconForGeometryType( md.geometryType() == Qgis::GeometryType::Unknown ? Qgis::GeometryType::Null : md.geometryType() );
101 }
102 break;
103 }
104 case Roles::Metadata:
105 {
106 return QVariant::fromValue( mResult.metadata().at( index.row() ) );
107 }
108 default:
109 // Ignore
110 break;
111
112 }
113 }
114 return QVariant();
115}
116
117QVariant QgsLayerMetadataResultsModel::headerData( int section, Qt::Orientation orientation, int role ) const
118{
119 if ( orientation == Qt::Orientation::Horizontal && section < columnCount( createIndex( -1, -1 ) ) )
120 {
121 if ( role == Qt::ItemDataRole::DisplayRole )
122 {
123 switch ( section )
124 {
125 case Sections::Identifier:
126 return tr( "Identifier" );
127 case Sections::Title:
128 return tr( "Title" );
129 case Sections::Abstract:
130 return tr( "Abstract" );
131 case Sections::DataProviderName:
132 return tr( "Provider" );
133 case Sections::GeometryType:
134 return tr( "Layer Type" );
135 }
136 }
137 // other roles here ...
138 }
139 return QAbstractTableModel::headerData( section, orientation, role );
140}
141
143{
144 cancel();
145 beginResetModel();
146 // Load results from layer metadata providers
148 const QList<QgsAbstractLayerMetadataProvider *> providers { QgsApplication::instance()->layerMetadataProviderRegistry()->layerMetadataProviders() };
149 for ( QgsAbstractLayerMetadataProvider *mdProvider : std::as_const( providers ) )
150 {
151 const QList<QgsLayerMetadataProviderResult> results { mdProvider->search( mSearchContext ).metadata() };
152 for ( const QgsLayerMetadataProviderResult &metadata : std::as_const( results ) )
153 {
154 mResult.addMetadata( metadata );
155 }
156 }
157 endResetModel();
158}
159
161{
162 cancel();
163 beginResetModel();
164 // Load results from layer metadata providers
166 endResetModel();
167 mFeedback->setProgress( 0 );
168 const QList<QgsAbstractLayerMetadataProvider *> providers { QgsApplication::instance()->layerMetadataProviderRegistry()->layerMetadataProviders() };
169 for ( QgsAbstractLayerMetadataProvider *mdProvider : std::as_const( providers ) )
170 {
171 std::unique_ptr<QgsMetadataResultsFetcher> fetcher = std::make_unique<QgsMetadataResultsFetcher>( mdProvider, mSearchContext, mFeedback.get() );
172 std::unique_ptr<QThread> thread = std::make_unique<QThread>();
173 fetcher->moveToThread( thread.get() );
174 // Forward signals to the model
175 connect( fetcher.get(), &QgsMetadataResultsFetcher::resultsReady, this, [ = ]( const QgsLayerMetadataSearchResults & results )
176 {
177 resultsReady( results );
178 } );
179 connect( thread.get(), &QThread::started, fetcher.get(), &QgsMetadataResultsFetcher::fetchMetadata );
180 mWorkerThreads.push_back( std::move( thread ) );
181 mWorkers.push_back( std::move( fetcher ) );
182 mWorkerThreads.back()->start();
183 }
184}
185
187{
188 mFeedback->setProgress( mFeedback->progress() + 100 / QgsApplication::instance()->layerMetadataProviderRegistry()->layerMetadataProviders().count() );
189 beginInsertRows( QModelIndex(), mResult.metadata().count(), mResult.metadata().count() + results.metadata().count() - 1 );
190 const QList<QgsLayerMetadataProviderResult> metadata { results.metadata() };
191 for ( const QgsLayerMetadataProviderResult &result : std::as_const( metadata ) )
192 {
193 mResult.addMetadata( result );
194 }
195 endInsertRows();
196}
197
199{
200 if ( mFeedback )
201 {
202 mFeedback->cancel();
203 }
204
205 for ( const auto &workerThread : std::as_const( mWorkerThreads ) )
206 {
207 workerThread->quit();
208 workerThread->wait();
209 }
210
211 mWorkers.clear();
212 mWorkerThreads.clear();
213
214 mFeedback = std::make_unique<QgsFeedback>();
216}
217
218
220
221QgsMetadataResultsFetcher::QgsMetadataResultsFetcher( const QgsAbstractLayerMetadataProvider *metadataProvider, const QgsMetadataSearchContext &searchContext, QgsFeedback *feedback )
222 : mLayerMetadataProvider( metadataProvider )
223 , mSearchContext( searchContext )
224 , mFeedback( feedback )
225{
226}
227
228void QgsMetadataResultsFetcher::fetchMetadata()
229{
230 emit resultsReady( mLayerMetadataProvider->search( mSearchContext, QString(), QgsRectangle(), mFeedback ) );
231}
232
Layer metadata provider backend interface.
static QgsLayerMetadataProviderRegistry * layerMetadataProviderRegistry()
Returns registry of available layer metadata provider implementations.
static QgsApplication * instance()
Returns the singleton instance of the QgsApplication.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:45
void progressChanged(double progress)
Emitted when the feedback object reports a progress change.
static QIcon iconForGeometryType(Qgis::GeometryType typeGroup)
Returns the icon for a vector layer whose geometry typeGroup is provided.
Class for metadata formatter.
QList< QgsAbstractLayerMetadataProvider * > layerMetadataProviders() const
Returns the list of all registered layer metadata providers.
Result record of layer metadata provider search.
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
int columnCount(const QModelIndex &parent) const override
void cancel()
Cancels the results fetching.
void reload()
Load/Reload model data synchronously.
void reloadAsync()
Load/Reload model data asynchronously using threads.
QgsLayerMetadataResultsModel(const QgsMetadataSearchContext &searchContext, QObject *parent=nullptr)
Constructs a QgsLayerMetadataResultsModel from a searchContext and an optional parent.
QVariant data(const QModelIndex &index, int role) const override
void progressChanged(int progress)
Emitted when the progress changed to progress.
void resultsReady(const QgsLayerMetadataSearchResults &results)
Triggered when metadata results have been fetched and can be added to the model.
int rowCount(const QModelIndex &parent) const override
Container of result records from a layer metadata search.
void addMetadata(const QgsLayerMetadataProviderResult &metadata)
Adds a Metadata record to the list of results.
QList< QgsLayerMetadataProviderResult > metadata() const
Returns the list of metadata results.
Holds data provider key, description, and associated shared library file or function pointer informat...
QString description() const
This returns descriptive text for the provider.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
QgsProviderMetadata * providerMetadata(const QString &providerKey) const
Returns metadata of the provider or nullptr if not found.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
static QString geometryDisplayString(Qgis::GeometryType type) SIP_HOLDGIL
Returns a display string for a geometry type.