QGIS API Documentation  2.8.6-Wien
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 
30  QHBoxLayout* layout = new QHBoxLayout();
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  {
154  QApplication::restoreOverrideCursor();
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 {
242  QStringList recentProjections = QgsCoordinateReferenceSystem::recentProjections();
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 }
void setCrs(const QgsCoordinateReferenceSystem &crs)
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
A generic dialog to prompt the user for a Coordinate Reference System.
bool createFromOgcWmsCrs(QString theCrs)
Set up this CRS from the given OGC CRS.
CrsOption
Predefined CRS options shown in widget.
void setOptionVisible(const CrsOption option, const bool visible)
QgsCoordinateReferenceSystem crs() const
void crsChanged(QgsCoordinateReferenceSystem)
static QStringList recentProjections()
Returns a list of recently used projections.
QString readEntry(const QString &scope, const QString &key, const QString &def=QString::null, bool *ok=0) const
static QgsProject * instance()
access to canonical QgsProject instance
Definition: qgsproject.cpp:351
Class for storing a coordinate reference system (CRS)
const CORE_EXPORT QString GEO_EPSG_CRS_AUTHID
Geographic coord sys from EPSG authority.
Definition: qgis.cpp:71
void setLayerCrs(const QgsCoordinateReferenceSystem &crs)
#define tr(sourceText)