QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
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 emit crsChanged();
92 emit hasValidSelectionChanged( hasValidSelection() );
93 }
94 } );
95
96 connect( projectionSelector, &QgsProjectionSelectionTreeWidget::hasValidSelectionChanged, this, [ = ]()
97 {
98 if ( !mBlockSignals )
99 {
100 emit crsChanged();
101 emit hasValidSelectionChanged( hasValidSelection() );
102 }
103 } );
104
105 const QgsSettings settings;
106 mSplitter->restoreState( settings.value( QStringLiteral( "Windows/ProjectionSelectorDialog/splitterState" ) ).toByteArray() );
107}
108
110{
111 QgsSettings settings;
112 settings.setValue( QStringLiteral( "Windows/ProjectionSelectorDialog/splitterState" ), mSplitter->saveState() );
113}
114
115void QgsCrsSelectionWidget::setMessage( const QString &message )
116{
117 textEdit->setHtml( QStringLiteral( "<head><style>%1</style></head><body>%2</body>" ).arg( QgsApplication::reportStyleSheet(),
118 message ) );
119 textEdit->show();
120}
121
123{
124 if ( mShowNoCrsOption == show )
125 return;
126
127 mBlockSignals++;
128 mShowNoCrsOption = show;
129 if ( mShowNoCrsOption )
130 {
131 mComboCrsType->insertItem( 0, mNotSetText );
132 }
133 else
134 {
135 mComboCrsType->removeItem( 0 );
136 }
137
138 if ( show && mDeferredInvalidCrsSet )
139 {
140 mComboCrsType->setCurrentIndex( 0 );
141 }
142
143 mBlockSignals--;
144
145 if ( mDeferredInvalidCrsSet )
146 emit crsChanged();
147
148 mDeferredInvalidCrsSet = false;
149
151}
152
154{
155 return mShowNoCrsOption;
156}
157
158void QgsCrsSelectionWidget::setNotSetText( const QString &text, const QString &description )
159{
160 mNotSetText = text;
161
162 if ( mShowNoCrsOption )
163 {
164 mComboCrsType->setItemText( 0, mNotSetText );
165 }
166
167 mLabelNoCrs->setText( description.isEmpty() ? text : description );
168}
169
171{
172 if ( !mComboCrsType->currentData().isValid() )
173 return true;
174 else if ( mDeferredInvalidCrsSet )
175 return false;
176 else
177 {
178 switch ( static_cast< CrsType >( mComboCrsType->currentData().toInt() ) )
179 {
180 case QgsCrsSelectionWidget::CrsType::Predefined:
181 return projectionSelector->hasValidSelection();
182 case QgsCrsSelectionWidget::CrsType::Custom:
183 return mCrsDefinitionWidget->crs().isValid();
184 }
186 }
187}
188
190{
191 if ( !mComboCrsType->currentData().isValid() )
193 else
194 {
195 switch ( static_cast< CrsType >( mComboCrsType->currentData().toInt() ) )
196 {
197 case QgsCrsSelectionWidget::CrsType::Predefined:
198 return projectionSelector->crs();
199 case QgsCrsSelectionWidget::CrsType::Custom:
200 return mCrsDefinitionWidget->crs();
201 }
203 }
204}
205
207{
208 mBlockSignals++;
209 if ( !crs.isValid() )
210 {
211 if ( mShowNoCrsOption )
212 mComboCrsType->setCurrentIndex( 0 );
213 else
214 mDeferredInvalidCrsSet = true;
215 }
216 else
217 {
218 projectionSelector->setCrs( crs );
219 mCrsDefinitionWidget->setCrs( crs );
220 if ( crs.isValid() && crs.authid().isEmpty() )
221 {
222 mComboCrsType->setCurrentIndex( mComboCrsType->findData( static_cast< int>( CrsType::Custom ) ) );
223 mStackedWidget->setCurrentWidget( mPageCustom );
224 }
225 else
226 {
227 mComboCrsType->setCurrentIndex( mComboCrsType->findData( static_cast< int>( CrsType::Predefined ) ) );
228 mStackedWidget->setCurrentWidget( mPageDatabase );
229 }
230 }
231 mBlockSignals--;
232
233 emit crsChanged();
235}
236
237void QgsCrsSelectionWidget::setOgcWmsCrsFilter( const QSet<QString> &crsFilter )
238{
239 projectionSelector->setOgcWmsCrsFilter( crsFilter );
240}
241
242
243
244//
245// QgsProjectionSelectionDialog
246//
247
249 Qt::WindowFlags fl )
250 : QDialog( parent, fl )
251{
252 QVBoxLayout *vlayout = new QVBoxLayout();
253
254 mCrsWidget = new QgsCrsSelectionWidget();
255 vlayout->addWidget( mCrsWidget, 1 );
256
257 mButtonBox = new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok );
258 connect( mButtonBox, &QDialogButtonBox::accepted, this, &QgsProjectionSelectionDialog::accept );
259 connect( mButtonBox, &QDialogButtonBox::rejected, this, &QgsProjectionSelectionDialog::reject );
260 connect( mButtonBox, &QDialogButtonBox::helpRequested, this, &QgsProjectionSelectionDialog::showHelp );
261
262 vlayout->addWidget( mButtonBox );
263
264 setLayout( vlayout );
265
267
268 //apply selected projection upon double-click on item
269 connect( mCrsWidget, &QgsCrsSelectionWidget::crsDoubleClicked, this, &QgsProjectionSelectionDialog::accept );
270}
271
272void QgsProjectionSelectionDialog::setMessage( const QString &message )
273{
274 mCrsWidget->setMessage( message );
275}
276
278{
279 setMessage( tr( "This layer appears to have no projection specification." )
280 + ' '
281 + tr( "By default, this layer will now have its projection set to that of the project, "
282 "but you may override this by selecting a different projection below." ) );
283}
284
286{
287 mCrsWidget->setShowNoCrs( show );
288}
289
291{
292 return mCrsWidget->showNoCrs();
293}
294
295void QgsProjectionSelectionDialog::setNotSetText( const QString &text, const QString &description )
296{
297 mCrsWidget->setNotSetText( text, description );
298}
299
301{
302 mRequireValidSelection = true;
303 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( hasValidSelection() );
304
305 connect( mCrsWidget, &QgsCrsSelectionWidget::hasValidSelectionChanged, this, [ = ]( bool isValid )
306 {
307 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( isValid );
308 } );
309}
310
312{
313 return mCrsWidget->hasValidSelection();
314}
315
317{
318 return mCrsWidget->crs();
319}
320
322{
323 mCrsWidget->setCrs( crs );
324
325 if ( mRequireValidSelection )
326 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( hasValidSelection() );
327}
328
329void QgsProjectionSelectionDialog::setOgcWmsCrsFilter( const QSet<QString> &crsFilter )
330{
331 mCrsWidget->setOgcWmsCrsFilter( crsFilter );
332}
333
334void QgsProjectionSelectionDialog::showHelp()
335{
336 QgsHelp::openHelp( QStringLiteral( "working_with_projections/working_with_projections.html" ) );
337}
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:178
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:62
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:3148
const QgsCoordinateReferenceSystem & crs