QList<QgsSymbol *> QgsGraduatedSymbolRendererWidget::selectedSymbols() { QList<QgsSymbol *> selectedSymbols; QItemSelectionModel *m = viewGraduated->selectionModel(); QModelIndexList selectedIndexes = m->selectedRows( 1 ); if ( m && !selectedIndexes.isEmpty() ) { const QgsRangeList &ranges = mRenderer->ranges(); QModelIndexList::const_iterator indexIt = selectedIndexes.constBegin(); for ( ; indexIt != selectedIndexes.constEnd(); ++indexIt ) { QStringList list = m->model()->data( *indexIt ).toString().split( ' ' ); if ( list.size() < 3 ) { continue; } // Not strictly necessary because the range should have been sanitized already // after user input, but being permissive never hurts bool ok = false; double lowerBound = qgsPermissiveToDouble( list.at( 0 ), ok ); if ( ! ok ) lowerBound = 0.0; double upperBound = qgsPermissiveToDouble( list.at( 2 ), ok ); if ( ! ok ) upperBound = 0.0; QgsSymbol *s = findSymbolForRange( lowerBound, upperBound, ranges ); if ( s ) { selectedSymbols.append( s ); } } } return selectedSymbols; }
void QgsGraduatedSymbolRendererWidget::changeRange( int rangeIdx ) { QgsLUDialog dialog( this ); const QgsRendererRange &range = mRenderer->ranges()[rangeIdx]; // Add arbitrary 2 to number of decimal places to retain a bit extra. // Ensures users can see if legend is not completely honest! int decimalPlaces = mRenderer->labelFormat().precision() + 2; if ( decimalPlaces < 0 ) decimalPlaces = 0; dialog.setLowerValue( QLocale().toString( range.lowerValue(), 'f', decimalPlaces ) ); dialog.setUpperValue( QLocale().toString( range.upperValue(), 'f', decimalPlaces ) ); if ( dialog.exec() == QDialog::Accepted ) { bool ok = false; double lowerValue = qgsPermissiveToDouble( dialog.lowerValue(), ok ); if ( ! ok ) lowerValue = 0.0; double upperValue = qgsPermissiveToDouble( dialog.upperValue(), ok ); if ( ! ok ) upperValue = 0.0; mRenderer->updateRangeUpperValue( rangeIdx, upperValue ); mRenderer->updateRangeLowerValue( rangeIdx, lowerValue ); //If the boundaries have to stay linked, we update the ranges above and below, as well as their label if needed if ( cbxLinkBoundaries->isChecked() ) { if ( rangeIdx > 0 ) { mRenderer->updateRangeUpperValue( rangeIdx - 1, lowerValue ); } if ( rangeIdx < mRenderer->ranges().size() - 1 ) { mRenderer->updateRangeLowerValue( rangeIdx + 1, upperValue ); } } } mHistogramWidget->refresh(); emit widgetChanged(); }
double QgsScaleComboBox::toDouble( const QString &scaleString, bool *returnOk ) { bool ok = false; QString scaleTxt( scaleString ); double denominator = qgsPermissiveToDouble( scaleTxt, ok ); double scale = !qgsDoubleNear( denominator, 0.0 ) ? 1.0 / denominator : 0.0; if ( ok ) { // Create a text version and set that text and rescan // Idea is to get the same rounding. scaleTxt = toString( scale ); } else { // It is now either X:Y or not valid QStringList txtList = scaleTxt.split( ':' ); if ( 2 == txtList.size() ) { bool okX = false; bool okY = false; int x = qgsPermissiveToInt( txtList[ 0 ], okX ); int y = qgsPermissiveToInt( txtList[ 1 ], okY ); if ( okX && okY && x != 0 ) { // Scale is fraction of x and y scale = static_cast< double >( y ) / static_cast< double >( x ); ok = true; } } } // Set up optional return flag if ( returnOk ) { *returnOk = ok; } return scale; }
bool QgsField::convertCompatible( QVariant &v ) const { if ( v.isNull() ) { v.convert( d->type ); return true; } if ( d->type == QVariant::Int && v.toInt() != v.toLongLong() ) { v = QVariant( d->type ); return false; } // Give it a chance to convert to double since for not '.' locales // we accept both comma and dot as decimal point if ( d->type == QVariant::Double && v.type() == QVariant::String ) { QVariant tmp( v ); if ( !tmp.convert( d->type ) ) { // This might be a string with thousand separator: use locale to convert bool ok = false; double d = qgsPermissiveToDouble( v.toString(), ok ); if ( ok ) { v = QVariant( d ); return true; } // For not 'dot' locales, we also want to accept '.' if ( QLocale().decimalPoint() != '.' ) { d = QLocale( QLocale::C ).toDouble( v.toString(), &ok ); if ( ok ) { v = QVariant( d ); return true; } } } } // For string representation of an int we also might have thousand separator if ( d->type == QVariant::Int && v.type() == QVariant::String ) { QVariant tmp( v ); if ( !tmp.convert( d->type ) ) { // This might be a string with thousand separator: use locale to convert bool ok; int i = qgsPermissiveToInt( v.toString(), ok ); if ( ok ) { v = QVariant( i ); return true; } } } // For string representation of a long we also might have thousand separator if ( d->type == QVariant::LongLong && v.type() == QVariant::String ) { QVariant tmp( v ); if ( !tmp.convert( d->type ) ) { // This might be a string with thousand separator: use locale to convert bool ok; qlonglong l = qgsPermissiveToLongLong( v.toString(), ok ); if ( ok ) { v = QVariant( l ); return true; } } } //String representations of doubles in QVariant will return false to convert( QVariant::Int ) //work around this by first converting to double, and then checking whether the double is convertible to int if ( d->type == QVariant::Int && v.canConvert( QVariant::Double ) ) { bool ok = false; double dbl = v.toDouble( &ok ); if ( !ok ) { //couldn't convert to number v = QVariant( d->type ); return false; } double round = std::round( dbl ); if ( round > std::numeric_limits<int>::max() || round < -std::numeric_limits<int>::max() ) { //double too large to fit in int v = QVariant( d->type ); return false; } v = QVariant( static_cast< int >( std::round( dbl ) ) ); return true; } if ( !v.convert( d->type ) ) { v = QVariant( d->type ); return false; } if ( d->type == QVariant::Double && d->precision > 0 ) { double s = std::pow( 10, d->precision ); double d = v.toDouble() * s; v = QVariant( ( d < 0 ? std::ceil( d - 0.5 ) : std::floor( d + 0.5 ) ) / s ); return true; } if ( d->type == QVariant::String && d->length > 0 && v.toString().length() > d->length ) { v = v.toString().left( d->length ); return false; } return true; }