QGIS API Documentation  2.14.0-Essen
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 : [email protected]
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(), 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(), crs.description() ) );
211  }
212  else
213  {
214  mCrsComboBox->insertItem( firstRecentCrsIndex(), tr( "Layer CRS (%1, %2)" ).arg( crs.authid(), 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(), mProjectCrs.description() ), QgsProjectionSelectionWidget::ProjectCrs );
232  }
233 }
234 
235 void QgsProjectionSelectionWidget::addDefaultCrsOption()
236 {
237  mCrsComboBox->addItem( tr( "Default CRS (%1 - %2)" ).arg( mDefaultCrs.authid(), mDefaultCrs.description() ), QgsProjectionSelectionWidget::DefaultCrs );
238 }
239 
240 void QgsProjectionSelectionWidget::addRecentCrs()
241 {
243  int i = 0;
244  Q_FOREACH ( const 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(), 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.
long srsid() const
Returns the SrsId, if available.
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)
QgsProjectionSelectionWidget(QWidget *parent=nullptr)
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.
QString readEntry(const QString &scope, const QString &key, const QString &def=QString::null, bool *ok=nullptr) const
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.
bool createFromSrsId(const long theSrsId)
Set up this CRS by fetching the appropriate information from the sqlite backend.
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.
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:74
void setSizePolicy(QSizePolicy)
QVariant itemData(int index, int role) const
bool blockSignals(bool block)
long toLong(bool *ok, int base) const
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
QVariant value(const QString &key, const QVariant &defaultValue) const
void removeItem(int index)
int findData(const QVariant &data, int role, QFlags< Qt::MatchFlag > flags) const
void crsChanged(const QgsCoordinateReferenceSystem &)
Emitted when the selected CRS is changed.
void setItemData(int index, const QVariant &value, int role)
static QgsProject * instance()
access to canonical QgsProject instance
Definition: qgsproject.cpp:381
Class for storing a coordinate reference system (CRS)
QString authid() const
Returns the authority identifier for the CRS, which includes both the authority (eg EPSG) and the CRS...
QString description() const
Returns the descriptive name of the CRS, eg "WGS 84" or "GDA 94 / Vicgrid94".
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.