mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
352 lines
11 KiB
C++
352 lines
11 KiB
C++
/***************************************************************************
|
|
qgsprojectionselectionwidget.cpp
|
|
--------------------------------------
|
|
Date : 05.01.2015
|
|
Copyright : (C) 2015 Denis Rouzaud
|
|
Email : denis.rouzaud@gmail.com
|
|
***************************************************************************
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include <QHBoxLayout>
|
|
|
|
#include "qgsprojectionselectionwidget.h"
|
|
#include "qgsapplication.h"
|
|
#include "qgsprojectionselectiondialog.h"
|
|
#include "qgsproject.h"
|
|
#include "qgssettings.h"
|
|
|
|
QgsProjectionSelectionWidget::QgsProjectionSelectionWidget( QWidget *parent )
|
|
: QWidget( parent )
|
|
{
|
|
mDialog = new QgsProjectionSelectionDialog( this );
|
|
|
|
QHBoxLayout *layout = new QHBoxLayout();
|
|
layout->setContentsMargins( 0, 0, 0, 0 );
|
|
layout->setSpacing( 0 );
|
|
setLayout( layout );
|
|
|
|
mCrsComboBox = new QComboBox( this );
|
|
mCrsComboBox->addItem( tr( "invalid projection" ), QgsProjectionSelectionWidget::CurrentCrs );
|
|
mCrsComboBox->setSizePolicy( QSizePolicy::Ignored, QSizePolicy::Preferred );
|
|
|
|
mProjectCrs = QgsProject::instance()->crs();
|
|
addProjectCrsOption();
|
|
|
|
QgsSettings settings;
|
|
QString defCrsString = settings.value( QStringLiteral( "/Projections/projectDefaultCrs" ), GEO_EPSG_CRS_AUTHID ).toString();
|
|
mDefaultCrs = QgsCoordinateReferenceSystem::fromOgcWmsCrs( defCrsString );
|
|
if ( mDefaultCrs.authid() != mProjectCrs.authid() )
|
|
{
|
|
//only show default CRS option if it's different to the project CRS, avoids
|
|
//needlessly cluttering the widget
|
|
addDefaultCrsOption();
|
|
}
|
|
|
|
addRecentCrs();
|
|
|
|
layout->addWidget( mCrsComboBox );
|
|
|
|
mButton = new QToolButton( this );
|
|
mButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "mActionSetProjection.svg" ) ) );
|
|
mButton->setToolTip( tr( "Select CRS" ) );
|
|
layout->addWidget( mButton );
|
|
|
|
setFocusPolicy( Qt::StrongFocus );
|
|
setFocusProxy( mButton );
|
|
|
|
connect( mButton, &QToolButton::clicked, this, &QgsProjectionSelectionWidget::selectCrs );
|
|
connect( mCrsComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( comboIndexChanged( int ) ) );
|
|
}
|
|
|
|
QgsCoordinateReferenceSystem QgsProjectionSelectionWidget::crs() const
|
|
{
|
|
switch ( ( CrsOption )mCrsComboBox->currentData().toInt() )
|
|
{
|
|
case QgsProjectionSelectionWidget::LayerCrs:
|
|
return mLayerCrs;
|
|
case QgsProjectionSelectionWidget::ProjectCrs:
|
|
return mProjectCrs ;
|
|
case QgsProjectionSelectionWidget::DefaultCrs:
|
|
return mDefaultCrs ;
|
|
case QgsProjectionSelectionWidget::CurrentCrs:
|
|
return mCrs;
|
|
case QgsProjectionSelectionWidget::RecentCrs:
|
|
{
|
|
long srsid = mCrsComboBox->currentData( Qt::UserRole + 1 ).toLongLong();
|
|
QgsCoordinateReferenceSystem crs = QgsCoordinateReferenceSystem::fromSrsId( srsid );
|
|
return crs;
|
|
}
|
|
case QgsProjectionSelectionWidget::CrsNotSet:
|
|
return QgsCoordinateReferenceSystem();
|
|
}
|
|
return mCrs;
|
|
}
|
|
|
|
void QgsProjectionSelectionWidget::setOptionVisible( const QgsProjectionSelectionWidget::CrsOption option, const bool visible )
|
|
{
|
|
int optionIndex = mCrsComboBox->findData( option );
|
|
|
|
if ( visible && optionIndex < 0 )
|
|
{
|
|
//add missing CRS option
|
|
switch ( option )
|
|
{
|
|
case QgsProjectionSelectionWidget::LayerCrs:
|
|
{
|
|
setLayerCrs( mLayerCrs );
|
|
return;
|
|
}
|
|
case QgsProjectionSelectionWidget::ProjectCrs:
|
|
{
|
|
addProjectCrsOption();
|
|
return;
|
|
}
|
|
case QgsProjectionSelectionWidget::DefaultCrs:
|
|
{
|
|
addDefaultCrsOption();
|
|
return;
|
|
}
|
|
case QgsProjectionSelectionWidget::CurrentCrs:
|
|
{
|
|
addCurrentCrsOption();
|
|
return;
|
|
}
|
|
case QgsProjectionSelectionWidget::RecentCrs:
|
|
//recently used CRS option cannot be readded
|
|
return;
|
|
case QgsProjectionSelectionWidget::CrsNotSet:
|
|
{
|
|
addNotSetOption();
|
|
|
|
if ( optionVisible( CurrentCrs ) && !mCrs.isValid() )
|
|
{
|
|
// hide invalid option if not set option is shown
|
|
setOptionVisible( CurrentCrs, false );
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
else if ( !visible && optionIndex >= 0 )
|
|
{
|
|
//remove CRS option
|
|
mCrsComboBox->removeItem( optionIndex );
|
|
|
|
if ( option == CrsNotSet )
|
|
{
|
|
setOptionVisible( CurrentCrs, true );
|
|
}
|
|
}
|
|
}
|
|
|
|
void QgsProjectionSelectionWidget::setNotSetText( const QString &text )
|
|
{
|
|
mNotSetText = text;
|
|
int optionIndex = mCrsComboBox->findData( CrsNotSet );
|
|
if ( optionIndex >= 0 )
|
|
{
|
|
mCrsComboBox->setItemText( optionIndex, mNotSetText );
|
|
}
|
|
}
|
|
|
|
bool QgsProjectionSelectionWidget::optionVisible( QgsProjectionSelectionWidget::CrsOption option ) const
|
|
{
|
|
int optionIndex = mCrsComboBox->findData( option );
|
|
return optionIndex >= 0;
|
|
}
|
|
|
|
void QgsProjectionSelectionWidget::selectCrs()
|
|
{
|
|
//find out crs id of current proj4 string
|
|
if ( mCrs.isValid() )
|
|
{
|
|
mDialog->setCrs( mCrs );
|
|
}
|
|
|
|
if ( mDialog->exec() )
|
|
{
|
|
mCrsComboBox->blockSignals( true );
|
|
mCrsComboBox->setCurrentIndex( mCrsComboBox->findData( QgsProjectionSelectionWidget::CurrentCrs ) );
|
|
mCrsComboBox->blockSignals( false );
|
|
QgsCoordinateReferenceSystem crs = mDialog->crs();
|
|
setCrs( crs );
|
|
emit crsChanged( crs );
|
|
}
|
|
else
|
|
{
|
|
QApplication::restoreOverrideCursor();
|
|
}
|
|
}
|
|
|
|
void QgsProjectionSelectionWidget::addNotSetOption()
|
|
{
|
|
mCrsComboBox->insertItem( 0, mNotSetText, QgsProjectionSelectionWidget::CrsNotSet );
|
|
if ( !mCrs.isValid() )
|
|
whileBlocking( mCrsComboBox )->setCurrentIndex( 0 );
|
|
}
|
|
|
|
void QgsProjectionSelectionWidget::comboIndexChanged( int idx )
|
|
{
|
|
switch ( ( CrsOption )mCrsComboBox->itemData( idx ).toInt() )
|
|
{
|
|
case QgsProjectionSelectionWidget::LayerCrs:
|
|
emit crsChanged( mLayerCrs );
|
|
return;
|
|
case QgsProjectionSelectionWidget::ProjectCrs:
|
|
emit crsChanged( mProjectCrs );
|
|
return;
|
|
case QgsProjectionSelectionWidget::CurrentCrs:
|
|
emit crsChanged( mCrs );
|
|
return;
|
|
case QgsProjectionSelectionWidget::DefaultCrs:
|
|
emit crsChanged( mDefaultCrs );
|
|
return;
|
|
case QgsProjectionSelectionWidget::RecentCrs:
|
|
{
|
|
long srsid = mCrsComboBox->itemData( idx, Qt::UserRole + 1 ).toLongLong();
|
|
QgsCoordinateReferenceSystem crs = QgsCoordinateReferenceSystem::fromSrsId( srsid );
|
|
emit crsChanged( crs );
|
|
return;
|
|
}
|
|
case QgsProjectionSelectionWidget::CrsNotSet:
|
|
emit cleared();
|
|
emit crsChanged( QgsCoordinateReferenceSystem() );
|
|
return;
|
|
}
|
|
}
|
|
|
|
void QgsProjectionSelectionWidget::setCrs( const QgsCoordinateReferenceSystem &crs )
|
|
{
|
|
if ( crs.isValid() )
|
|
{
|
|
if ( !optionVisible( QgsProjectionSelectionWidget::CurrentCrs ) )
|
|
setOptionVisible( QgsProjectionSelectionWidget::CurrentCrs, true );
|
|
mCrsComboBox->setItemText( mCrsComboBox->findData( QgsProjectionSelectionWidget::CurrentCrs ),
|
|
currentCrsOptionText( crs ) );
|
|
mCrsComboBox->blockSignals( true );
|
|
mCrsComboBox->setCurrentIndex( mCrsComboBox->findData( QgsProjectionSelectionWidget::CurrentCrs ) );
|
|
mCrsComboBox->blockSignals( false );
|
|
}
|
|
else
|
|
{
|
|
int crsNotSetIndex = mCrsComboBox->findData( QgsProjectionSelectionWidget::CrsNotSet );
|
|
if ( crsNotSetIndex >= 0 )
|
|
{
|
|
mCrsComboBox->blockSignals( true );
|
|
mCrsComboBox->setCurrentIndex( crsNotSetIndex );
|
|
mCrsComboBox->blockSignals( false );
|
|
}
|
|
else
|
|
{
|
|
mCrsComboBox->setItemText( mCrsComboBox->findData( QgsProjectionSelectionWidget::CurrentCrs ),
|
|
currentCrsOptionText( crs ) );
|
|
}
|
|
}
|
|
mCrs = crs;
|
|
}
|
|
|
|
void QgsProjectionSelectionWidget::setLayerCrs( const QgsCoordinateReferenceSystem &crs )
|
|
{
|
|
int layerItemIndex = mCrsComboBox->findData( QgsProjectionSelectionWidget::LayerCrs );
|
|
if ( crs.isValid() )
|
|
{
|
|
if ( layerItemIndex > -1 )
|
|
{
|
|
mCrsComboBox->setItemText( layerItemIndex, tr( "Layer CRS (%1, %2)" ).arg( crs.authid(), crs.description() ) );
|
|
}
|
|
else
|
|
{
|
|
mCrsComboBox->insertItem( firstRecentCrsIndex(), tr( "Layer CRS (%1, %2)" ).arg( crs.authid(), crs.description() ), QgsProjectionSelectionWidget::LayerCrs );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( layerItemIndex > -1 )
|
|
{
|
|
mCrsComboBox->removeItem( layerItemIndex );
|
|
}
|
|
}
|
|
mLayerCrs = crs;
|
|
}
|
|
|
|
void QgsProjectionSelectionWidget::addProjectCrsOption()
|
|
{
|
|
if ( mProjectCrs.isValid() )
|
|
{
|
|
mCrsComboBox->addItem( tr( "Project CRS (%1 - %2)" ).arg( mProjectCrs.authid(), mProjectCrs.description() ), QgsProjectionSelectionWidget::ProjectCrs );
|
|
}
|
|
}
|
|
|
|
void QgsProjectionSelectionWidget::addDefaultCrsOption()
|
|
{
|
|
mCrsComboBox->addItem( tr( "Default CRS (%1 - %2)" ).arg( mDefaultCrs.authid(), mDefaultCrs.description() ), QgsProjectionSelectionWidget::DefaultCrs );
|
|
}
|
|
|
|
void QgsProjectionSelectionWidget::addCurrentCrsOption()
|
|
{
|
|
int index = optionVisible( CrsNotSet ) ? 1 : 0;
|
|
mCrsComboBox->insertItem( index, currentCrsOptionText( mCrs ), QgsProjectionSelectionWidget::CurrentCrs );
|
|
|
|
}
|
|
|
|
QString QgsProjectionSelectionWidget::currentCrsOptionText( const QgsCoordinateReferenceSystem &crs ) const
|
|
{
|
|
if ( crs.isValid() )
|
|
return tr( "Selected CRS (%1, %2)" ).arg( crs.authid(), crs.description() );
|
|
else
|
|
return tr( "invalid projection" );
|
|
}
|
|
|
|
void QgsProjectionSelectionWidget::addRecentCrs()
|
|
{
|
|
QStringList recentProjections = QgsCoordinateReferenceSystem::recentProjections();
|
|
int i = 0;
|
|
Q_FOREACH ( const QString &projection, recentProjections )
|
|
{
|
|
long srsid = projection.toLong();
|
|
|
|
//check if already shown
|
|
if ( crsIsShown( srsid ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
i++;
|
|
QgsCoordinateReferenceSystem crs = QgsCoordinateReferenceSystem::fromSrsId( srsid );
|
|
if ( crs.isValid() )
|
|
{
|
|
mCrsComboBox->addItem( tr( "%1 - %2" ).arg( crs.authid(), crs.description() ), QgsProjectionSelectionWidget::RecentCrs );
|
|
mCrsComboBox->setItemData( mCrsComboBox->count() - 1, QVariant( ( long long )srsid ), Qt::UserRole + 1 );
|
|
}
|
|
if ( i >= 4 )
|
|
{
|
|
//limit to 4 recent projections to avoid clutter
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool QgsProjectionSelectionWidget::crsIsShown( const long srsid ) const
|
|
{
|
|
return srsid == mLayerCrs.srsid() || srsid == mDefaultCrs.srsid() || srsid == mProjectCrs.srsid();
|
|
}
|
|
|
|
int QgsProjectionSelectionWidget::firstRecentCrsIndex() const
|
|
{
|
|
for ( int i = 0; i < mCrsComboBox->count(); ++i )
|
|
{
|
|
if ( ( CrsOption )mCrsComboBox->itemData( i ).toInt() == RecentCrs )
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|