QGIS/src/gui/qgsprojectionselectionwidget.cpp
Juergen E. Fischer 0a1517bfaa header cleanups
2017-03-04 02:38:15 +01:00

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;
}