Skip to content

Commit e0d4e37

Browse files
committedMay 10, 2017
fix bugs relates to statistical dock (fix #16117, #16118, #16119)
backported from master
1 parent 4ae8065 commit e0d4e37

File tree

2 files changed

+183
-62
lines changed

2 files changed

+183
-62
lines changed
 

‎src/app/qgsstatisticalsummarydockwidget.cpp

Lines changed: 168 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717
#include "qgsmaplayerregistry.h"
1818
#include "qgisapp.h"
1919
#include "qgsmapcanvas.h"
20+
2021
#include <QTableWidget>
2122
#include <QAction>
2223
#include <QSettings>
24+
#include <QMenu>
2325

2426
QList< QgsStatisticalSummary::Statistic > QgsStatisticalSummaryDockWidget::mDisplayStats =
2527
QList< QgsStatisticalSummary::Statistic > () << QgsStatisticalSummary::Count
@@ -76,6 +78,7 @@ static QgsExpressionContext _getExpressionContext( const void* context )
7678
QgsStatisticalSummaryDockWidget::QgsStatisticalSummaryDockWidget( QWidget *parent )
7779
: QgsDockWidget( parent )
7880
, mLayer( nullptr )
81+
, mStatisticsMenu( nullptr )
7982
{
8083
setupUi( this );
8184

@@ -95,28 +98,12 @@ QgsStatisticalSummaryDockWidget::QgsStatisticalSummaryDockWidget( QWidget *paren
9598
connect( mButtonRefresh, SIGNAL( clicked( bool ) ), this, SLOT( refreshStatistics() ) );
9699
connect( QgsMapLayerRegistry::instance(), SIGNAL( layersWillBeRemoved( QStringList ) ), this, SLOT( layersRemoved( QStringList ) ) );
97100

98-
QSettings settings;
99-
Q_FOREACH ( QgsStatisticalSummary::Statistic stat, mDisplayStats )
100-
{
101-
QAction* action = new QAction( QgsStatisticalSummary::displayName( stat ), mOptionsToolButton );
102-
action->setCheckable( true );
103-
bool checked = settings.value( QString( "/StatisticalSummaryDock/checked_%1" ).arg( stat ), true ).toBool();
104-
action->setChecked( checked );
105-
action->setData( stat );
106-
mStatsActions.insert( stat, action );
107-
connect( action, SIGNAL( triggered( bool ) ), this, SLOT( statActionTriggered( bool ) ) );
108-
mOptionsToolButton->addAction( action );
109-
}
101+
mStatisticsMenu = new QMenu( mOptionsToolButton );
102+
mOptionsToolButton->setMenu( mStatisticsMenu );
110103

111-
//count of null values statistic:
112-
QAction* nullCountAction = new QAction( tr( "Missing (null) values" ), mOptionsToolButton );
113-
nullCountAction->setCheckable( true );
114-
bool checked = settings.value( QString( "/StatisticalSummaryDock/checked_missing_values" ), true ).toBool();
115-
nullCountAction->setChecked( checked );
116-
nullCountAction->setData( MISSING_VALUES );
117-
mStatsActions.insert( MISSING_VALUES, nullCountAction );
118-
connect( nullCountAction, SIGNAL( triggered( bool ) ), this, SLOT( statActionTriggered( bool ) ) );
119-
mOptionsToolButton->addAction( nullCountAction );
104+
mFieldType = DataType::Numeric;
105+
mPreviousFieldType = DataType::Numeric;
106+
refreshStatisticsMenu();
120107
}
121108

122109
QgsStatisticalSummaryDockWidget::~QgsStatisticalSummaryDockWidget()
@@ -132,39 +119,34 @@ void QgsStatisticalSummaryDockWidget::refreshStatistics()
132119
return;
133120
}
134121

135-
// non numeric field?
136-
bool isNumeric = true;
137-
QVariant::Type fieldType = QVariant::Double;
122+
// determine field type
123+
mFieldType = DataType::Numeric;
138124
if ( !mFieldExpressionWidget->isExpression() )
139125
{
140-
QString field = mFieldExpressionWidget->currentField();
141-
fieldType = mLayer->fields().field( mLayer->fields().fieldNameIndex( field ) ).type();
142-
if ( fieldType == QVariant::String || fieldType == QVariant::Date || fieldType == QVariant::DateTime )
143-
{
144-
isNumeric = false;
145-
}
126+
mFieldType = fieldType( mFieldExpressionWidget->currentField() );
146127
}
147128

148-
bool selectedOnly = mSelectedOnlyCheckBox->isChecked();
149-
150-
if ( isNumeric )
129+
if ( mFieldType != mPreviousFieldType )
151130
{
152-
updateNumericStatistics( selectedOnly );
131+
refreshStatisticsMenu();
132+
mPreviousFieldType = mFieldType;
153133
}
154-
else
134+
135+
bool selectedOnly = mSelectedOnlyCheckBox->isChecked();
136+
137+
switch ( mFieldType )
155138
{
156-
switch ( fieldType )
157-
{
158-
case QVariant::String:
159-
updateStringStatistics( selectedOnly );
160-
break;
161-
case QVariant::Date:
162-
case QVariant::DateTime:
163-
updateDateTimeStatistics( selectedOnly );
164-
break;
165-
default:
166-
break;
167-
}
139+
case DataType::Numeric:
140+
updateNumericStatistics( selectedOnly );
141+
break;
142+
case DataType::String:
143+
updateStringStatistics( selectedOnly );
144+
break;
145+
case DataType::DateTime:
146+
updateDateTimeStatistics( selectedOnly );
147+
break;
148+
default:
149+
break;
168150
}
169151
}
170152

@@ -234,15 +216,26 @@ void QgsStatisticalSummaryDockWidget::updateStringStatistics( bool selectedOnly
234216
return;
235217
}
236218

219+
QList< QgsStringStatisticalSummary::Statistic > statsToDisplay;
220+
QgsStringStatisticalSummary::Statistics statsToCalc = 0;
221+
Q_FOREACH ( QgsStringStatisticalSummary::Statistic stat, mDisplayStringStats )
222+
{
223+
if ( mStatsActions.value( stat )->isChecked() )
224+
{
225+
statsToDisplay << stat;
226+
statsToCalc |= stat;
227+
}
228+
}
229+
237230
QgsStringStatisticalSummary stats;
238-
stats.setStatistics( QgsStringStatisticalSummary::All );
231+
stats.setStatistics( statsToCalc );
239232
stats.calculateFromVariants( values );
240233

241-
mStatisticsTable->setRowCount( mDisplayStringStats.count() );
234+
mStatisticsTable->setRowCount( statsToDisplay.count() );
242235
mStatisticsTable->setColumnCount( 2 );
243236

244237
int row = 0;
245-
Q_FOREACH ( QgsStringStatisticalSummary::Statistic stat, mDisplayStringStats )
238+
Q_FOREACH ( QgsStringStatisticalSummary::Statistic stat, statsToDisplay )
246239
{
247240
addRow( row, QgsStringStatisticalSummary::displayName( stat ),
248241
stats.statistic( stat ).toString(),
@@ -280,19 +273,37 @@ void QgsStatisticalSummaryDockWidget::layerChanged( QgsMapLayer *layer )
280273

281274
void QgsStatisticalSummaryDockWidget::statActionTriggered( bool checked )
282275
{
283-
refreshStatistics();
284276
QAction* action = dynamic_cast<QAction*>( sender() );
285277
int stat = action->data().toInt();
286278

279+
QString settingsKey;
280+
switch ( mFieldType )
281+
{
282+
case DataType::Numeric:
283+
settingsKey = "numeric";
284+
break;
285+
case DataType::String:
286+
settingsKey = "string";
287+
break;
288+
case DataType::DateTime:
289+
settingsKey = "datetime";
290+
break;
291+
default:
292+
break;
293+
}
294+
295+
287296
QSettings settings;
288297
if ( stat >= 0 )
289298
{
290-
settings.setValue( QString( "/StatisticalSummaryDock/checked_%1" ).arg( stat ), checked );
299+
settings.setValue( QString( "/StatisticalSummaryDock/%1_%2" ).arg( settingsKey ).arg( stat ), checked );
291300
}
292301
else if ( stat == MISSING_VALUES )
293302
{
294-
settings.setValue( QString( "/StatisticalSummaryDock/checked_missing_values" ).arg( stat ), checked );
303+
settings.setValue( QString( "/StatisticalSummaryDock/numeric_missing_values" ), checked );
295304
}
305+
306+
refreshStatistics();
296307
}
297308

298309
void QgsStatisticalSummaryDockWidget::layersRemoved( const QStringList& layers )
@@ -322,15 +333,26 @@ void QgsStatisticalSummaryDockWidget::updateDateTimeStatistics( bool selectedOnl
322333
return;
323334
}
324335

336+
QList< QgsDateTimeStatisticalSummary::Statistic > statsToDisplay;
337+
QgsDateTimeStatisticalSummary::Statistics statsToCalc = 0;
338+
Q_FOREACH ( QgsDateTimeStatisticalSummary::Statistic stat, mDisplayDateTimeStats )
339+
{
340+
if ( mStatsActions.value( stat )->isChecked() )
341+
{
342+
statsToDisplay << stat;
343+
statsToCalc |= stat;
344+
}
345+
}
346+
325347
QgsDateTimeStatisticalSummary stats;
326-
stats.setStatistics( QgsDateTimeStatisticalSummary::All );
348+
stats.setStatistics( statsToCalc );
327349
stats.calculate( values );
328350

329-
mStatisticsTable->setRowCount( mDisplayDateTimeStats.count() );
351+
mStatisticsTable->setRowCount( statsToDisplay.count() );
330352
mStatisticsTable->setColumnCount( 2 );
331353

332354
int row = 0;
333-
Q_FOREACH ( QgsDateTimeStatisticalSummary::Statistic stat, mDisplayDateTimeStats )
355+
Q_FOREACH ( QgsDateTimeStatisticalSummary::Statistic stat, statsToDisplay )
334356
{
335357
QString value = ( stat == QgsDateTimeStatisticalSummary::Range
336358
? tr( "%1 seconds" ).arg( stats.range().seconds() )
@@ -361,3 +383,93 @@ void QgsStatisticalSummaryDockWidget::addRow( int row, const QString& name, cons
361383
mStatisticsTable->setItem( row, 1, valueItem );
362384
}
363385

386+
void QgsStatisticalSummaryDockWidget::refreshStatisticsMenu()
387+
{
388+
mStatisticsMenu->clear();
389+
mStatsActions.clear();
390+
391+
QSettings settings;
392+
switch ( mFieldType )
393+
{
394+
case DataType::Numeric:
395+
{
396+
Q_FOREACH ( QgsStatisticalSummary::Statistic stat, mDisplayStats )
397+
{
398+
QAction *action = new QAction( QgsStatisticalSummary::displayName( stat ), mStatisticsMenu );
399+
action->setCheckable( true );
400+
bool checked = settings.value( QString( "StatisticalSummaryDock/numeric_%1" ).arg( stat ), true ).toBool();
401+
action->setChecked( checked );
402+
action->setData( stat );
403+
mStatsActions.insert( stat, action );
404+
connect( action, SIGNAL( triggered( bool ) ), this, SLOT( statActionTriggered( bool ) ) );
405+
mStatisticsMenu->addAction( action );
406+
}
407+
408+
//count of null values statistic
409+
QAction *nullCountAction = new QAction( tr( "Missing (null) values" ), mStatisticsMenu );
410+
nullCountAction->setCheckable( true );
411+
bool checked = settings.value( QString( "StatisticalSummaryDock/numeric_missing_values" ), true ).toBool();
412+
nullCountAction->setChecked( checked );
413+
nullCountAction->setData( MISSING_VALUES );
414+
mStatsActions.insert( MISSING_VALUES, nullCountAction );
415+
connect( nullCountAction, SIGNAL( triggered( bool ) ), this, SLOT( statActionTriggered( bool ) ) );
416+
mStatisticsMenu->addAction( nullCountAction );
417+
418+
break;
419+
}
420+
case DataType::String:
421+
{
422+
Q_FOREACH ( QgsStringStatisticalSummary::Statistic stat, mDisplayStringStats )
423+
{
424+
QAction *action = new QAction( QgsStringStatisticalSummary::displayName( stat ), mStatisticsMenu );
425+
action->setCheckable( true );
426+
bool checked = settings.value( QString( "StatisticalSummaryDock/string_%1" ).arg( stat ), true ).toBool();
427+
action->setChecked( checked );
428+
action->setData( stat );
429+
mStatsActions.insert( stat, action );
430+
connect( action, SIGNAL( triggered( bool ) ), this, SLOT( statActionTriggered( bool ) ) );
431+
mStatisticsMenu->addAction( action );
432+
}
433+
break;
434+
}
435+
case DataType::DateTime:
436+
{
437+
Q_FOREACH ( QgsDateTimeStatisticalSummary::Statistic stat, mDisplayDateTimeStats )
438+
{
439+
QAction *action = new QAction( QgsDateTimeStatisticalSummary::displayName( stat ), mStatisticsMenu );
440+
action->setCheckable( true );
441+
bool checked = settings.value( QString( "StatisticalSummaryDock/datetime_%1" ).arg( stat ), true ).toBool();
442+
action->setChecked( checked );
443+
action->setData( stat );
444+
mStatsActions.insert( stat, action );
445+
connect( action, SIGNAL( triggered( bool ) ), this, SLOT( statActionTriggered( bool ) ) );
446+
mStatisticsMenu->addAction( action );
447+
}
448+
break;
449+
}
450+
default:
451+
break;
452+
}
453+
}
454+
455+
QgsStatisticalSummaryDockWidget::DataType QgsStatisticalSummaryDockWidget::fieldType( const QString &fieldName )
456+
{
457+
QgsField field = mLayer->fields().field( fieldName );
458+
if ( field.isNumeric() )
459+
{
460+
return DataType::Numeric;
461+
}
462+
463+
switch ( field.type() )
464+
{
465+
case QVariant::String:
466+
return DataType::String;
467+
case QVariant::Date:
468+
case QVariant::DateTime:
469+
return DataType::DateTime;
470+
default:
471+
break;
472+
}
473+
474+
return DataType::Numeric;
475+
}

‎src/app/qgsstatisticalsummarydockwidget.h

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,7 @@
2323
#include "qgsdatetimestatisticalsummary.h"
2424
#include "qgsdockwidget.h"
2525

26-
class QgsBrowserModel;
27-
class QModelIndex;
28-
class QgsDockBrowserTreeView;
29-
class QgsLayerItem;
30-
class QgsDataItem;
31-
class QgsBrowserTreeFilterProxyModel;
26+
class QMenu;
3227

3328
/** A dock widget which displays a statistical summary of the values in a field or expression
3429
*/
@@ -60,7 +55,18 @@ class APP_EXPORT QgsStatisticalSummaryDockWidget : public QgsDockWidget, private
6055

6156
private:
6257

58+
//! Enumeration of supported statistics types
59+
enum DataType
60+
{
61+
Numeric, //!< Numeric fields: int, double, etc
62+
String, //!< String fields
63+
DateTime //!< Date and DateTime fields
64+
};
65+
6366
QgsVectorLayer* mLayer;
67+
QMenu *mStatisticsMenu;
68+
DataType mFieldType;
69+
DataType mPreviousFieldType;
6470

6571
QMap< int, QAction* > mStatsActions;
6672
static QList< QgsStatisticalSummary::Statistic > mDisplayStats;
@@ -71,6 +77,9 @@ class APP_EXPORT QgsStatisticalSummaryDockWidget : public QgsDockWidget, private
7177
void updateStringStatistics( bool selectedOnly );
7278
void updateDateTimeStatistics( bool selectedOnly );
7379
void addRow( int row, const QString& name, const QString& value, bool showValue );
80+
void refreshStatisticsMenu();
81+
DataType fieldType( const QString &fieldName );
82+
7483
};
7584

7685
#endif // QGSSTATISTICALSUMMARYDOCKWIDGET_H

0 commit comments

Comments
 (0)
Please sign in to comment.