1 /***************************************************************************
2     qgsrangeconfigdlgbase.cpp
3      --------------------------------------
4     Date                 : 5.1.2014
5     Copyright            : (C) 2014 Matthias Kuhn
6     Email                : matthias at opengis dot ch
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 
16 #include "qgsrangeconfigdlg.h"
17 
18 #include "qgsvectorlayer.h"
19 
QgsRangeConfigDlg(QgsVectorLayer * vl,int fieldIdx,QWidget * parent)20 QgsRangeConfigDlg::QgsRangeConfigDlg( QgsVectorLayer *vl, int fieldIdx, QWidget *parent )
21   : QgsEditorConfigWidget( vl, fieldIdx, parent )
22 {
23   setupUi( this );
24   precisionSpinBox->setClearValue( 4 );
25 
26   minimumSpinBox->setMinimum( std::numeric_limits<int>::lowest() );
27   minimumSpinBox->setMaximum( std::numeric_limits<int>::max() );
28   minimumSpinBox->setValue( std::numeric_limits<int>::lowest() );
29 
30   maximumSpinBox->setMinimum( std::numeric_limits<int>::lowest() );
31   maximumSpinBox->setMaximum( std::numeric_limits<int>::max() );
32   maximumSpinBox->setValue( std::numeric_limits<int>::max() );
33 
34   stepSpinBox->setMaximum( std::numeric_limits<int>::max() );
35   stepSpinBox->setValue( 1 );
36   stepSpinBox->setClearValue( 1 );
37 
38   minimumDoubleSpinBox->setMinimum( std::numeric_limits<double>::lowest() );
39   minimumDoubleSpinBox->setMaximum( std::numeric_limits<double>::max() );
40   minimumDoubleSpinBox->setValue( std::numeric_limits<double>::min() );
41 
42   maximumDoubleSpinBox->setMinimum( std::numeric_limits<double>::lowest() );
43   maximumDoubleSpinBox->setMaximum( std::numeric_limits<double>::max() );
44   maximumDoubleSpinBox->setValue( std::numeric_limits<double>::max() );
45 
46   // Use integer here:
47   stepDoubleSpinBox->setMaximum( std::numeric_limits<int>::max() );
48   stepDoubleSpinBox->setValue( 1 );
49   stepDoubleSpinBox->setClearValue( 1 );
50 
51 
52   QString text;
53 
54   const QVariant::Type fieldType( vl->fields().at( fieldIdx ).type() );
55 
56   switch ( fieldType )
57   {
58     case QVariant::Int:
59     case QVariant::LongLong:
60     case QVariant::Double:
61     {
62       // we use the double spin boxes for double OR long long field types, as QSpinBox does not have sufficient
63       // available range for long long values
64       rangeStackedWidget->setCurrentIndex( fieldType == QVariant::Int ? 0 : 1 );
65       if ( fieldType == QVariant::LongLong )
66       {
67         minimumDoubleSpinBox->setDecimals( 0 );
68         maximumDoubleSpinBox->setDecimals( 0 );
69         stepDoubleSpinBox->setDecimals( 0 );
70       }
71 
72       rangeWidget->clear();
73       rangeWidget->addItem( tr( "Editable" ), QStringLiteral( "SpinBox" ) );
74       rangeWidget->addItem( tr( "Slider" ), QStringLiteral( "Slider" ) );
75       rangeWidget->addItem( tr( "Dial" ), QStringLiteral( "Dial" ) );
76 
77       QVariant min;
78       QVariant max;
79       vl->minimumAndMaximumValue( fieldIdx, min, max );
80 
81       text = tr( "Current minimum for this value is %1 and current maximum is %2." ).arg( min.toString(), max.toString() );
82       break;
83     }
84 
85     default:
86       text = tr( "Attribute has no integer or real type, therefore range is not usable." );
87       break;
88   }
89 
90   // Hide precision for integer types
91   if ( fieldType != QVariant::Double )
92   {
93     precisionSpinBox->hide();
94     precisionLabel->hide();
95   }
96 
97   valuesLabel->setText( text );
98 
99   connect( rangeWidget, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRangeConfigDlg::rangeWidgetChanged );
100   connect( minimumSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsEditorConfigWidget::changed );
101   connect( maximumSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsEditorConfigWidget::changed );
102   connect( stepSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsEditorConfigWidget::changed );
103   connect( minimumDoubleSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsEditorConfigWidget::changed );
104   connect( maximumDoubleSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsEditorConfigWidget::changed );
105   connect( stepDoubleSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsEditorConfigWidget::changed );
106   connect( rangeWidget, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsEditorConfigWidget::changed );
107   connect( allowNullCheckBox, &QAbstractButton::toggled, this, &QgsEditorConfigWidget::changed );
108   connect( suffixLineEdit, &QLineEdit::textChanged, this, &QgsEditorConfigWidget::changed );
109 }
110 
config()111 QVariantMap QgsRangeConfigDlg::config()
112 {
113   QVariantMap cfg;
114 
115   switch ( layer()->fields().at( field() ).type() )
116   {
117     case QVariant::Int:
118       cfg.insert( QStringLiteral( "Min" ), minimumSpinBox->value() );
119       cfg.insert( QStringLiteral( "Max" ), maximumSpinBox->value() );
120       cfg.insert( QStringLiteral( "Step" ), stepSpinBox->value() );
121       break;
122 
123     // we use the double spin boxes for double OR long long field types, as QSpinBox does not have sufficient
124     // available range for long long values
125     case QVariant::Double:
126     case QVariant::LongLong:
127       cfg.insert( QStringLiteral( "Min" ), minimumDoubleSpinBox->value() );
128       cfg.insert( QStringLiteral( "Max" ), maximumDoubleSpinBox->value() );
129       cfg.insert( QStringLiteral( "Step" ), stepDoubleSpinBox->value() );
130       break;
131 
132     default:
133       break;
134   }
135 
136   cfg.insert( QStringLiteral( "Style" ), rangeWidget->currentData().toString() );
137   cfg.insert( QStringLiteral( "AllowNull" ), allowNullCheckBox->isChecked() );
138   cfg.insert( QStringLiteral( "Precision" ), precisionSpinBox->value() );
139 
140   if ( !suffixLineEdit->text().isEmpty() )
141   {
142     cfg.insert( QStringLiteral( "Suffix" ), suffixLineEdit->text() );
143   }
144 
145   return cfg;
146 }
147 
setConfig(const QVariantMap & config)148 void QgsRangeConfigDlg::setConfig( const QVariantMap &config )
149 {
150   minimumDoubleSpinBox->setValue( config.value( QStringLiteral( "Min" ), std::numeric_limits<double>::lowest() ).toDouble( ) );
151   maximumDoubleSpinBox->setValue( config.value( QStringLiteral( "Max" ), std::numeric_limits<double>::max() ).toDouble( ) );
152   stepDoubleSpinBox->setValue( config.value( QStringLiteral( "Step" ), 1.0 ).toDouble() );
153   minimumSpinBox->setValue( config.value( QStringLiteral( "Min" ), std::numeric_limits<int>::lowest() ).toInt() );
154   maximumSpinBox->setValue( config.value( QStringLiteral( "Max" ), std::numeric_limits<int>::max() ).toInt() );
155   stepSpinBox->setValue( config.value( QStringLiteral( "Step" ), 1 ).toInt() );
156   rangeWidget->setCurrentIndex( rangeWidget->findData( config.value( QStringLiteral( "Style" ), "SpinBox" ) ) );
157   suffixLineEdit->setText( config.value( QStringLiteral( "Suffix" ) ).toString() );
158   allowNullCheckBox->setChecked( config.value( QStringLiteral( "AllowNull" ), true ).toBool() );
159   precisionSpinBox->setValue( config.value( QStringLiteral( "Precision" ), layer()->fields().at( field() ).precision() ).toInt( ) );
160 }
161 
rangeWidgetChanged(int index)162 void QgsRangeConfigDlg::rangeWidgetChanged( int index )
163 {
164   const QString style = rangeWidget->itemData( index ).toString();
165   allowNullCheckBox->setEnabled( style == QLatin1String( "SpinBox" ) );
166 }
167