25 #include <QHeaderView> 26 #include <QResizeEvent> 27 #include <QMessageBox> 32 , mUserProjList( nullptr )
34 , mProjList( nullptr )
35 , mProjListDone( false )
36 , mUserProjListDone( false )
37 , mRecentProjListDone( false )
38 , mSearchColumn( NONE )
39 , mPushProjectionToFront( false )
44 if ( qobject_cast<QDialog*>( parent ) )
53 lstCoordinateSystems->header()->setResizeMode( AUTHID_COLUMN, QHeaderView::Stretch );
54 lstCoordinateSystems->header()->resizeSection( QGIS_CRS_ID_COLUMN, 0 );
55 lstCoordinateSystems->header()->setResizeMode( QGIS_CRS_ID_COLUMN, QHeaderView::Fixed );
58 lstCoordinateSystems->setColumnHidden( QGIS_CRS_ID_COLUMN,
true );
60 lstRecent->header()->setResizeMode( AUTHID_COLUMN, QHeaderView::Stretch );
61 lstRecent->header()->resizeSection( QGIS_CRS_ID_COLUMN, 0 );
62 lstRecent->header()->setResizeMode( QGIS_CRS_ID_COLUMN, QHeaderView::Fixed );
65 lstRecent->setColumnHidden( QGIS_CRS_ID_COLUMN,
true );
72 if ( !mPushProjectionToFront )
86 while ( mRecentProjections.
size() > 8 )
93 settings.
setValue(
"/UI/recentProjections", mRecentProjections );
99 for (
int i = 0; i < mRecentProjections.
size(); i++ )
103 if ( ! crs.isValid() )
108 projectionsProj4 << crs.toProj4();
109 projectionsAuthId << crs.authid();
111 settings.
setValue(
"/UI/recentProjectionsProj4", projectionsProj4 );
112 settings.
setValue(
"/UI/recentProjectionsAuthId", projectionsAuthId );
117 lstCoordinateSystems->header()->resizeSection( NAME_COLUMN, theEvent->
size().
width() - 240 );
118 lstCoordinateSystems->header()->resizeSection( AUTHID_COLUMN, 240 );
119 lstCoordinateSystems->header()->resizeSection( QGIS_CRS_ID_COLUMN, 0 );
121 lstRecent->header()->resizeSection( NAME_COLUMN, theEvent->
size().
width() - 240 );
122 lstRecent->header()->resizeSection( AUTHID_COLUMN, 240 );
123 lstRecent->header()->resizeSection( QGIS_CRS_ID_COLUMN, 0 );
133 if ( !mRecentProjListDone )
135 for (
int i = mRecentProjections.
size() - 1; i >= 0; i-- )
136 insertRecent( mRecentProjections.
at( i ).toLong() );
137 mRecentProjListDone =
true;
155 return sqlExpression;
175 Q_FOREACH (
const QString& auth_id, *crsFilter )
179 if ( parts.
size() < 2 )
182 authParts[ parts.
at( 0 ).toUpper()].append( parts.
at( 1 ).toUpper() );
186 return sqlExpression;
191 Q_FOREACH (
const QString& auth_name, authParts.
keys() )
193 sqlExpression +=
QString(
"%1(upper(auth_name)='%2' AND upper(auth_id) IN ('%3'))" )
196 authParts[auth_name].join(
"','" ) );
199 sqlExpression +=
')';
202 QgsDebugMsg(
"exiting with '" + sqlExpression +
"'." );
204 return sqlExpression;
209 applySelection( NAME_COLUMN, theCRSName );
219 applySelection( AUTHID_COLUMN,
id );
222 void QgsProjectionSelector::applySelection(
int column,
QString value )
224 if ( !mProjListDone || !mUserProjListDone )
227 mSearchColumn = column;
228 mSearchValue = value;
232 if ( column == NONE )
235 column = mSearchColumn;
236 value = mSearchValue;
238 mSearchColumn = NONE;
239 mSearchValue.
clear();
242 if ( column == NONE )
245 QList<QTreeWidgetItem*> nodes = lstCoordinateSystems->findItems( value, Qt::MatchExactly | Qt::MatchRecursive, column );
249 lstCoordinateSystems->setCurrentItem( nodes.
first() );
255 lstCoordinateSystems->clearSelection();
256 lstRecent->clearSelection();
257 teProjection->setText(
"" );
258 teSelected->setText(
"" );
262 void QgsProjectionSelector::insertRecent(
long theCrsId )
264 if ( !mProjListDone || !mUserProjListDone )
272 << nodes.
first()->text( NAME_COLUMN )
273 << nodes.
first()->text( AUTHID_COLUMN )
274 << nodes.
first()->text( QGIS_CRS_ID_COLUMN ) ) );
282 return lvi ? lvi->
text( NAME_COLUMN ) : QString::null;
295 if ( !item || item->
text( QGIS_CRS_ID_COLUMN ).
isEmpty() )
311 if ( !
QFileInfo( databaseFileName ).exists() )
316 databaseFileName = mSrsDatabaseFileName;
322 int rc = sqlite3_open_v2( databaseFileName.
toUtf8().
data(), &database, SQLITE_OPEN_READONLY, nullptr );
325 showDBMissingWarning( databaseFileName );
332 QString sql =
QString(
"select parameters from tbl_srs where srs_id=%1" ).
arg( srsId );
339 if ( rc == SQLITE_OK && sqlite3_step( stmt ) == SQLITE_ROW )
345 sqlite3_finalize( stmt );
347 sqlite3_close( database );
349 Q_ASSERT( !projString.isEmpty() );
354 QString QgsProjectionSelector::getSelectedExpression(
const QString& expression )
364 if ( !lvi || lvi->
text( QGIS_CRS_ID_COLUMN ).
isEmpty() )
375 if ( !
QFileInfo( databaseFileName ).exists() )
382 databaseFileName = mSrsDatabaseFileName;
391 int rc = sqlite3_open_v2( databaseFileName.
toUtf8().
data(), &database, SQLITE_OPEN_READONLY, nullptr );
394 showDBMissingWarning( databaseFileName );
403 lvi->
text( QGIS_CRS_ID_COLUMN ) );
409 if ( rc == SQLITE_OK && sqlite3_step( stmt ) == SQLITE_ROW )
416 sqlite3_finalize( stmt );
418 sqlite3_close( database );
421 return attributeValue;
427 return getSelectedExpression(
"srid" ).
toLong();
433 int srid = getSelectedExpression(
"srs_id" ).
toLong();
437 return getSelectedExpression(
"upper(auth_name||':'||auth_id)" );
444 if ( item && !item->
text( QGIS_CRS_ID_COLUMN ).
isEmpty() )
445 return lstCoordinateSystems->currentItem()->
text( QGIS_CRS_ID_COLUMN ).
toLong();
453 mCrsFilter = crsFilter;
454 mProjListDone =
false;
455 mUserProjListDone =
false;
456 lstCoordinateSystems->clear();
461 if ( mUserProjListDone )
467 QString sqlFilter = ogcWmsCrsFilterAsSqlExpression( crsFilter );
473 QFont fontTemp = mUserProjList->
font( 0 );
476 mUserProjList->
setFont( 0, fontTemp );
486 if ( !
QFileInfo( databaseFileName ).exists() )
488 QgsDebugMsg(
"Users qgis.db not found...skipping" );
489 mUserProjListDone =
true;
497 int result = sqlite3_open_v2( databaseFileName.
toUtf8().
constData(), &database, SQLITE_OPEN_READONLY, nullptr );
504 showDBMissingWarning( databaseFileName );
509 QString sql =
QString(
"select description, srs_id from vw_srs where %1" ).
arg( sqlFilter );
511 result = sqlite3_prepare( database, sql.
toUtf8(), sql.
toUtf8().
length(), &stmt, &tail );
513 if ( result == SQLITE_OK )
516 while ( sqlite3_step( stmt ) == SQLITE_ROW )
529 sqlite3_finalize( stmt );
530 sqlite3_close( database );
532 mUserProjListDone =
true;
541 QString sqlFilter = ogcWmsCrsFilterAsSqlExpression( crsFilter );
552 mGeoList->
setFont( 0, fontTemp );
558 fontTemp = mProjList->
font( 0 );
561 mProjList->
setFont( 0, fontTemp );
569 if ( !
QFileInfo( mSrsDatabaseFileName ).exists() )
571 mProjListDone =
true;
577 int rc = sqlite3_open_v2( mSrsDatabaseFileName.
toUtf8().
data(), &database, SQLITE_OPEN_READONLY, nullptr );
582 showDBMissingWarning( mSrsDatabaseFileName );
591 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" )
596 if ( rc == SQLITE_OK )
604 while ( sqlite3_step( stmt ) == SQLITE_ROW )
607 int isGeo = sqlite3_column_int( stmt, 3 );
627 if ( srsType == previousSrsType )
629 node = previousSrsTypeNode;
633 QList<QTreeWidgetItem*> nodes = lstCoordinateSystems->findItems( srsType, Qt::MatchExactly | Qt::MatchRecursive, NAME_COLUMN );
645 node = nodes.
first();
648 previousSrsType = srsType;
649 previousSrsTypeNode = node;
663 newItem->
setHidden( cbxHideDeprecated->isChecked() );
669 sqlite3_finalize( stmt );
671 sqlite3_close( database );
673 mProjListDone =
true;
687 lstCoordinateSystems->scrollToItem( current );
703 lstRecent->setCurrentItem( nodes.
first() );
708 lstRecent->clearSelection();
709 lstCoordinateSystems->setFocus( Qt::OtherFocusReason );
716 teProjection->setText(
"" );
717 teSelected->setText(
"" );
718 lstRecent->clearSelection();
722 void QgsProjectionSelector::on_lstCoordinateSystems_itemDoubleClicked(
QTreeWidgetItem *current,
int column )
750 lstRecent->scrollToItem( current );
752 QList<QTreeWidgetItem*> nodes = lstCoordinateSystems->findItems( current->
text( QGIS_CRS_ID_COLUMN ), Qt::MatchExactly | Qt::MatchRecursive, QGIS_CRS_ID_COLUMN );
754 lstCoordinateSystems->setCurrentItem( nodes.
first() );
757 void QgsProjectionSelector::on_lstRecent_itemDoubleClicked(
QTreeWidgetItem *current,
int column )
769 QList<QTreeWidgetItem*> nodes = lstCoordinateSystems->findItems( current->
text( QGIS_CRS_ID_COLUMN ), Qt::MatchExactly | Qt::MatchRecursive, QGIS_CRS_ID_COLUMN );
778 item->
setHidden( cbxHideDeprecated->isChecked() );
782 teProjection->setText(
"" );
783 teSelected->setText(
"" );
787 for (
int i = 0; i < item->
childCount(); i++ )
788 hideDeprecated( item->
child( i ) );
793 for (
int i = 0; i < lstCoordinateSystems->topLevelItemCount(); i++ )
794 hideDeprecated( lstCoordinateSystems->topLevelItem( i ) );
799 QString filterTxt = theFilterTxt;
801 QRegExp re( filterTxt, Qt::CaseInsensitive );
807 if (( *itr )->childCount() == 0 )
809 if (( *itr )->text( NAME_COLUMN ).contains( re )
810 || ( *itr )->text( AUTHID_COLUMN ).contains( re )
813 ( *itr )->setHidden(
false );
819 parent = parent->
parent();
829 ( *itr )->setHidden(
true );
838 if (( *it )->childCount() == 0 )
840 if (( *it )->text( NAME_COLUMN ).contains( re )
841 || ( *it )->text( AUTHID_COLUMN ).contains( re )
844 ( *it )->setHidden(
false );
850 parent = parent->
parent();
860 ( *it )->setHidden(
true );
870 mPushProjectionToFront =
true;
874 long QgsProjectionSelector::getLargestCRSIDMatch(
const QString& theSql )
891 if (
QFileInfo( databaseFileName ).exists() )
893 result = sqlite3_open_v2( databaseFileName.
toUtf8().
data(), &database, SQLITE_OPEN_READONLY, nullptr );
900 showDBMissingWarning( databaseFileName );
904 result = sqlite3_prepare( database, theSql.
toUtf8(), theSql.
toUtf8().
length(), &stmt, &tail );
906 if ( result == SQLITE_OK && sqlite3_step( stmt ) == SQLITE_ROW )
909 srsId = srsIdString.
toLong();
911 sqlite3_finalize( stmt );
912 sqlite3_close( database );
919 result = sqlite3_open_v2( mSrsDatabaseFileName.
toUtf8().
data(), &database, SQLITE_OPEN_READONLY, nullptr );
922 QgsDebugMsg(
QString(
"Can't open * user * database: %1" ).arg( sqlite3_errmsg( database ) ) );
928 result = sqlite3_prepare( database, theSql.
toUtf8(), theSql.
toUtf8().
length(), &stmt, &tail );
930 if ( result == SQLITE_OK && sqlite3_step( stmt ) == SQLITE_ROW )
933 srsId = srsIdString.
toLong();
937 sqlite3_finalize( stmt );
938 sqlite3_close( database );
949 int result = sqlite3_open_v2( mSrsDatabaseFileName.
toUtf8().
data(), &database, SQLITE_OPEN_READONLY, nullptr );
952 QgsDebugMsg(
QString(
"Can't open * user * database: %1" ).arg( sqlite3_errmsg( database ) ) );
957 QString theSql =
"select distinct auth_name from tbl_srs";
958 result = sqlite3_prepare( database, theSql.
toUtf8(), theSql.
toUtf8().
length(), &stmt, &tail );
961 if ( result == SQLITE_OK )
963 while ( sqlite3_step( stmt ) == SQLITE_ROW )
971 sqlite3_finalize( stmt );
972 sqlite3_close( database );
989 retval.
replace(
'\\',
"\\\\" );
990 retval.
replace(
'\"',
"\\\"" );
996 void QgsProjectionSelector::showDBMissingWarning(
const QString& theFileName )
1000 tr(
"Error reading database file from: \n %1\n" 1001 "Because of this the projection selector will not work..." )
1002 .arg( theFileName ) );
void resizeEvent(QResizeEvent *theEvent) override
Used to manage column sizes.
static QString qgisUserDbFilePath()
Returns the path to the user qgis.db file.
void projectionDoubleClicked()
Apply projection on double click.
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.
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
const T & at(int i) const
void setSelectedCrsId(long theCRSID)
QgsProjectionSelector(QWidget *parent, const char *name="", const Qt::WindowFlags &fl=nullptr)
QString selectedProj4String()
long selectedPostgresSrId()
Gets the current PostGIS-style projection identifier.
QString tr(const char *sourceText, const char *disambiguation, int n)
void on_lstRecent_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *prev)
void setBold(bool enable)
QList< Key > keys() const
void setValue(const QString &key, const QVariant &value)
void sridSelected(const QString &theSRID)
QString number(int n, int base)
QString selectedAuthId()
Gets the current authority-style projection identifier.
QString fromUtf8(const char *str, int size)
void setSelectedCrsName(const QString &theCRSName)
static QStringList recentProjections()
Returns a list of recently used projections.
int removeAll(const T &value)
const char * constData() const
void on_cbxHideDeprecated_stateChanged()
void loadUserCrsList(QSet< QString > *crsFilter=nullptr)
Populate the proj tree view with user defined projection names...
void on_lstCoordinateSystems_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *prev)
void on_leSearch_textChanged(const QString &)
void pushProjectionToFront()
mark selected projection for push to front
void setSelectedAuthId(const QString &authId)
void loadCrsList(QSet< QString > *crsFilter=nullptr)
Populate the proj tree view with system projection names...
const QSize & size() const
void setItalic(bool enable)
long toLong(bool *ok, int base) const
QString & replace(int position, int n, QChar after)
const int USER_CRS_START_ID
Magick number that determines whether a projection crsid is a system (srs.db) or user (~/...
void setOgcWmsCrsFilter(const QSet< QString > &crsFilter)
filters this widget by the given CRSs
Class for storing a coordinate reference system (CRS)
void setText(int column, const QString &text)
void initialized()
Notify others that the widget is now fully initialized, including deferred selection of projection...
StandardButton critical(QWidget *parent, const QString &title, const QString &text, QFlags< QMessageBox::StandardButton > buttons, StandardButton defaultButton)
void prepend(const T &value)
void showEvent(QShowEvent *theEvent) override
Used to ensure the projection list view is actually populated.
static QString srsDbFilePath()
Returns the path to the srs.db file.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QString text(int column) const
long selectedCrsId()
Gets the current QGIS projection identfier.
QByteArray toUtf8() const