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