QGIS API Documentation 3.32.0-Lima (311a8cb8a6)
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//
33 : QgsPanelWidget( parent )
34{
35 setupUi( this );
36
37 //we will show this only when a message is set
38 textEdit->hide();
39
40 mNotSetText = tr( "No CRS (or unknown/non-Earth projection)" );
41 mLabelNoCrs->setText( tr( "Use this option to treat all coordinates as Cartesian coordinates in an unknown reference system." ) );
42
43 mComboCrsType->addItem( tr( "Predefined CRS" ), static_cast< int >( CrsType::Predefined ) );
44 mComboCrsType->addItem( tr( "Custom CRS" ), static_cast< int >( CrsType::Custom ) );
45
46 mStackedWidget->setCurrentWidget( mPageDatabase );
47 mComboCrsType->setCurrentIndex( mComboCrsType->findData( static_cast< int >( CrsType::Predefined ) ) );
48
49 connect( mComboCrsType, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]( int )
50 {
51 if ( !mComboCrsType->currentData().isValid() )
52 mStackedWidget->setCurrentWidget( mPageNoCrs );
53 else
54 {
55 switch ( static_cast< CrsType >( mComboCrsType->currentData().toInt() ) )
56 {
57 case QgsCrsSelectionWidget::CrsType::Predefined:
58 mStackedWidget->setCurrentWidget( mPageDatabase );
59 break;
60 case QgsCrsSelectionWidget::CrsType::Custom:
61 mStackedWidget->setCurrentWidget( mPageCustom );
62 break;
63 }
64 }
65
66 if ( !mBlockSignals )
67 {
68 emit crsChanged();
70 }
71 } );
72
73 connect( projectionSelector, &QgsProjectionSelectionTreeWidget::projectionDoubleClicked, this, [ = ]
74 {
75 emit crsDoubleClicked( projectionSelector->crs() );
76 } );
77
78 connect( mCrsDefinitionWidget, &QgsCrsDefinitionWidget::crsChanged, this, [ = ]()
79 {
80 if ( !mBlockSignals )
81 {
82 emit crsChanged();
83 emit hasValidSelectionChanged( hasValidSelection() );
84 }
85 } );
86
87 connect( projectionSelector, &QgsProjectionSelectionTreeWidget::crsSelected, this, [ = ]()
88 {
89 if ( !mBlockSignals )
90 {
91 mDeferredInvalidCrsSet = false;
92 emit crsChanged();
93 emit hasValidSelectionChanged( hasValidSelection() );
94 }
95 } );
96
97 connect( projectionSelector, &QgsProjectionSelectionTreeWidget::hasValidSelectionChanged, this, [ = ]()
98 {
99 if ( !mBlockSignals )
100 {
101 emit crsChanged();
102 emit hasValidSelectionChanged( hasValidSelection() );
103 }
104 } );
105
106 const QgsSettings settings;
107 mSplitter->restoreState( settings.value( QStringLiteral( "Windows/ProjectionSelectorDialog/splitterState" ) ).toByteArray() );
108}
109
111{
112 QgsSettings settings;
113 settings.setValue( QStringLiteral( "Windows/ProjectionSelectorDialog/splitterState" ), mSplitter->saveState() );
114}
115
116void QgsCrsSelectionWidget::setMessage( const QString &message )
117{
118 textEdit->setHtml( QStringLiteral( "<head><style>%1</style></head><body>%2</body>" ).arg( QgsApplication::reportStyleSheet(),
119 message ) );
120 textEdit->show();
121}
122
124{
125 if ( mShowNoCrsOption == show )
126 return;
127
128 mBlockSignals++;
129 mShowNoCrsOption = show;
130 if ( mShowNoCrsOption )
131 {
132 mComboCrsType->insertItem( 0, mNotSetText );
133 }
134 else
135 {
136 mComboCrsType->removeItem( 0 );
137 }
138
139 if ( show && mDeferredInvalidCrsSet )
140 {
141 mComboCrsType->setCurrentIndex( 0 );
142 }
143
144 mBlockSignals--;
145
146 if ( mDeferredInvalidCrsSet )
147 emit crsChanged();
148
149 mDeferredInvalidCrsSet = false;
150
152}
153
155{
156 return mShowNoCrsOption;
157}
158
159void QgsCrsSelectionWidget::setNotSetText( const QString &text, const QString &description )
160{
161 mNotSetText = text;
162
163 if ( mShowNoCrsOption )
164 {
165 mComboCrsType->setItemText( 0, mNotSetText );
166 }
167
168 mLabelNoCrs->setText( description.isEmpty() ? text : description );
169}
170
172{
173 if ( !mComboCrsType->currentData().isValid() )
174 return true;
175 else if ( mDeferredInvalidCrsSet )
176 return false;
177 else
178 {
179 switch ( static_cast< CrsType >( mComboCrsType->currentData().toInt() ) )
180 {
181 case QgsCrsSelectionWidget::CrsType::Predefined:
182 return projectionSelector->hasValidSelection();
183 case QgsCrsSelectionWidget::CrsType::Custom:
184 return mCrsDefinitionWidget->crs().isValid();
185 }
187 }
188}
189
191{
192 if ( !mComboCrsType->currentData().isValid() )
194 else
195 {
196 switch ( static_cast< CrsType >( mComboCrsType->currentData().toInt() ) )
197 {
198 case QgsCrsSelectionWidget::CrsType::Predefined:
199 return projectionSelector->crs();
200 case QgsCrsSelectionWidget::CrsType::Custom:
201 return mCrsDefinitionWidget->crs();
202 }
204 }
205}
206
208{
209 mBlockSignals++;
210 if ( !crs.isValid() )
211 {
212 if ( mShowNoCrsOption )
213 mComboCrsType->setCurrentIndex( 0 );
214 else
215 mDeferredInvalidCrsSet = true;
216 }
217 else
218 {
219 projectionSelector->setCrs( crs );
220 mCrsDefinitionWidget->setCrs( crs );
221 if ( crs.isValid() && crs.authid().isEmpty() )
222 {
223 mComboCrsType->setCurrentIndex( mComboCrsType->findData( static_cast< int>( CrsType::Custom ) ) );
224 mStackedWidget->setCurrentWidget( mPageCustom );
225 }
226 else
227 {
228 mComboCrsType->setCurrentIndex( mComboCrsType->findData( static_cast< int>( CrsType::Predefined ) ) );
229 mStackedWidget->setCurrentWidget( mPageDatabase );
230 }
231 }
232 mBlockSignals--;
233
234 emit crsChanged();
236}
237
238void QgsCrsSelectionWidget::setOgcWmsCrsFilter( const QSet<QString> &crsFilter )
239{
240 projectionSelector->setOgcWmsCrsFilter( crsFilter );
241}
242
243
244
245//
246// QgsProjectionSelectionDialog
247//
248
250 Qt::WindowFlags fl )
251 : QDialog( parent, fl )
252{
253 QVBoxLayout *vlayout = new QVBoxLayout();
254
255 mCrsWidget = new QgsCrsSelectionWidget();
256 vlayout->addWidget( mCrsWidget, 1 );
257
258 mButtonBox = new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok );
259 connect( mButtonBox, &QDialogButtonBox::accepted, this, &QgsProjectionSelectionDialog::accept );
260 connect( mButtonBox, &QDialogButtonBox::rejected, this, &QgsProjectionSelectionDialog::reject );
261 connect( mButtonBox, &QDialogButtonBox::helpRequested, this, &QgsProjectionSelectionDialog::showHelp );
262
263 vlayout->addWidget( mButtonBox );
264
265 setLayout( vlayout );
266
268
269 //apply selected projection upon double-click on item
270 connect( mCrsWidget, &QgsCrsSelectionWidget::crsDoubleClicked, this, &QgsProjectionSelectionDialog::accept );
271}
272
273void QgsProjectionSelectionDialog::setMessage( const QString &message )
274{
275 mCrsWidget->setMessage( message );
276}
277
279{
280 setMessage( tr( "This layer appears to have no projection specification." )
281 + ' '
282 + tr( "By default, this layer will now have its projection set to that of the project, "
283 "but you may override this by selecting a different projection below." ) );
284}
285
287{
288 mCrsWidget->setShowNoCrs( show );
289}
290
292{
293 return mCrsWidget->showNoCrs();
294}
295
296void QgsProjectionSelectionDialog::setNotSetText( const QString &text, const QString &description )
297{
298 mCrsWidget->setNotSetText( text, description );
299}
300
302{
303 mRequireValidSelection = true;
304 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( hasValidSelection() );
305
306 connect( mCrsWidget, &QgsCrsSelectionWidget::hasValidSelectionChanged, this, [ = ]( bool isValid )
307 {
308 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( isValid );
309 } );
310}
311
313{
314 return mCrsWidget->hasValidSelection();
315}
316
318{
319 return mCrsWidget->crs();
320}
321
323{
324 mCrsWidget->setCrs( crs );
325
326 if ( mRequireValidSelection )
327 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( hasValidSelection() );
328}
329
330void QgsProjectionSelectionDialog::setOgcWmsCrsFilter( const QSet<QString> &crsFilter )
331{
332 mCrsWidget->setOgcWmsCrsFilter( crsFilter );
333}
334
335void QgsProjectionSelectionDialog::showHelp()
336{
337 QgsHelp::openHelp( QStringLiteral( "working_with_projections/working_with_projections.html" ) );
338}
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.
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.
QgsCrsSelectionWidget(QWidget *parent=nullptr)
Constructor for QgsCrsSelectionWidget, with the specified parent widget.
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:193
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:38
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.
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)
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 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:63
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:4659
const QgsCoordinateReferenceSystem & crs