QGIS API Documentation 3.41.0-Master (45a0abf3bec)
Loading...
Searching...
No Matches
qgsvaliditycheckresultswidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsvaliditycheckresultswidget.cpp
3 ----------------------------------
4 begin : November 2018
5 copyright : (C) 2018 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17#include "moc_qgsvaliditycheckresultswidget.cpp"
19#include "qgsapplication.h"
20#include "qgsfeedback.h"
22#include <QProgressDialog>
23#include <QDialogButtonBox>
24#include <QPushButton>
25
26//
27// QgsValidityCheckResultsModel
28//
29
30QgsValidityCheckResultsModel::QgsValidityCheckResultsModel( const QList<QgsValidityCheckResult> &results, QObject *parent )
31 : QAbstractItemModel( parent )
32 , mResults( results )
33{
34
35}
36
37QModelIndex QgsValidityCheckResultsModel::index( int row, int column, const QModelIndex &parent ) const
38{
39 Q_UNUSED( parent )
40 return createIndex( row, column );
41}
42
43QModelIndex QgsValidityCheckResultsModel::parent( const QModelIndex &child ) const
44{
45 Q_UNUSED( child )
46 return QModelIndex();
47}
48
49int QgsValidityCheckResultsModel::rowCount( const QModelIndex &parent ) const
50{
51 Q_UNUSED( parent )
52 return mResults.count();
53}
54
55int QgsValidityCheckResultsModel::columnCount( const QModelIndex &parent ) const
56{
57 Q_UNUSED( parent )
58 return 1;
59}
60
61QVariant QgsValidityCheckResultsModel::data( const QModelIndex &index, int role ) const
62{
63 if ( index.row() >= mResults.count() || index.row() < 0 )
64 return QVariant();
65
66 const QgsValidityCheckResult &res = mResults.at( index.row() );
67 switch ( role )
68 {
69 case Qt::DisplayRole:
70 case Qt::ToolTipRole:
71 return res.title;
72
74 return res.detailedDescription;
75
76 case Qt::DecorationRole:
77 switch ( res.type )
78 {
80 return QgsApplication::getThemeIcon( QStringLiteral( "/mIconCritical.svg" ) );
81
83 return QgsApplication::getThemeIcon( QStringLiteral( "/mIconWarning.svg" ) );
84 }
85 break;
86
87 default:
88 return QVariant();
89 }
90 return QVariant();
91}
92
93//
94// QgsValidityCheckResultsWidget
95//
96
98 : QWidget( parent )
99{
100 setupUi( this );
101
102}
103
104void QgsValidityCheckResultsWidget::setResults( const QList<QgsValidityCheckResult> &results )
105{
106 if ( mResultsModel )
107 mResultsModel->deleteLater();
108
109 mResultsModel = new QgsValidityCheckResultsModel( results, this );
110 mResultsListView->setModel( mResultsModel );
111
112 connect( mResultsListView->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsValidityCheckResultsWidget::selectionChanged );
113
114 if ( mResultsModel->rowCount() > 0 )
115 {
116 // auto select first result in list
117 const QModelIndex firstResult( mResultsModel->index( 0, 0, QModelIndex() ) );
118 mResultsListView->selectionModel()->select( firstResult, QItemSelectionModel::ClearAndSelect );
119 selectionChanged( firstResult, QModelIndex() );
120 }
121
122 mDescriptionLabel->hide();
123}
124
125void QgsValidityCheckResultsWidget::setDescription( const QString &description )
126{
127 mDescriptionLabel->setText( description );
128 mDescriptionLabel->setVisible( !description.isEmpty() );
129}
130
131bool QgsValidityCheckResultsWidget::runChecks( int type, const QgsValidityCheckContext *context, const QString &title, const QString &description, QWidget *parent )
132{
133 std::unique_ptr< QgsFeedback > feedback = std::make_unique< QgsFeedback >();
134 std::unique_ptr< QProgressDialog > progressDialog = std::make_unique< QProgressDialog >( tr( "Running Checks…" ), tr( "Abort" ), 0, 100, parent );
135 progressDialog->setWindowTitle( title );
136
137 QgsProxyProgressTask *proxyTask = new QgsProxyProgressTask( tr( "Running Checks" ) );
138
139 connect( feedback.get(), &QgsFeedback::progressChanged, progressDialog.get(), [ & ]( double progress )
140 {
141 progressDialog->setValue( static_cast< int >( progress ) );
142 progressDialog->setLabelText( feedback->property( "progress" ).toString() ) ;
143
144 proxyTask->setProxyProgress( progress );
145
146#ifdef Q_OS_LINUX
147 // One iteration is actually enough on Windows to get good interactivity
148 // whereas on Linux we must allow for far more iterations.
149 int nIters = 0;
150 while ( ++nIters < 100 )
151#endif
152 {
153 QCoreApplication::processEvents();
154 }
155
156 } );
157 connect( progressDialog.get(), &QProgressDialog::canceled, progressDialog.get(), [ & ]
158 {
159 feedback->cancel();
160 } );
161
162 QgsApplication::taskManager()->addTask( proxyTask );
163
164 const QList<QgsValidityCheckResult> results = QgsApplication::validityCheckRegistry()->runChecks( type, context, feedback.get() );
165
166 proxyTask->finalize( true );
167
168 if ( feedback->isCanceled() )
169 return false;
170
171 if ( results.empty() )
172 return true;
173
175 w->setResults( results );
176 w->setDescription( description );
177
178 bool hasCritical = false;
179 for ( const QgsValidityCheckResult &res : results )
180 {
181 if ( res.type == QgsValidityCheckResult::Critical )
182 {
183 hasCritical = true;
184 break;
185 }
186 }
187
188 QVBoxLayout *l = new QVBoxLayout();
189 l->addWidget( w );
190
191 QDialog dlg( parent );
192 dlg.setWindowTitle( title );
193
194 QDialogButtonBox *buttons = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dlg );
195 connect( buttons, &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
196 connect( buttons, &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
197 if ( hasCritical )
198 {
199 buttons->button( QDialogButtonBox::Ok )->setEnabled( false );
200 buttons->button( QDialogButtonBox::Ok )->setToolTip( tr( "Critical errors prevent this task from proceeding. Please address these issues and then retry." ) );
201 }
202
203 l->addWidget( buttons );
204
205 dlg.setLayout( l );
206
207 return dlg.exec();
208}
209
210void QgsValidityCheckResultsWidget::selectionChanged( const QModelIndex &current, const QModelIndex & )
211{
212 const QString desc = mResultsModel->data( current, static_cast< int >( QgsValidityCheckResultsModel::CustomRole::Description ) ).toString();
213 mDetailedDescriptionTextBrowser->setHtml( desc );
214}
static QgsValidityCheckRegistry * validityCheckRegistry()
Returns the application's validity check registry, used for managing validity checks.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QgsTaskManager * taskManager()
Returns the application's task manager, used for managing application wide background task handling.
void progressChanged(double progress)
Emitted when the feedback object reports a progress change.
A QgsTask shell which proxies progress reports.
long addTask(QgsTask *task, int priority=0)
Adds a task to the manager.
Base class for validity check contexts.
QList< QgsValidityCheckResult > runChecks(int type, const QgsValidityCheckContext *context, QgsFeedback *feedback) const
Runs all checks of the specified type and returns a list of results.
Represents an individual result from a validity check run by a QgsAbstractValidityCheck subclass.
@ Critical
Critical error - notify user of result and prevent operation from proceeding.
@ Warning
Warning only, allow operation to proceed but notify user of result.
QString detailedDescription
Detailed description of the result (translated), giving users enough detail for them to resolve the e...
QString title
A short, translated string summarising the result.
A QAbstractItemModel subclass for displaying the results from a QgsAbstractValidityCheck.
QgsValidityCheckResultsModel(const QList< QgsValidityCheckResult > &results, QObject *parent=nullptr)
Constructor for QgsValidityCheckResultsModel, showing the specified list of checks results.
QModelIndex parent(const QModelIndex &child) const override
QModelIndex index(int row, int column, const QModelIndex &parent) const override
@ Description
Result detailed description.
int columnCount(const QModelIndex &parent) const override
QVariant data(const QModelIndex &index, int role) const override
int rowCount(const QModelIndex &parent=QModelIndex()) const override
A reusable widget which displays a summary of the results from a QgsAbstractValidityCheck (or checks)...
QgsValidityCheckResultsWidget(QWidget *parent)
Constructor for QgsValidityCheckResultsWidget, with the specified parent widget.
void setDescription(const QString &description)
Sets a description label to show at the top of the widget, e.g.
static bool runChecks(int type, const QgsValidityCheckContext *context, const QString &title, const QString &description, QWidget *parent=nullptr)
Runs all registered validity checks of the given type, and if any warnings or critical errors are enc...
void setResults(const QList< QgsValidityCheckResult > &results)
Sets the list of check results to show in the dialog.