QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsprojectionselectiondialog.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsgenericprojectionselector.cpp
3 Set user defined CRS using projection selector widget
4 -------------------
5 begin : May 28, 2004
6 copyright : (C) 2004 by Gary E.Sherman
7 email : sherman at mrcc.com
8 ***************************************************************************/
9
10/***************************************************************************
11 * *
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
16 * *
17 ***************************************************************************/
18#include "qgsapplication.h"
19#include "qgssettings.h"
20
22#include "qgshelp.h"
23#include <QDialogButtonBox>
24#include <QApplication>
25#include "qgsgui.h"
26#include <QPushButton>
27
28
29//
30// QgsCrsSelectionWidget
31//
34 : QgsPanelWidget( parent )
35{
36 setupUi( this );
37
38 projectionSelector->setFilters( filters );
39
40 //we will show this only when a message is set
41 textEdit->hide();
42
43 mNotSetText = tr( "No CRS (or unknown/non-Earth projection)" );
44 mLabelNoCrs->setText( tr( "Use this option to treat all coordinates as Cartesian coordinates in an unknown reference system." ) );
45
46 mComboCrsType->addItem( tr( "Predefined CRS" ), static_cast< int >( CrsType::Predefined ) );
47 mComboCrsType->addItem( tr( "Custom CRS" ), static_cast< int >( CrsType::Custom ) );
48
49 mStackedWidget->setCurrentWidget( mPageDatabase );
50 mComboCrsType->setCurrentIndex( mComboCrsType->findData( static_cast< int >( CrsType::Predefined ) ) );
51
52 connect( mComboCrsType, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]( int )
53 {
54 if ( !mComboCrsType->currentData().isValid() )
55 mStackedWidget->setCurrentWidget( mPageNoCrs );
56 else
57 {
58 switch ( static_cast< CrsType >( mComboCrsType->currentData().toInt() ) )
59 {
60 case QgsCrsSelectionWidget::CrsType::Predefined:
61 mStackedWidget->setCurrentWidget( mPageDatabase );
62 break;
63 case QgsCrsSelectionWidget::CrsType::Custom:
64 mStackedWidget->setCurrentWidget( mPageCustom );
65 break;
66 }
67 }
68
69 if ( !mBlockSignals )
70 {
71 emit crsChanged();
73 }
74 } );
75
76 connect( projectionSelector, &QgsProjectionSelectionTreeWidget::projectionDoubleClicked, this, [ = ]
77 {
78 emit crsDoubleClicked( projectionSelector->crs() );
79 } );
80
81 connect( mCrsDefinitionWidget, &QgsCrsDefinitionWidget::crsChanged, this, [ = ]()
82 {
83 if ( !mBlockSignals )
84 {
85 emit crsChanged();
86 emit hasValidSelectionChanged( hasValidSelection() );
87 }
88 } );
89
90 connect( projectionSelector, &QgsProjectionSelectionTreeWidget::crsSelected, this, [ = ]()
91 {
92 if ( !mBlockSignals )
93 {
94 mDeferredInvalidCrsSet = false;
95 emit crsChanged();
96 emit hasValidSelectionChanged( hasValidSelection() );
97 }
98 } );
99
100 connect( projectionSelector, &QgsProjectionSelectionTreeWidget::hasValidSelectionChanged, this, [ = ]()
101 {
102 if ( !mBlockSignals )
103 {
104 emit crsChanged();
105 emit hasValidSelectionChanged( hasValidSelection() );
106 }
107 } );
108
109 const QgsSettings settings;
110 mSplitter->restoreState( settings.value( QStringLiteral( "Windows/ProjectionSelectorDialog/splitterState" ) ).toByteArray() );
111}
112
114{
115 QgsSettings settings;
116 settings.setValue( QStringLiteral( "Windows/ProjectionSelectorDialog/splitterState" ), mSplitter->saveState() );
117}
118
119void QgsCrsSelectionWidget::setMessage( const QString &message )
120{
121 textEdit->setHtml( QStringLiteral( "<head><style>%1</style></head><body>%2</body>" ).arg( QgsApplication::reportStyleSheet(),
122 message ) );
123 textEdit->show();
124}
125
127{
128 if ( mShowNoCrsOption == show )
129 return;
130
131 mBlockSignals++;
132 mShowNoCrsOption = show;
133 if ( mShowNoCrsOption )
134 {
135 mComboCrsType->insertItem( 0, mNotSetText );
136 }
137 else
138 {
139 mComboCrsType->removeItem( 0 );
140 }
141
142 if ( show && mDeferredInvalidCrsSet )
143 {
144 mComboCrsType->setCurrentIndex( 0 );
145 }
146
147 mBlockSignals--;
148
149 if ( mDeferredInvalidCrsSet )
150 emit crsChanged();
151
152 mDeferredInvalidCrsSet = false;
153
155}
156
158{
159 return mShowNoCrsOption;
160}
161
162void QgsCrsSelectionWidget::setNotSetText( const QString &text, const QString &description )
163{
164 mNotSetText = text;
165
166 if ( mShowNoCrsOption )
167 {
168 mComboCrsType->setItemText( 0, mNotSetText );
169 }
170
171 mLabelNoCrs->setText( description.isEmpty() ? text : description );
172}
173
175{
176 if ( !mComboCrsType->currentData().isValid() )
177 return true;
178 else if ( mDeferredInvalidCrsSet )
179 return false;
180 else
181 {
182 switch ( static_cast< CrsType >( mComboCrsType->currentData().toInt() ) )
183 {
184 case QgsCrsSelectionWidget::CrsType::Predefined:
185 return projectionSelector->hasValidSelection();
186 case QgsCrsSelectionWidget::CrsType::Custom:
187 return mCrsDefinitionWidget->crs().isValid();
188 }
190 }
191}
192
194{
195 return projectionSelector->filters();
196}
197
199{
200 projectionSelector->setFilters( filters );
201}
202
204{
205 if ( !mComboCrsType->currentData().isValid() )
207 else
208 {
209 switch ( static_cast< CrsType >( mComboCrsType->currentData().toInt() ) )
210 {
211 case QgsCrsSelectionWidget::CrsType::Predefined:
212 return projectionSelector->crs();
213 case QgsCrsSelectionWidget::CrsType::Custom:
214 return mCrsDefinitionWidget->crs();
215 }
217 }
218}
219
221{
222 mBlockSignals++;
223 if ( !crs.isValid() )
224 {
225 if ( mShowNoCrsOption )
226 mComboCrsType->setCurrentIndex( 0 );
227 else
228 mDeferredInvalidCrsSet = true;
229 }
230 else
231 {
232 projectionSelector->setCrs( crs );
233 mCrsDefinitionWidget->setCrs( crs );
234 if ( crs.isValid() && crs.authid().isEmpty() )
235 {
236 mComboCrsType->setCurrentIndex( mComboCrsType->findData( static_cast< int>( CrsType::Custom ) ) );
237 mStackedWidget->setCurrentWidget( mPageCustom );
238 }
239 else
240 {
241 mComboCrsType->setCurrentIndex( mComboCrsType->findData( static_cast< int>( CrsType::Predefined ) ) );
242 mStackedWidget->setCurrentWidget( mPageDatabase );
243 }
244 }
245 mBlockSignals--;
246
247 emit crsChanged();
249}
250
251void QgsCrsSelectionWidget::setOgcWmsCrsFilter( const QSet<QString> &crsFilter )
252{
253 projectionSelector->setOgcWmsCrsFilter( crsFilter );
254}
255
256
257
258//
259// QgsProjectionSelectionDialog
260//
261
263 Qt::WindowFlags fl, QgsCoordinateReferenceSystemProxyModel::Filters filters )
264 : QDialog( parent, fl )
265{
266 QVBoxLayout *vlayout = new QVBoxLayout();
267
268 mCrsWidget = new QgsCrsSelectionWidget( nullptr, filters );
269 vlayout->addWidget( mCrsWidget, 1 );
270
271 mButtonBox = new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok );
272 connect( mButtonBox, &QDialogButtonBox::accepted, this, &QgsProjectionSelectionDialog::accept );
273 connect( mButtonBox, &QDialogButtonBox::rejected, this, &QgsProjectionSelectionDialog::reject );
274 connect( mButtonBox, &QDialogButtonBox::helpRequested, this, &QgsProjectionSelectionDialog::showHelp );
275
276 vlayout->addWidget( mButtonBox );
277
278 setLayout( vlayout );
279
281
282 //apply selected projection upon double-click on item
283 connect( mCrsWidget, &QgsCrsSelectionWidget::crsDoubleClicked, this, &QgsProjectionSelectionDialog::accept );
284}
285
286void QgsProjectionSelectionDialog::setMessage( const QString &message )
287{
288 mCrsWidget->setMessage( message );
289}
290
292{
293 setMessage( tr( "This layer appears to have no projection specification." )
294 + ' '
295 + tr( "By default, this layer will now have its projection set to that of the project, "
296 "but you may override this by selecting a different projection below." ) );
297}
298
300{
301 mCrsWidget->setShowNoCrs( show );
302}
303
305{
306 return mCrsWidget->showNoCrs();
307}
308
309void QgsProjectionSelectionDialog::setNotSetText( const QString &text, const QString &description )
310{
311 mCrsWidget->setNotSetText( text, description );
312}
313
315{
316 mRequireValidSelection = true;
317 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( hasValidSelection() );
318
319 connect( mCrsWidget, &QgsCrsSelectionWidget::hasValidSelectionChanged, this, [ = ]( bool isValid )
320 {
321 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( isValid );
322 } );
323}
324
326{
327 return mCrsWidget->hasValidSelection();
328}
329
331{
332 return mCrsWidget->filters();
333}
334
336{
337 mCrsWidget->setFilters( filters );
338}
339
341{
342 return mCrsWidget->crs();
343}
344
346{
347 mCrsWidget->setCrs( crs );
348
349 if ( mRequireValidSelection )
350 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( hasValidSelection() );
351}
352
353void QgsProjectionSelectionDialog::setOgcWmsCrsFilter( const QSet<QString> &crsFilter )
354{
355 mCrsWidget->setOgcWmsCrsFilter( crsFilter );
356}
357
358void QgsProjectionSelectionDialog::showHelp()
359{
360 QgsHelp::openHelp( QStringLiteral( "working_with_projections/working_with_projections.html" ) );
361}
static QString reportStyleSheet(QgsApplication::StyleSheetType styleSheetType=QgsApplication::StyleSheetType::Qt)
Returns a css style sheet for reports, the styleSheetType argument determines what type of stylesheet...
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
void crsChanged()
Emitted when the CRS defined in the widget is changed.
A generic widget allowing users to pick a Coordinate Reference System (or define their own).
bool showNoCrs() const
Returns whether the "no/invalid" CRS option is shown.
QgsCoordinateReferenceSystem crs() const
Returns the CRS currently selected in the widget.
void hasValidSelectionChanged(bool isValid)
Emitted when the widget has a valid selection or not.
QgsCrsSelectionWidget(QWidget *parent=nullptr, QgsCoordinateReferenceSystemProxyModel::Filters filters=QgsCoordinateReferenceSystemProxyModel::FilterHorizontal|QgsCoordinateReferenceSystemProxyModel::FilterCompound)
Constructor for QgsCrsSelectionWidget, with the specified parent widget.
QgsCoordinateReferenceSystemProxyModel::Filters filters() const
Returns the filters set on the available CRS.
void setFilters(QgsCoordinateReferenceSystemProxyModel::Filters filters)
Sets filters for the available CRS.
void crsDoubleClicked(const QgsCoordinateReferenceSystem &crs)
Emitted when a CRS entry in the widget is double-clicked.
void setShowNoCrs(bool show)
Sets whether a "no/invalid" CRS option should be shown.
void crsChanged()
Emitted when the CRS defined in the widget is changed.
void setMessage(const QString &message)
Sets a message to show in the dialog.
bool hasValidSelection() const
Returns true if the widget has a valid CRS defined.
void setNotSetText(const QString &text, const QString &description=QString())
Sets the text to show for the not set option.
void setOgcWmsCrsFilter(const QSet< QString > &crsFilter)
filters this dialog by the given CRSs
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the crs to show within the widget.
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
Definition: qgsgui.cpp:194
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:39
Base class for any widget that can be shown as a inline panel.
void showNoCrsForLayerMessage()
When called, the dialog will show a default "layer has no CRS set" message above the projection selec...
void setShowNoProjection(bool show)
Sets whether a "no/invalid" projection option should be shown.
bool showNoProjection() const
Returns whether the "no/invalid" projection option is shown.
QgsCoordinateReferenceSystemProxyModel::Filters filters() const
Returns the filters set on the available CRS.
bool hasValidSelection() const
Returns true if the dialog has a valid CRS defined.
void setNotSetText(const QString &text, const QString &description=QString())
Sets the text to show for the not set option.
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the initial crs to show within the dialog.
void setMessage(const QString &message)
Sets a message to show in the dialog.
QgsCoordinateReferenceSystem crs() const
Returns the CRS currently selected in the widget.
QgsProjectionSelectionDialog(QWidget *parent=nullptr, Qt::WindowFlags fl=QgsGuiUtils::ModalDialogFlags, QgsCoordinateReferenceSystemProxyModel::Filters filters=QgsCoordinateReferenceSystemProxyModel::FilterHorizontal|QgsCoordinateReferenceSystemProxyModel::FilterCompound)
Constructor for QgsProjectionSelectionDialog.
void setRequireValidSelection()
Sets the dialog to require a valid selection only, preventing users from accepting the dialog if no s...
void setOgcWmsCrsFilter(const QSet< QString > &crsFilter)
filters this dialog by the given CRSs
void setFilters(QgsCoordinateReferenceSystemProxyModel::Filters filters)
Sets filters for the available CRS.
void crsSelected()
Emitted when a projection is selected in the widget.
void projectionDoubleClicked()
Emitted when a projection is double clicked in the list.
void hasValidSelectionChanged(bool isValid)
Emitted when the selection in the tree is changed from a valid selection to an invalid selection,...
This class is a composition of two QSettings instances:
Definition: qgssettings.h:64
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
#define BUILTIN_UNREACHABLE
Definition: qgis.h:5853
const QgsCoordinateReferenceSystem & crs