|
QGIS API Documentation
master-59fd5e0
|
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 }