2
2
3
3
#include " qgsvectorlayer.h"
4
4
5
+ #include < QIcon>
6
+
5
7
QgsGeometryValidationModel::QgsGeometryValidationModel ( QgsGeometryValidationService *geometryValidationService, QObject *parent )
6
8
: QAbstractItemModel( parent )
7
9
, mGeometryValidationService( geometryValidationService )
8
10
{
9
-
11
+ connect ( mGeometryValidationService , &QgsGeometryValidationService::geometryCheckCompleted, this , &QgsGeometryValidationModel::onGeometryCheckCompleted );
12
+ connect ( mGeometryValidationService , &QgsGeometryValidationService::geometryCheckStarted, this , &QgsGeometryValidationModel::onGeometryCheckStarted );
10
13
}
11
14
12
15
QModelIndex QgsGeometryValidationModel::index ( int row, int column, const QModelIndex &parent ) const
@@ -24,7 +27,7 @@ QModelIndex QgsGeometryValidationModel::parent( const QModelIndex &child ) const
24
27
int QgsGeometryValidationModel::rowCount ( const QModelIndex &parent ) const
25
28
{
26
29
Q_UNUSED ( parent )
27
- return mGeometryValidationService -> featureErrors ( mCurrentLayer ).size ();
30
+ return mErrorStorage . value ( mCurrentLayer ).size ();
28
31
}
29
32
30
33
int QgsGeometryValidationModel::columnCount ( const QModelIndex &parent ) const
@@ -35,14 +38,37 @@ int QgsGeometryValidationModel::columnCount( const QModelIndex &parent ) const
35
38
36
39
QVariant QgsGeometryValidationModel::data ( const QModelIndex &index, int role ) const
37
40
{
41
+ const auto &layerErrors = mErrorStorage .value ( mCurrentLayer );
42
+
43
+ const auto &featureItem = layerErrors.at ( index .row () );
44
+
38
45
switch ( role )
39
46
{
40
47
case Qt::DisplayRole:
41
- QgsGeometryValidationService::FeatureError error = mGeometryValidationService -> featureError ( mCurrentLayer , index . row () );
42
- QgsFeature feature = mCurrentLayer ->getFeature ( error. featureId );
48
+ {
49
+ QgsFeature feature = mCurrentLayer ->getFeature ( featureItem. fid ); // TODO: this should be cached!
43
50
mExpressionContext .setFeature ( feature );
44
51
QString featureTitle = mDisplayExpression .evaluate ( &mExpressionContext ).toString ();
45
- return QStringLiteral ( " <b>%1</b>: %2" ).arg ( featureTitle, error.error .what () );
52
+ if ( featureTitle.isEmpty () )
53
+ featureTitle = featureItem.fid ;
54
+
55
+ if ( featureItem.errors .count () > 1 )
56
+ return tr ( " %1: %n Errors" , " " , featureItem.errors .count () ).arg ( featureTitle );
57
+ else if ( featureItem.errors .count () == 1 )
58
+ return tr ( " %1: %2" ).arg ( featureTitle, featureItem.errors .at ( 0 ).what () );
59
+ #if 0
60
+ else
61
+ return tr( "%1: No Errors" ).arg( featureTitle );
62
+ #endif
63
+ }
64
+
65
+ case Qt::DecorationRole:
66
+ {
67
+ if ( mGeometryValidationService ->validationActive ( mCurrentLayer , featureItem.fid ) )
68
+ return QgsApplication::getThemeIcon ( " /mActionTracing.svg" );
69
+ else
70
+ return QVariant ();
71
+ }
46
72
}
47
73
48
74
return QVariant ();
@@ -60,8 +86,90 @@ void QgsGeometryValidationModel::setCurrentLayer( QgsVectorLayer *currentLayer )
60
86
61
87
beginResetModel ();
62
88
mCurrentLayer = currentLayer;
63
- mDisplayExpression = mCurrentLayer ->displayExpression ();
64
- mExpressionContext = QgsExpressionContext ( QgsExpressionContextUtils::globalProjectLayerScopes ( mCurrentLayer ) );
65
- mDisplayExpression .prepare ( &mExpressionContext );
89
+ if ( mCurrentLayer )
90
+ {
91
+ mDisplayExpression = mCurrentLayer ? mCurrentLayer ->displayExpression () : QString ();
92
+ mExpressionContext = QgsExpressionContext ( QgsExpressionContextUtils::globalProjectLayerScopes ( mCurrentLayer ) );
93
+ mDisplayExpression .prepare ( &mExpressionContext );
94
+ }
95
+ else
96
+ {
97
+ mDisplayExpression = QString ();
98
+ mExpressionContext = QgsExpressionContext ();
99
+ }
66
100
endResetModel ();
67
101
}
102
+
103
+ void QgsGeometryValidationModel::onGeometryCheckCompleted ( QgsVectorLayer *layer, QgsFeatureId fid, const QList<QgsGeometry::Error> &errors )
104
+ {
105
+ auto &layerErrors = mErrorStorage [layer];
106
+
107
+ int featureIdx = errorsForFeature ( layer, fid );
108
+
109
+ // The last check for this feature finished: remove
110
+ if ( featureIdx > -1 && errors.empty () && !mGeometryValidationService ->validationActive ( layer, fid ) )
111
+ {
112
+ if ( mCurrentLayer == layer )
113
+ beginRemoveRows ( QModelIndex (), featureIdx, featureIdx );
114
+
115
+ layerErrors.removeAt ( featureIdx );
116
+
117
+ if ( mCurrentLayer == layer )
118
+ endRemoveRows ();
119
+ }
120
+ else if ( !errors.empty () )
121
+ {
122
+ // a new or updated feature
123
+ if ( featureIdx == -1 )
124
+ {
125
+ featureIdx = layerErrors.count ();
126
+ if ( mCurrentLayer == layer )
127
+ beginInsertRows ( QModelIndex (), featureIdx, featureIdx );
128
+
129
+ layerErrors << FeatureErrors ( fid );
130
+
131
+ if ( mCurrentLayer == layer )
132
+ endInsertRows ();
133
+ }
134
+
135
+ auto &featureItem = layerErrors[featureIdx];
136
+ featureItem.errors .append ( errors );
137
+ if ( mCurrentLayer == layer )
138
+ {
139
+ QModelIndex modelIndex = index ( featureIdx, 0 , QModelIndex () );
140
+ emit dataChanged ( modelIndex, modelIndex );
141
+ }
142
+ }
143
+ }
144
+
145
+ void QgsGeometryValidationModel::onGeometryCheckStarted ( QgsVectorLayer *layer, QgsFeatureId fid )
146
+ {
147
+ auto &layerErrors = mErrorStorage [layer];
148
+ int featureIdx = errorsForFeature ( layer, fid );
149
+ if ( featureIdx != -1 )
150
+ {
151
+ auto &featureItem = layerErrors[featureIdx];
152
+
153
+ featureItem.errors .clear ();
154
+
155
+ if ( mCurrentLayer == layer )
156
+ {
157
+ QModelIndex modelIndex = index ( featureIdx, 0 , QModelIndex () );
158
+ emit dataChanged ( modelIndex, modelIndex );
159
+ }
160
+ }
161
+ }
162
+
163
+ int QgsGeometryValidationModel::errorsForFeature ( QgsVectorLayer *layer, QgsFeatureId fid )
164
+ {
165
+ const auto &layerErrors = mErrorStorage [layer];
166
+ int idx = 0 ;
167
+
168
+ for ( const auto &feature : layerErrors )
169
+ {
170
+ if ( feature.fid == fid )
171
+ return idx;
172
+ idx++;
173
+ }
174
+ return -1 ;
175
+ }
0 commit comments