24 #include <QHeaderView> 25 #include <QResizeEvent> 26 #include <QMessageBox> 30 : QWidget( parent, fl )
31 , mUserProjList( NULL )
34 , mProjListDone( false )
35 , mUserProjListDone( false )
36 , mRecentProjListDone( false )
37 , mSearchColumn( NONE )
38 , mPushProjectionToFront( false )
43 if ( qobject_cast<QDialog*>( parent ) )
52 lstCoordinateSystems->header()->setResizeMode( AUTHID_COLUMN, QHeaderView::Stretch );
53 lstCoordinateSystems->header()->resizeSection( QGIS_CRS_ID_COLUMN, 0 );
54 lstCoordinateSystems->header()->setResizeMode( QGIS_CRS_ID_COLUMN, QHeaderView::Fixed );
57 lstCoordinateSystems->setColumnHidden( QGIS_CRS_ID_COLUMN,
true );
59 lstRecent->header()->setResizeMode( AUTHID_COLUMN, QHeaderView::Stretch );
60 lstRecent->header()->resizeSection( QGIS_CRS_ID_COLUMN, 0 );
61 lstRecent->header()->setResizeMode( QGIS_CRS_ID_COLUMN, QHeaderView::Fixed );
64 lstRecent->setColumnHidden( QGIS_CRS_ID_COLUMN,
true );
71 if ( !mPushProjectionToFront )
82 mRecentProjections.removeAll( QString::number( crsId ) );
83 mRecentProjections.prepend( QString::number( crsId ) );
85 while ( mRecentProjections.size() > 8 )
87 mRecentProjections.removeLast();
92 settings.setValue(
"/UI/recentProjections", mRecentProjections );
96 QStringList projectionsProj4;
97 QStringList projectionsAuthId;
98 for (
int i = 0; i < mRecentProjections.size(); i++ )
102 if ( ! crs.isValid() )
107 projectionsProj4 << crs.
toProj4();
108 projectionsAuthId << crs.authid();
110 settings.setValue(
"/UI/recentProjectionsProj4", projectionsProj4 );
111 settings.setValue(
"/UI/recentProjectionsAuthId", projectionsAuthId );
116 lstCoordinateSystems->header()->resizeSection( NAME_COLUMN, theEvent->size().width() - 240 );
117 lstCoordinateSystems->header()->resizeSection( AUTHID_COLUMN, 240 );
118 lstCoordinateSystems->header()->resizeSection( QGIS_CRS_ID_COLUMN, 0 );
120 lstRecent->header()->resizeSection( NAME_COLUMN, theEvent->size().width() - 240 );
121 lstRecent->header()->resizeSection( AUTHID_COLUMN, 240 );
122 lstRecent->header()->resizeSection( QGIS_CRS_ID_COLUMN, 0 );
132 if ( !mRecentProjListDone )
134 for (
int i = mRecentProjections.size() - 1; i >= 0; i-- )
135 insertRecent( mRecentProjections.at( i ).toLong() );
136 mRecentProjListDone =
true;
145 QWidget::showEvent( theEvent );
148 QString QgsProjectionSelector::ogcWmsCrsFilterAsSqlExpression( QSet<QString> * crsFilter )
150 QString sqlExpression =
"1";
151 QMap<QString, QStringList> authParts;
154 return sqlExpression;
174 foreach ( QString auth_id, crsFilter->values() )
176 QStringList parts = auth_id.split(
":" );
178 if ( parts.size() < 2 )
181 authParts[ parts.at( 0 ).toUpper()].append( parts.at( 1 ).toUpper() );
184 if ( authParts.isEmpty() )
185 return sqlExpression;
187 if ( authParts.size() > 0 )
189 QString prefix =
" AND (";
190 foreach ( QString auth_name, authParts.keys() )
192 sqlExpression += QString(
"%1(upper(auth_name)='%2' AND upper(auth_id) IN ('%3'))" )
195 .arg( authParts[auth_name].join(
"','" ) );
198 sqlExpression +=
")";
201 QgsDebugMsg(
"exiting with '" + sqlExpression +
"'." );
203 return sqlExpression;
208 applySelection( NAME_COLUMN, theCRSName );
213 applySelection( QGIS_CRS_ID_COLUMN, QString::number( theCRSID ) );
218 applySelection( AUTHID_COLUMN,
id );
221 void QgsProjectionSelector::applySelection(
int column, QString value )
223 if ( !mProjListDone || !mUserProjListDone )
226 mSearchColumn = column;
227 mSearchValue = value;
231 if ( column == NONE )
234 column = mSearchColumn;
235 value = mSearchValue;
237 mSearchColumn = NONE;
238 mSearchValue.clear();
241 if ( column == NONE )
244 QList<QTreeWidgetItem*> nodes = lstCoordinateSystems->findItems( value, Qt::MatchExactly | Qt::MatchRecursive, column );
245 if ( nodes.count() > 0 )
247 QgsDebugMsg( QString(
"found %1,%2" ).arg( column ).arg( value ) );
248 lstCoordinateSystems->setCurrentItem( nodes.first() );
252 QgsDebugMsg( QString(
"nothing found for %1,%2" ).arg( column ).arg( value ) );
254 lstCoordinateSystems->clearSelection();
255 lstRecent->clearSelection();
256 teProjection->setText(
"" );
257 teSelected->setText(
"" );
261 void QgsProjectionSelector::insertRecent(
long theCrsId )
263 if ( !mProjListDone || !mUserProjListDone )
266 QList<QTreeWidgetItem*> nodes = lstCoordinateSystems->findItems( QString::number( theCrsId ), Qt::MatchExactly | Qt::MatchRecursive, QGIS_CRS_ID_COLUMN );
267 if ( nodes.count() == 0 )
270 lstRecent->insertTopLevelItem( 0,
new QTreeWidgetItem( lstRecent, QStringList()
271 << nodes.first()->text( NAME_COLUMN )
272 << nodes.first()->text( AUTHID_COLUMN )
273 << nodes.first()->text( QGIS_CRS_ID_COLUMN ) ) );
280 QTreeWidgetItem *lvi = lstCoordinateSystems->currentItem();
281 return lvi ? lvi->text( NAME_COLUMN ) : QString::null;
293 QTreeWidgetItem *item = lstCoordinateSystems->currentItem();
294 if ( !item || item->text( QGIS_CRS_ID_COLUMN ).isEmpty() )
297 QString srsId = item->text( QGIS_CRS_ID_COLUMN );
306 QString databaseFileName;
310 if ( !QFileInfo( databaseFileName ).exists() )
311 return QString(
"" );
315 databaseFileName = mSrsDatabaseFileName;
321 int rc = sqlite3_open_v2( databaseFileName.toUtf8().data(), &database, SQLITE_OPEN_READONLY, NULL );
324 showDBMissingWarning( databaseFileName );
331 QString sql = QString(
"select parameters from tbl_srs where srs_id=%1" ).arg( srsId );
335 rc = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail );
338 if ( rc == SQLITE_OK && sqlite3_step( stmt ) == SQLITE_ROW )
340 projString = QString::fromUtf8((
char * )sqlite3_column_text( stmt, 0 ) );
344 sqlite3_finalize( stmt );
346 sqlite3_close( database );
348 Q_ASSERT( !projString.isEmpty() );
353 QString QgsProjectionSelector::getSelectedExpression( QString expression )
362 QTreeWidgetItem *lvi = lstCoordinateSystems->currentItem();
363 if ( !lvi || lvi->text( QGIS_CRS_ID_COLUMN ).isEmpty() )
370 QString databaseFileName;
374 if ( !QFileInfo( databaseFileName ).exists() )
381 databaseFileName = mSrsDatabaseFileName;
390 int rc = sqlite3_open_v2( databaseFileName.toUtf8().data(), &database, SQLITE_OPEN_READONLY, NULL );
393 showDBMissingWarning( databaseFileName );
400 QString sql = QString(
"select %1 from tbl_srs where srs_id=%2" )
402 .arg( lvi->text( QGIS_CRS_ID_COLUMN ) );
404 QgsDebugMsg( QString(
"Finding selected attribute using : %1" ).arg( sql ) );
405 rc = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail );
407 QString attributeValue;
408 if ( rc == SQLITE_OK && sqlite3_step( stmt ) == SQLITE_ROW )
411 attributeValue = QString::fromUtf8((
char * )sqlite3_column_text( stmt, 0 ) );
415 sqlite3_finalize( stmt );
417 sqlite3_close( database );
420 return attributeValue;
426 return getSelectedExpression(
"srid" ).toLong();
432 int srid = getSelectedExpression(
"srs_id" ).toLong();
434 return QString(
"USER:%1" ).arg( srid );
436 return getSelectedExpression(
"upper(auth_name||':'||auth_id)" );
441 QTreeWidgetItem* item = lstCoordinateSystems->currentItem();
443 if ( item && !item->text( QGIS_CRS_ID_COLUMN ).isEmpty() )
444 return lstCoordinateSystems->currentItem()->text( QGIS_CRS_ID_COLUMN ).toLong();
452 mCrsFilter = crsFilter;
453 mProjListDone =
false;
454 mUserProjListDone =
false;
455 lstCoordinateSystems->clear();
460 if ( mUserProjListDone )
466 QString sqlFilter = ogcWmsCrsFilterAsSqlExpression( crsFilter );
470 mUserProjList =
new QTreeWidgetItem( lstCoordinateSystems, QStringList(
tr(
"User Defined Coordinate Systems" ) ) );
472 QFont fontTemp = mUserProjList->font( 0 );
473 fontTemp.setItalic(
true );
474 fontTemp.setBold(
true );
475 mUserProjList->setFont( 0, fontTemp );
485 if ( !QFileInfo( databaseFileName ).exists() )
487 QgsDebugMsg(
"Users qgis.db not found...skipping" );
488 mUserProjListDone =
true;
496 int result = sqlite3_open_v2( databaseFileName.toUtf8().constData(), &database, SQLITE_OPEN_READONLY, NULL );
503 showDBMissingWarning( databaseFileName );
508 QString sql = QString(
"select description, srs_id from vw_srs where %1" ).arg( sqlFilter );
510 result = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail );
512 if ( result == SQLITE_OK )
514 QTreeWidgetItem *newItem;
515 while ( sqlite3_step( stmt ) == SQLITE_ROW )
517 newItem =
new QTreeWidgetItem( mUserProjList, QStringList( QString::fromUtf8((
char * )sqlite3_column_text( stmt, 0 ) ) ) );
523 newItem->setText( QGIS_CRS_ID_COLUMN, QString::fromUtf8((
char * )sqlite3_column_text( stmt, 1 ) ) );
524 newItem->setText( AUTHID_COLUMN, QString(
"USER:%1" ).arg( QString::fromUtf8((
char * )sqlite3_column_text( stmt, 1 ) ).toInt() ) );
528 sqlite3_finalize( stmt );
529 sqlite3_close( database );
531 mUserProjListDone =
true;
540 QString sqlFilter = ogcWmsCrsFilterAsSqlExpression( crsFilter );
546 mGeoList =
new QTreeWidgetItem( lstCoordinateSystems, QStringList(
tr(
"Geographic Coordinate Systems" ) ) );
548 QFont fontTemp = mGeoList->font( 0 );
549 fontTemp.setItalic(
true );
550 fontTemp.setBold(
true );
551 mGeoList->setFont( 0, fontTemp );
555 mProjList =
new QTreeWidgetItem( lstCoordinateSystems, QStringList(
tr(
"Projected Coordinate Systems" ) ) );
557 fontTemp = mProjList->font( 0 );
558 fontTemp.setItalic(
true );
559 fontTemp.setBold(
true );
560 mProjList->setFont( 0, fontTemp );
568 if ( !QFileInfo( mSrsDatabaseFileName ).exists() )
570 mProjListDone =
true;
576 int rc = sqlite3_open_v2( mSrsDatabaseFileName.toUtf8().data(), &database, SQLITE_OPEN_READONLY, NULL );
581 showDBMissingWarning( mSrsDatabaseFileName );
590 QString sql = QString(
"select description, srs_id, upper(auth_name||':'||auth_id), is_geo, name, parameters, deprecated from vw_srs where %1 order by name,description" )
593 rc = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail );
595 if ( rc == SQLITE_OK )
597 QTreeWidgetItem *newItem;
600 QString previousSrsType(
"" );
601 QTreeWidgetItem* previousSrsTypeNode = 0;
603 while ( sqlite3_step( stmt ) == SQLITE_ROW )
606 int isGeo = sqlite3_column_int( stmt, 3 );
611 newItem =
new QTreeWidgetItem( mGeoList, QStringList( QString::fromUtf8((
char * )sqlite3_column_text( stmt, 0 ) ) ) );
614 newItem->setText( AUTHID_COLUMN, QString::fromUtf8((
char * )sqlite3_column_text( stmt, 2 ) ) );
617 newItem->setText( QGIS_CRS_ID_COLUMN, QString::fromUtf8((
char * )sqlite3_column_text( stmt, 1 ) ) );
622 QTreeWidgetItem *node;
623 QString srsType = QString::fromUtf8((
char* )sqlite3_column_text( stmt, 4 ) );
626 if ( srsType == previousSrsType )
628 node = previousSrsTypeNode;
632 QList<QTreeWidgetItem*> nodes = lstCoordinateSystems->findItems( srsType, Qt::MatchExactly | Qt::MatchRecursive, NAME_COLUMN );
633 if ( nodes.count() == 0 )
637 node =
new QTreeWidgetItem( mProjList, QStringList( srsType ) );
638 QFont fontTemp = node->font( 0 );
639 fontTemp.setItalic(
true );
640 node->setFont( 0, fontTemp );
644 node = nodes.first();
647 previousSrsType = srsType;
648 previousSrsTypeNode = node;
651 newItem =
new QTreeWidgetItem( node, QStringList( QString::fromUtf8((
char * )sqlite3_column_text( stmt, 0 ) ) ) );
653 newItem->setText( AUTHID_COLUMN, QString::fromUtf8((
char * )sqlite3_column_text( stmt, 2 ) ) );
655 newItem->setText( QGIS_CRS_ID_COLUMN, QString::fromUtf8((
char * )sqlite3_column_text( stmt, 1 ) ) );
657 newItem->parent()->setExpanded(
true );
661 newItem->setData( 0, Qt::UserRole, QString::fromUtf8((
char * )sqlite3_column_text( stmt, 6 ) ) );
662 newItem->setHidden( cbxHideDeprecated->isChecked() );
664 mProjList->setExpanded(
true );
668 sqlite3_finalize( stmt );
670 sqlite3_close( database );
672 mProjListDone =
true;
686 lstCoordinateSystems->scrollToItem( current );
690 if ( current->childCount() == 0 )
698 QList<QTreeWidgetItem*> nodes = lstRecent->findItems( current->text( QGIS_CRS_ID_COLUMN ), Qt::MatchExactly, QGIS_CRS_ID_COLUMN );
699 if ( nodes.count() > 0 )
701 QgsDebugMsg( QString(
"found srs %1 in recent" ).arg( current->text( QGIS_CRS_ID_COLUMN ) ) );
702 lstRecent->setCurrentItem( nodes.first() );
706 QgsDebugMsg( QString(
"srs %1 not recent" ).arg( current->text( QGIS_CRS_ID_COLUMN ) ) );
707 lstRecent->clearSelection();
708 lstCoordinateSystems->setFocus( Qt::OtherFocusReason );
714 current->setSelected(
false );
715 teProjection->setText(
"" );
716 teSelected->setText(
"" );
717 lstRecent->clearSelection();
731 lstRecent->scrollToItem( current );
733 QList<QTreeWidgetItem*> nodes = lstCoordinateSystems->findItems( current->text( QGIS_CRS_ID_COLUMN ), Qt::MatchExactly | Qt::MatchRecursive, QGIS_CRS_ID_COLUMN );
734 if ( nodes.count() > 0 )
735 lstCoordinateSystems->setCurrentItem( nodes.first() );
738 void QgsProjectionSelector::hideDeprecated( QTreeWidgetItem *item )
740 if ( item->data( 0, Qt::UserRole ).toBool() )
742 item->setHidden( cbxHideDeprecated->isChecked() );
743 if ( item->isSelected() && item->isHidden() )
745 item->setSelected(
false );
746 teProjection->setText(
"" );
747 teSelected->setText(
"" );
751 for (
int i = 0; i < item->childCount(); i++ )
752 hideDeprecated( item->child( i ) );
757 for (
int i = 0; i < lstCoordinateSystems->topLevelItemCount(); i++ )
758 hideDeprecated( lstCoordinateSystems->topLevelItem( i ) );
763 QString filterTxt = theFilterTxt;
764 filterTxt.replace( QRegExp(
"\\s+" ),
".*" );
765 QRegExp re( filterTxt, Qt::CaseInsensitive );
768 QTreeWidgetItemIterator itr( lstRecent );
771 if (( *itr )->childCount() == 0 )
773 if (( *itr )->text( NAME_COLUMN ).contains( re )
774 || ( *itr )->text( AUTHID_COLUMN ).contains( re )
777 ( *itr )->setHidden(
false );
778 QTreeWidgetItem * parent = ( *itr )->parent();
781 parent->setExpanded(
true );
782 parent->setHidden(
false );
783 parent = parent->parent();
788 ( *itr )->setHidden(
true );
793 ( *itr )->setHidden(
true );
799 QTreeWidgetItemIterator it( lstCoordinateSystems );
802 if (( *it )->childCount() == 0 )
804 if (( *it )->text( NAME_COLUMN ).contains( re )
805 || ( *it )->text( AUTHID_COLUMN ).contains( re )
808 ( *it )->setHidden(
false );
809 QTreeWidgetItem * parent = ( *it )->parent();
812 parent->setExpanded(
true );
813 parent->setHidden(
false );
814 parent = parent->parent();
819 ( *it )->setHidden(
true );
824 ( *it )->setHidden(
true );
834 mPushProjectionToFront =
true;
838 long QgsProjectionSelector::getLargestCRSIDMatch( QString theSql )
855 if ( QFileInfo( databaseFileName ).exists() )
857 result = sqlite3_open_v2( databaseFileName.toUtf8().data(), &database, SQLITE_OPEN_READONLY, NULL );
864 showDBMissingWarning( databaseFileName );
868 result = sqlite3_prepare( database, theSql.toUtf8(), theSql.toUtf8().length(), &stmt, &tail );
870 if ( result == SQLITE_OK && sqlite3_step( stmt ) == SQLITE_ROW )
872 QString srsIdString = QString::fromUtf8((
char * )sqlite3_column_text( stmt, 0 ) );
873 srsId = srsIdString.toLong();
875 sqlite3_finalize( stmt );
876 sqlite3_close( database );
883 result = sqlite3_open_v2( mSrsDatabaseFileName.toUtf8().data(), &database, SQLITE_OPEN_READONLY, NULL );
886 QgsDebugMsg( QString(
"Can't open * user * database: %1" ).arg( sqlite3_errmsg( database ) ) );
892 result = sqlite3_prepare( database, theSql.toUtf8(), theSql.toUtf8().length(), &stmt, &tail );
894 if ( result == SQLITE_OK && sqlite3_step( stmt ) == SQLITE_ROW )
896 QString srsIdString = QString::fromUtf8((
char * )sqlite3_column_text( stmt, 0 ) );
897 srsId = srsIdString.toLong();
901 sqlite3_finalize( stmt );
902 sqlite3_close( database );
907 QStringList QgsProjectionSelector::authorities()
913 int result = sqlite3_open_v2( mSrsDatabaseFileName.toUtf8().data(), &database, SQLITE_OPEN_READONLY, NULL );
916 QgsDebugMsg( QString(
"Can't open * user * database: %1" ).arg( sqlite3_errmsg( database ) ) );
918 return QStringList();
921 QString theSql =
"select distinct auth_name from tbl_srs";
922 result = sqlite3_prepare( database, theSql.toUtf8(), theSql.toUtf8().length(), &stmt, &tail );
924 QStringList authorities;
925 if ( result == SQLITE_OK )
927 while ( sqlite3_step( stmt ) == SQLITE_ROW )
929 authorities << QString::fromUtf8((
char * )sqlite3_column_text( stmt, 0 ) );
935 sqlite3_finalize( stmt );
936 sqlite3_close( database );
952 QString retval = theSQL;
953 retval.replace(
"\\",
"\\\\" );
954 retval.replace(
'\"',
"\\\"" );
955 retval.replace(
"\'",
"\\'" );
956 retval.replace(
"%",
"\\%" );
960 void QgsProjectionSelector::showDBMissingWarning(
const QString theFileName )
963 QMessageBox::critical(
this,
tr(
"Resource Location Error" ),
964 tr(
"Error reading database file from: \n %1\n" 965 "Because of this the projection selector will not work..." )
966 .arg( theFileName ) );
const QString sqlSafeString(const QString theSQL)
Make the string safe for use in SQL statements. This involves escaping single quotes, double quotes, backslashes, and optionally, percentage symbols. Percentage symbols are used as wildcards sometimes and so when using the string as part of the LIKE phrase of a select statement, should be escaped.
void resizeEvent(QResizeEvent *theEvent) override
Used to manage column sizes.
static const QString activeThemePath()
Returns the path to the currently active theme directory.
void setOgcWmsCrsFilter(QSet< QString > crsFilter)
filters this widget by the given CRSs
QgsProjectionSelector(QWidget *parent, const char *name="", Qt::WindowFlags fl=0)
void setSelectedCrsId(long theCRSID)
QString selectedProj4String()
long selectedPostgresSrId()
Gets the current PostGIS-style projection identifier.
void loadUserCrsList(QSet< QString > *crsFilter=0)
Populate the proj tree view with user defined projection names...
void setSelectedCrsName(QString theCRSName)
void on_lstRecent_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *prev)
QString selectedAuthId()
Gets the current authority-style projection identifier.
static QStringList recentProjections()
Returns a list of recently used projections.
void setSelectedAuthId(QString authId)
void on_cbxHideDeprecated_stateChanged()
void on_lstCoordinateSystems_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *prev)
void sridSelected(QString theSRID)
void on_leSearch_textChanged(const QString &)
void pushProjectionToFront()
mark selected projection for push to front
const int USER_CRS_START_ID
Magick number that determines whether a projection crsid is a system (srs.db) or user (~/...
void loadCrsList(QSet< QString > *crsFilter=0)
Populate the proj tree view with system projection names...
Class for storing a coordinate reference system (CRS)
static const QString srsDbFilePath()
Returns the path to the srs.db file.
void initialized()
Notify others that the widget is now fully initialized, including deferred selection of projection...
void showEvent(QShowEvent *theEvent) override
Used to ensure the projection list view is actually populated.
static const QString qgisUserDbFilePath()
Returns the path to the user qgis.db file.
QString toProj4() const
Get the Proj Proj4 string representation of this srs.
long selectedCrsId()
Gets the current QGIS projection identfier.