QGIS API Documentation 3.41.0-Master (3440c17df1d)
Loading...
Searching...
No Matches
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 "moc_qgslayermetadataresultsmodel.cpp"
18#include "qgsfeedback.h"
19#include "qgsapplication.h"
22#include "qgsiconutils.h"
23#include "qgsproviderregistry.h"
24#include "qgsprovidermetadata.h"
25#include <QIcon>
26
27QgsLayerMetadataResultsModel::QgsLayerMetadataResultsModel( const QgsMetadataSearchContext &searchContext, QObject *parent )
28 : QAbstractTableModel( parent )
29 , mSearchContext( searchContext )
30{
31 qRegisterMetaType< QgsLayerMetadataSearchResults>( "QgsLayerMetadataSearchResults" );
32 qRegisterMetaType< QgsLayerMetadataProviderResult>( "QgsLayerMetadataProviderResult" );
33}
34
35QgsLayerMetadataResultsModel::~QgsLayerMetadataResultsModel()
36{
37 cancel();
38}
39
40int QgsLayerMetadataResultsModel::rowCount( const QModelIndex &parent ) const
41{
42 return parent.isValid() ? 0 : mResult.metadata().count();
43}
44
45int QgsLayerMetadataResultsModel::columnCount( const QModelIndex &parent ) const
46{
47 return parent.isValid() ? 0 : 5;
48}
49
50QVariant QgsLayerMetadataResultsModel::data( const QModelIndex &index, int role ) const
51{
52 if ( index.isValid() && index.row() < mResult.metadata().count( ) )
53 {
54 switch ( role )
55 {
56 case Qt::ItemDataRole::DisplayRole:
57 {
58 switch ( index.column() )
59 {
60 case Sections::Identifier:
61 return mResult.metadata().at( index.row() ).identifier( );
62 case Sections::Title:
63 return mResult.metadata().at( index.row() ).title();
64 case Sections::Abstract:
65 return mResult.metadata().at( index.row() ).abstract();
66 case Sections::DataProviderName:
67 {
68 const QString providerName { mResult.metadata().at( index.row() ).dataProviderName() };
70 return md ? md->description() : providerName;
71 }
72 case Sections::GeometryType:
73 {
74 const QList<QgsLayerMetadataProviderResult> metadata = mResult.metadata();
75 const QgsLayerMetadataProviderResult &md { metadata.at( index.row() ) };
76 if ( md.layerType() == Qgis::LayerType::Raster )
77 return tr( "Raster" );
78 return md.geometryType() == Qgis::GeometryType::Unknown ? QgsWkbTypes::geometryDisplayString( Qgis::GeometryType::Null ) : QgsWkbTypes::geometryDisplayString( md.geometryType() );
79 }
80 default:
81 return QVariant();
82 }
83 break;
84 }
85 case Qt::ItemDataRole::ToolTipRole:
86 {
87 const QgsLayerMetadataFormatter formatter { mResult.metadata().at( index.row() ) };
88 return tr( R"HTML(<html><body><!-- metadata headers ---><h3>Identification</h3>%1</body></html>)HTML" )
89 .arg(
90 formatter.identificationSectionHtml() );
91 break;
92 }
93 case Qt::ItemDataRole::DecorationRole:
94 {
95 if ( index.column() == 0 )
96 {
97 const QList<QgsLayerMetadataProviderResult> metadata = mResult.metadata();
98 const QgsLayerMetadataProviderResult &md { metadata.at( index.row() ) };
99 if ( md.layerType() == Qgis::LayerType::Raster )
100 return QgsApplication::getThemeIcon( QStringLiteral( "mIconRaster.svg" ) );
101 return QgsIconUtils::iconForGeometryType( md.geometryType() == Qgis::GeometryType::Unknown ? Qgis::GeometryType::Null : md.geometryType() );
102 }
103 break;
104 }
105 case static_cast< int >( CustomRole::Metadata ):
106 {
107 return QVariant::fromValue( mResult.metadata().at( index.row() ) );
108 }
109 default:
110 // Ignore
111 break;
112
113 }
114 }
115 return QVariant();
116}
117
118QVariant QgsLayerMetadataResultsModel::headerData( int section, Qt::Orientation orientation, int role ) const
119{
120 if ( orientation == Qt::Orientation::Horizontal && section < columnCount( createIndex( -1, -1 ) ) )
121 {
122 if ( role == Qt::ItemDataRole::DisplayRole )
123 {
124 switch ( section )
125 {
126 case Sections::Identifier:
127 return tr( "Identifier" );
128 case Sections::Title:
129 return tr( "Title" );
130 case Sections::Abstract:
131 return tr( "Abstract" );
132 case Sections::DataProviderName:
133 return tr( "Provider" );
134 case Sections::GeometryType:
135 return tr( "Layer Type" );
136 }
137 }
138 // other roles here ...
139 }
140 return QAbstractTableModel::headerData( section, orientation, role );
141}
142
143void QgsLayerMetadataResultsModel::reload()
144{
145 cancel();
146 beginResetModel();
147 // Load results from layer metadata providers
149 const QList<QgsAbstractLayerMetadataProvider *> providers { QgsApplication::instance()->layerMetadataProviderRegistry()->layerMetadataProviders() };
150 for ( QgsAbstractLayerMetadataProvider *mdProvider : std::as_const( providers ) )
151 {
152 const QList<QgsLayerMetadataProviderResult> results { mdProvider->search( mSearchContext ).metadata() };
153 for ( const QgsLayerMetadataProviderResult &metadata : std::as_const( results ) )
154 {
155 mResult.addMetadata( metadata );
156 }
157 }
158 endResetModel();
159}
160
161void QgsLayerMetadataResultsModel::reloadAsync()
162{
163 cancel();
164 beginResetModel();
165 // Load results from layer metadata providers
167 endResetModel();
168 mFeedback->setProgress( 0 );
169 const QList<QgsAbstractLayerMetadataProvider *> providers { QgsApplication::instance()->layerMetadataProviderRegistry()->layerMetadataProviders() };
170 for ( QgsAbstractLayerMetadataProvider *mdProvider : std::as_const( providers ) )
171 {
172 std::unique_ptr<QgsMetadataResultsFetcher> fetcher = std::make_unique<QgsMetadataResultsFetcher>( mdProvider, mSearchContext, mFeedback.get() );
173 std::unique_ptr<QThread> thread = std::make_unique<QThread>();
174 fetcher->moveToThread( thread.get() );
175 // Forward signals to the model
176 connect( fetcher.get(), &QgsMetadataResultsFetcher::resultsReady, this, [ = ]( const QgsLayerMetadataSearchResults & results )
177 {
178 resultsReady( results );
179 } );
180 connect( thread.get(), &QThread::started, fetcher.get(), &QgsMetadataResultsFetcher::fetchMetadata );
181 mWorkerThreads.push_back( std::move( thread ) );
182 mWorkers.push_back( std::move( fetcher ) );
183 mWorkerThreads.back()->start();
184 }
185}
186
187void QgsLayerMetadataResultsModel::resultsReady( const QgsLayerMetadataSearchResults &results )
188{
189 mFeedback->setProgress( mFeedback->progress() + static_cast< double >( 100 ) / QgsApplication::instance()->layerMetadataProviderRegistry()->layerMetadataProviders().count() );
190 beginInsertRows( QModelIndex(), mResult.metadata().count(), mResult.metadata().count() + results.metadata().count() - 1 );
191 const QList<QgsLayerMetadataProviderResult> metadata { results.metadata() };
192 for ( const QgsLayerMetadataProviderResult &result : std::as_const( metadata ) )
193 {
194 mResult.addMetadata( result );
195 }
196 endInsertRows();
197}
198
199void QgsLayerMetadataResultsModel::cancel()
200{
201 if ( mFeedback )
202 {
203 mFeedback->cancel();
204 }
205
206 for ( const auto &workerThread : std::as_const( mWorkerThreads ) )
207 {
208 workerThread->quit();
209 workerThread->wait();
210 }
211
212 mWorkers.clear();
213 mWorkerThreads.clear();
214
215 mFeedback = std::make_unique<QgsFeedback>();
216 connect( mFeedback.get(), &QgsFeedback::progressChanged, this, &QgsLayerMetadataResultsModel::progressChanged );
217}
218
219
221
222QgsMetadataResultsFetcher::QgsMetadataResultsFetcher( const QgsAbstractLayerMetadataProvider *metadataProvider, const QgsMetadataSearchContext &searchContext, QgsFeedback *feedback )
223 : mLayerMetadataProvider( metadataProvider )
224 , mSearchContext( searchContext )
225 , mFeedback( feedback )
226{
227}
228
229void QgsMetadataResultsFetcher::fetchMetadata()
230{
231 emit resultsReady( mLayerMetadataProvider->search( mSearchContext, QString(), QgsRectangle(), mFeedback ) );
232}
233
@ Unknown
Unknown types.
@ Null
No geometry.
@ Raster
Raster layer.
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:44
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.
Container of result records from a layer metadata search.
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.
Handles storage of information regarding WKB types and their properties.
Definition qgswkbtypes.h:42
static QString geometryDisplayString(Qgis::GeometryType type)
Returns a display string for a geometry type.