QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
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 QgsLayerMetadataProviderResult &md { mResult.metadata().at( index.row() ) };
74 if ( md.layerType() == QgsMapLayerType::RasterLayer )
75 return tr( "Raster" );
76 return md.geometryType() == QgsWkbTypes::GeometryType::UnknownGeometry ? QgsWkbTypes::geometryDisplayString( QgsWkbTypes::GeometryType::NullGeometry ) : QgsWkbTypes::geometryDisplayString( md.geometryType() );
77 }
78 default:
79 return QVariant();
80 }
81 break;
82 }
83 case Qt::ItemDataRole::ToolTipRole:
84 {
85 const QgsLayerMetadataFormatter formatter { mResult.metadata().at( index.row() ) };
86 return tr( R"HTML(<html><body><!-- metadata headers ---><h3>Identification</h3>%1</body></html>)HTML" )
87 .arg(
88 formatter.identificationSectionHtml() );
89 break;
90 }
91 case Qt::ItemDataRole::DecorationRole:
92 {
93 if ( index.column() == 0 )
94 {
95 const QgsLayerMetadataProviderResult &md { mResult.metadata().at( index.row() ) };
96 if ( md.layerType() == QgsMapLayerType::RasterLayer )
97 return QgsApplication::getThemeIcon( QStringLiteral( "mIconRaster.svg" ) );
98 return QgsIconUtils::iconForGeometryType( md.geometryType() == QgsWkbTypes::GeometryType::UnknownGeometry ? QgsWkbTypes::GeometryType::NullGeometry : md.geometryType() );
99 }
100 break;
101 }
102 case Roles::Metadata:
103 {
104 return QVariant::fromValue( mResult.metadata().at( index.row() ) );
105 }
106 default:
107 // Ignore
108 break;
109
110 }
111 }
112 return QVariant();
113}
114
115QVariant QgsLayerMetadataResultsModel::headerData( int section, Qt::Orientation orientation, int role ) const
116{
117 if ( orientation == Qt::Orientation::Horizontal && section < columnCount( createIndex( -1, -1 ) ) )
118 {
119 if ( role == Qt::ItemDataRole::DisplayRole )
120 {
121 switch ( section )
122 {
123 case Sections::Identifier:
124 return tr( "Identifier" );
125 case Sections::Title:
126 return tr( "Title" );
127 case Sections::Abstract:
128 return tr( "Abstract" );
129 case Sections::DataProviderName:
130 return tr( "Provider" );
131 case Sections::GeometryType:
132 return tr( "Layer Type" );
133 }
134 }
135 // other roles here ...
136 }
137 return QAbstractTableModel::headerData( section, orientation, role );
138}
139
141{
142 cancel();
143 beginResetModel();
144 // Load results from layer metadata providers
146 const QList<QgsAbstractLayerMetadataProvider *> providers { QgsApplication::instance()->layerMetadataProviderRegistry()->layerMetadataProviders() };
147 for ( QgsAbstractLayerMetadataProvider *mdProvider : std::as_const( providers ) )
148 {
149 const QList<QgsLayerMetadataProviderResult> results { mdProvider->search( mSearchContext ).metadata() };
150 for ( const QgsLayerMetadataProviderResult &metadata : std::as_const( results ) )
151 {
152 mResult.addMetadata( metadata );
153 }
154 }
155 endResetModel();
156}
157
159{
160 cancel();
161 beginResetModel();
162 // Load results from layer metadata providers
164 endResetModel();
165 mFeedback->setProgress( 0 );
166 const QList<QgsAbstractLayerMetadataProvider *> providers { QgsApplication::instance()->layerMetadataProviderRegistry()->layerMetadataProviders() };
167 for ( QgsAbstractLayerMetadataProvider *mdProvider : std::as_const( providers ) )
168 {
169 std::unique_ptr<QgsMetadataResultsFetcher> fetcher = std::make_unique<QgsMetadataResultsFetcher>( mdProvider, mSearchContext, mFeedback.get() );
170 std::unique_ptr<QThread> thread = std::make_unique<QThread>();
171 fetcher->moveToThread( thread.get() );
172 // Forward signals to the model
173 connect( fetcher.get(), &QgsMetadataResultsFetcher::resultsReady, this, [ = ]( const QgsLayerMetadataSearchResults & results )
174 {
175 resultsReady( results );
176 } );
177 connect( thread.get(), &QThread::started, fetcher.get(), &QgsMetadataResultsFetcher::fetchMetadata );
178 mWorkerThreads.push_back( std::move( thread ) );
179 mWorkers.push_back( std::move( fetcher ) );
180 mWorkerThreads.back()->start();
181 }
182}
183
185{
186 mFeedback->setProgress( mFeedback->progress() + 100 / QgsApplication::instance()->layerMetadataProviderRegistry()->layerMetadataProviders().count() );
187 beginInsertRows( QModelIndex(), mResult.metadata().count(), mResult.metadata().count() + results.metadata().count() - 1 );
188 const QList<QgsLayerMetadataProviderResult> metadata { results.metadata() };
189 for ( const QgsLayerMetadataProviderResult &result : std::as_const( metadata ) )
190 {
191 mResult.addMetadata( result );
192 }
193 endInsertRows();
194}
195
197{
198 if ( mFeedback )
199 {
200 mFeedback->cancel();
201 }
202
203 for ( const auto &workerThread : std::as_const( mWorkerThreads ) )
204 {
205 workerThread->quit();
206 workerThread->wait();
207 }
208
209 mWorkers.clear();
210 mWorkerThreads.clear();
211
212 mFeedback = std::make_unique<QgsFeedback>();
214}
215
216
218
219QgsMetadataResultsFetcher::QgsMetadataResultsFetcher( const QgsAbstractLayerMetadataProvider *metadataProvider, const QgsMetadataSearchContext &searchContext, QgsFeedback *feedback )
220 : mLayerMetadataProvider( metadataProvider )
221 , mSearchContext( searchContext )
222 , mFeedback( feedback )
223{
224}
225
226void QgsMetadataResultsFetcher::fetchMetadata()
227{
228 emit resultsReady( mLayerMetadataProvider->search( mSearchContext, QString(), QgsRectangle(), mFeedback ) );
229}
230
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(QgsWkbTypes::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(GeometryType type) SIP_HOLDGIL
Returns a display string for a geometry type.
@ RasterLayer
Raster layer.