QGIS API Documentation  2.10.1-Pisa
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgsprojectionselectionwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsprojectionselectionwidget.cpp
3  --------------------------------------
4  Date : 05.01.2015
5  Copyright : (C) 2015 Denis Rouzaud
6  Email : denis.rouzaud@gmail.com
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 <QHBoxLayout>
17 
18 
20 #include "qgsapplication.h"
22 #include "qgsproject.h"
23 #include <QSettings>
24 
26  QWidget( parent )
27 {
28  mDialog = new QgsGenericProjectionSelector( this );
29 
31  layout->setContentsMargins( 0, 0, 0, 0 );
32  layout->setSpacing( 0 );
33  setLayout( layout );
34 
35  mCrsComboBox = new QComboBox( this );
36  mCrsComboBox->addItem( tr( "invalid projection" ), QgsProjectionSelectionWidget::CurrentCrs );
37  mCrsComboBox->setSizePolicy( QSizePolicy::Ignored, QSizePolicy::Preferred );
38 
39  if ( QgsProject::instance()->readNumEntry( "SpatialRefSys", "/ProjectionsEnabled", 0 ) )
40  {
41  //only show project CRS if OTF reprojection is enabled - otherwise the
42  //CRS stored in the project can be misleading
43  QString projectCrsString = QgsProject::instance()->readEntry( "SpatialRefSys", "/ProjectCrs" );
44  mProjectCrs.createFromOgcWmsCrs( projectCrsString );
45  addProjectCrsOption();
46  }
47 
48  QSettings settings;
49  QString defCrsString = settings.value( "/Projections/projectDefaultCrs", GEO_EPSG_CRS_AUTHID ).toString();
50  mDefaultCrs.createFromOgcWmsCrs( defCrsString );
51  if ( mDefaultCrs.authid() != mProjectCrs.authid() )
52  {
53  //only show default CRS option if it's different to the project CRS, avoids
54  //needlessly cluttering the widget
55  addDefaultCrsOption();
56  }
57 
58  addRecentCrs();
59 
60  layout->addWidget( mCrsComboBox );
61 
62  mButton = new QToolButton( this );
63  mButton->setIcon( QgsApplication::getThemeIcon( "mActionSetProjection.svg" ) );
64  mButton->setToolTip( tr( "Select CRS" ) );
65  layout->addWidget( mButton );
66 
67  setFocusPolicy( Qt::StrongFocus );
68  setFocusProxy( mButton );
69 
70  connect( mButton, SIGNAL( clicked() ), this, SLOT( selectCrs() ) );
71  connect( mCrsComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( comboIndexChanged( int ) ) );
72 }
73 
75 {
76  switch (( CrsOption )mCrsComboBox->itemData( mCrsComboBox->currentIndex() ).toInt() )
77  {
79  return mLayerCrs;
81  return mProjectCrs ;
83  return mDefaultCrs ;
85  return mCrs;
87  {
88  long srsid = mCrsComboBox->itemData( mCrsComboBox->currentIndex(), Qt::UserRole + 1 ).toLongLong();
90  crs.createFromSrsId( srsid );
91  return crs;
92  }
93  }
94  return mCrs;
95 }
96 
98 {
99  int optionIndex = mCrsComboBox->findData( option );
100 
101  if ( visible && optionIndex < 0 )
102  {
103  //add missing CRS option
104  switch ( option )
105  {
107  {
108  setLayerCrs( mLayerCrs );
109  return;
110  }
112  {
113  addProjectCrsOption();
114  return;
115  }
117  {
118  addDefaultCrsOption();
119  return;
120  }
123  //current/recently used CRS option cannot be readded
124  return;
125  }
126  }
127  else if ( !visible && optionIndex >= 0 )
128  {
129  //remove CRS option
130  mCrsComboBox->removeItem( optionIndex );
131  }
132 }
133 
135 {
136  //find out crs id of current proj4 string
137  if ( mCrs.isValid() )
138  {
139  mDialog->setSelectedCrsId( mCrs.srsid() );
140  }
141 
142  if ( mDialog->exec() )
143  {
144  mCrsComboBox->blockSignals( true );
145  mCrsComboBox->setCurrentIndex( mCrsComboBox->findData( QgsProjectionSelectionWidget::CurrentCrs ) );
146  mCrsComboBox->blockSignals( false );
148  crs.createFromOgcWmsCrs( mDialog->selectedAuthId() );
149  setCrs( crs );
150  emit crsChanged( crs );
151  }
152  else
153  {
155  }
156 }
157 
158 void QgsProjectionSelectionWidget::comboIndexChanged( int idx )
159 {
160  switch (( CrsOption )mCrsComboBox->itemData( idx ).toInt() )
161  {
163  emit crsChanged( mLayerCrs );
164  return;
166  emit crsChanged( mProjectCrs );
167  return;
169  emit crsChanged( mCrs );
170  return;
172  emit crsChanged( mDefaultCrs );
173  return;
175  {
176  long srsid = mCrsComboBox->itemData( idx, Qt::UserRole + 1 ).toLongLong();
178  crs.createFromSrsId( srsid );
179  emit crsChanged( crs );
180  return;
181  }
182  }
183 }
184 
186 {
187  if ( crs.isValid() )
188  {
189  mCrsComboBox->setItemText( mCrsComboBox->findData( QgsProjectionSelectionWidget::CurrentCrs ),
190  tr( "Selected CRS (%1, %2)" ).arg( crs.authid() ).arg( crs.description() ) );
191  mCrsComboBox->blockSignals( true );
192  mCrsComboBox->setCurrentIndex( mCrsComboBox->findData( QgsProjectionSelectionWidget::CurrentCrs ) );
193  mCrsComboBox->blockSignals( false );
194  }
195  else
196  {
197  mCrsComboBox->setItemText( mCrsComboBox->findData( QgsProjectionSelectionWidget::CurrentCrs ),
198  tr( "invalid projection" ) );
199  }
200  mCrs = crs;
201 }
202 
204 {
205  int layerItemIndex = mCrsComboBox->findData( QgsProjectionSelectionWidget::LayerCrs );
206  if ( crs.isValid() )
207  {
208  if ( layerItemIndex > -1 )
209  {
210  mCrsComboBox->setItemText( layerItemIndex, tr( "Layer CRS (%1, %2)" ).arg( crs.authid() ).arg( crs.description() ) );
211  }
212  else
213  {
214  mCrsComboBox->insertItem( firstRecentCrsIndex(), tr( "Layer CRS (%1, %2)" ).arg( crs.authid() ).arg( crs.description() ), QgsProjectionSelectionWidget::LayerCrs );
215  }
216  }
217  else
218  {
219  if ( layerItemIndex > -1 )
220  {
221  mCrsComboBox->removeItem( layerItemIndex );
222  }
223  }
224  mLayerCrs = crs;
225 }
226 
227 void QgsProjectionSelectionWidget::addProjectCrsOption()
228 {
229  if ( mProjectCrs.isValid() )
230  {
231  mCrsComboBox->addItem( tr( "Project CRS (%1 - %2)" ).arg( mProjectCrs.authid() ).arg( mProjectCrs.description() ), QgsProjectionSelectionWidget::ProjectCrs );
232  }
233 }
234 
235 void QgsProjectionSelectionWidget::addDefaultCrsOption()
236 {
237  mCrsComboBox->addItem( tr( "Default CRS (%1 - %2)" ).arg( mDefaultCrs.authid() ).arg( mDefaultCrs.description() ), QgsProjectionSelectionWidget::DefaultCrs );
238 }
239 
240 void QgsProjectionSelectionWidget::addRecentCrs()
241 {
243  int i = 0;
244  foreach ( QString projection, recentProjections )
245  {
246  long srsid = projection.toLong();
247 
248  //check if already shown
249  if ( crsIsShown( srsid ) )
250  {
251  continue;
252  }
253 
254  i++;
256  crs.createFromSrsId( srsid );
257  if ( crs.isValid() )
258  {
259  mCrsComboBox->addItem( tr( "%1 - %2" ).arg( crs.authid() ).arg( crs.description() ), QgsProjectionSelectionWidget::RecentCrs );
260  mCrsComboBox->setItemData( mCrsComboBox->count() - 1, QVariant(( long long )srsid ), Qt::UserRole + 1 );
261  }
262  if ( i >= 4 )
263  {
264  //limit to 4 recent projections to avoid clutter
265  break;
266  }
267  }
268 }
269 
270 bool QgsProjectionSelectionWidget::crsIsShown( const long srsid ) const
271 {
272  return srsid == mLayerCrs.srsid() || srsid == mDefaultCrs.srsid() || srsid == mProjectCrs.srsid();
273 }
274 
275 int QgsProjectionSelectionWidget::firstRecentCrsIndex() const
276 {
277  for ( int i = 0; i < mCrsComboBox->count(); ++i )
278  {
279  if (( CrsOption )mCrsComboBox->itemData( i ).toInt() == RecentCrs )
280  {
281  return i;
282  }
283  }
284  return -1;
285 }
QLayout * layout() const
qlonglong toLongLong(bool *ok) const
void setContentsMargins(int left, int top, int right, int bottom)
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the current CRS for the widget.
void setFocusPolicy(Qt::FocusPolicy policy)
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
A generic dialog to prompt the user for a Coordinate Reference System.
int exec()
void setIcon(const QIcon &icon)
QString tr(const char *sourceText, const char *disambiguation, int n)
void setItemText(int index, const QString &text)
void insertItem(int index, const QString &text, const QVariant &userData)
void addItem(const QString &text, const QVariant &userData)
bool createFromOgcWmsCrs(QString theCrs)
Set up this CRS from the given OGC CRS.
CrsOption
Predefined CRS options shown in widget.
void addWidget(QWidget *widget, int stretch, QFlags< Qt::AlignmentFlag > alignment)
void setOptionVisible(const CrsOption option, const bool visible)
Sets whether a predefined CRS option should be shown in the widget.
QgsCoordinateReferenceSystem crs() const
Returns the currently selected CRS for the widget.
void setLayout(QLayout *layout)
int toInt(bool *ok) const
void selectCrs()
Opens the dialog for selecting a new CRS.
void crsChanged(QgsCoordinateReferenceSystem)
Emitted when the selected CRS is changed.
static QStringList recentProjections()
Returns a list of recently used projections.
void setFocusProxy(QWidget *w)
void restoreOverrideCursor()
const QString GEO_EPSG_CRS_AUTHID
Geographic coord sys from EPSG authority.
Definition: qgis.cpp:72
void setSizePolicy(QSizePolicy)
QVariant itemData(int index, int role) const
bool blockSignals(bool block)
long toLong(bool *ok, int base) const
QVariant value(const QString &key, const QVariant &defaultValue) const
void removeItem(int index)
QString readEntry(const QString &scope, const QString &key, const QString &def=QString::null, bool *ok=0) const
int findData(const QVariant &data, int role, QFlags< Qt::MatchFlag > flags) const
void setItemData(int index, const QVariant &value, int role)
static QgsProject * instance()
access to canonical QgsProject instance
Definition: qgsproject.cpp:351
Class for storing a coordinate reference system (CRS)
void setToolTip(const QString &)
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QString toString() const
void setSpacing(int spacing)
void setLayerCrs(const QgsCoordinateReferenceSystem &crs)
Sets the layer CRS for the widget.