QGIS API Documentation  master-59fd5e0
src/gui/qgsscalecombobox.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                               qgsscalecombobox.h
00003                               ------------------------
00004   begin                : January 7, 2012
00005   copyright            : (C) 2012 by Alexander Bruy
00006   email                : alexander dot bruy at gmail dot com
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #include "qgis.h"
00019 #include "qgslogger.h"
00020 #include "qgsscalecombobox.h"
00021 
00022 #include <QAbstractItemView>
00023 #include <QLocale>
00024 #include <QSettings>
00025 #include <QLineEdit>
00026 
00027 QgsScaleComboBox::QgsScaleComboBox( QWidget* parent ) : QComboBox( parent ), mScale( 1.0 )
00028 {
00029   updateScales();
00030 
00031   setEditable( true );
00032   setInsertPolicy( QComboBox::NoInsert );
00033   setCompleter( 0 );
00034   connect( this, SIGNAL( activated( const QString & ) ), this, SLOT( fixupScale() ) );
00035   connect( lineEdit(), SIGNAL( editingFinished() ), this, SLOT( fixupScale() ) );
00036   fixupScale();
00037 }
00038 
00039 QgsScaleComboBox::~QgsScaleComboBox()
00040 {
00041 }
00042 
00043 void QgsScaleComboBox::updateScales( const QStringList &scales )
00044 {
00045   QStringList myScalesList;
00046   QString oldScale = currentText();
00047 
00048   if ( scales.isEmpty() )
00049   {
00050     QSettings settings;
00051     QString myScales = settings.value( "Map/scales", PROJECT_SCALES ).toString();
00052     if ( !myScales.isEmpty() )
00053     {
00054       myScalesList = myScales.split( "," );
00055     }
00056   }
00057   else
00058   {
00059     QStringList::const_iterator scaleIt = scales.constBegin();
00060     for ( ; scaleIt != scales.constEnd(); ++scaleIt )
00061     {
00062       myScalesList.append( *scaleIt );
00063     }
00064   }
00065 
00066   blockSignals( true );
00067   clear();
00068   addItems( myScalesList );
00069   setScaleString( oldScale );
00070   blockSignals( false );
00071 }
00072 
00073 void QgsScaleComboBox::showPopup()
00074 {
00075   QComboBox::showPopup();
00076 
00077   if ( !currentText().contains( ':' ) )
00078   {
00079     return;
00080   }
00081   QStringList parts = currentText().split( ':' );
00082   bool ok;
00083   int idx = 0;
00084   int min = 999999;
00085   long currScale = parts.at( 1 ).toLong( &ok );
00086   long nextScale, delta;
00087   for ( int i = 0; i < count(); i++ )
00088   {
00089     parts = itemText( i ).split( ':' );
00090     nextScale = parts.at( 1 ).toLong( &ok );
00091     delta = qAbs( currScale - nextScale );
00092     if ( delta < min )
00093     {
00094       min = delta;
00095       idx = i;
00096     }
00097   }
00098 
00099   blockSignals( true );
00100   view()->setCurrentIndex( model()->index( idx, 0 ) );
00101   blockSignals( false );
00102 }
00103 
00105 // @note added in 2.0
00106 QString QgsScaleComboBox::scaleString()
00107 {
00108   return toString( mScale );
00109 }
00110 
00112 // @note added in 2.0
00113 bool QgsScaleComboBox::setScaleString( QString scaleTxt )
00114 {
00115   bool ok;
00116   double newScale = toDouble( scaleTxt, &ok );
00117   if ( ! ok )
00118   {
00119     return false;
00120   }
00121   else
00122   {
00123     mScale = newScale;
00124     setEditText( toString( mScale ) );
00125     clearFocus();
00126     return true;
00127   }
00128 }
00129 
00131 // @note added in 2.0
00132 double QgsScaleComboBox::scale()
00133 {
00134   return mScale;
00135 }
00136 
00138 // @note added in 2.0
00139 void QgsScaleComboBox::setScale( double scale )
00140 {
00141   setScaleString( toString( scale ) );
00142 }
00143 
00145 void QgsScaleComboBox::fixupScale()
00146 {
00147   double newScale;
00148   double oldScale = mScale;
00149   bool ok, userSetScale;
00150   QStringList txtList = currentText().split( ':' );
00151   txtList.size() == 2 ? userSetScale = false : userSetScale = true ;
00152 
00153   // QgsDebugMsg( QString( "entered with oldScale: %1" ).arg( oldScale ) );
00154   newScale = toDouble( currentText(), &ok );
00155 
00156   // Valid string representation
00157   if ( ok && ( newScale != oldScale ) )
00158   {
00159     // if a user types scale = 2345, we transform to 1:2345
00160     if ( userSetScale && newScale >= 1.0 )
00161     {
00162       mScale = 1 / newScale;
00163     }
00164     else
00165     {
00166       mScale = newScale;
00167     }
00168     setScale( mScale );
00169     emit scaleChanged();
00170   }
00171   else
00172   {
00173     // Invalid string representation or same scale
00174     // Reset to the old
00175     setScale( mScale );
00176   }
00177 }
00178 
00179 QString QgsScaleComboBox::toString( double scale )
00180 {
00181   if ( scale > 1 )
00182   {
00183     return QString( "%1:1" ).arg( qRound( scale ) );
00184   }
00185   else
00186   {
00187     return QString( "1:%1" ).arg( qRound( 1.0 / scale ) );
00188   }
00189 }
00190 
00191 double QgsScaleComboBox::toDouble( QString scaleString, bool * returnOk )
00192 {
00193   bool ok = false;
00194   QString scaleTxt( scaleString );
00195 
00196   double scale = QLocale::system().toDouble( scaleTxt, &ok );
00197   if ( ok )
00198   {
00199     // Create a text version and set that text and rescan
00200     // Idea is to get the same rounding.
00201     scaleTxt = toString( scale );
00202   }
00203   // It is now either X:Y or not valid
00204   ok = false;
00205   QStringList txtList = scaleTxt.split( ':' );
00206   if ( 2 == txtList.size() )
00207   {
00208     bool okX = false;
00209     bool okY = false;
00210     int x = QLocale::system().toInt( txtList[ 0 ], &okX );
00211     int y = QLocale::system().toInt( txtList[ 1 ], &okY );
00212     if ( okX && okY )
00213     {
00214       // Scale is fraction of x and y
00215       scale = ( double )x / ( double )y;
00216       ok = true;
00217     }
00218   }
00219 
00220   // Set up optional return flag
00221   if ( returnOk )
00222   {
00223     *returnOk = ok;
00224   }
00225   return scale;
00226 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines