void QgsProjectionSelectionTreeWidget::loadCrsList( QSet<QString> *crsFilter )
{
  if ( mProjListDone )
    return;

  // convert our Coordinate Reference System filter into the SQL expression
  QString sqlFilter = ogcWmsCrsFilterAsSqlExpression( crsFilter );

  // Create the top-level nodes for the list view of projections
  // Make in an italic font to distinguish them from real projections
  //
  // Geographic coordinate system node
  mGeoList = new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr( "Geographic Coordinate Systems" ) ) );

  QFont fontTemp = mGeoList->font( 0 );
  fontTemp.setItalic( true );
  fontTemp.setBold( true );
  mGeoList->setFont( 0, fontTemp );
  mGeoList->setIcon( 0, QgsApplication::getThemeIcon( QStringLiteral( "/mIconProjectionEnabled.svg" ) ) );

  // Projected coordinate system node
  mProjList = new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr( "Projected Coordinate Systems" ) ) );

  fontTemp = mProjList->font( 0 );
  fontTemp.setItalic( true );
  fontTemp.setBold( true );
  mProjList->setFont( 0, fontTemp );
  mProjList->setIcon( 0, QgsApplication::getThemeIcon( QStringLiteral( "/transformed.svg" ) ) );

  //bail out in case the projections db does not exist
  //this is necessary in case the pc is running linux with a
  //read only filesystem because otherwise sqlite will try
  //to create the db file on the fly

  if ( !QFileInfo::exists( mSrsDatabaseFileName ) )
  {
    mProjListDone = true;
    return;
  }

  // open the database containing the spatial reference data
  sqlite3 *database = nullptr;
  int rc = sqlite3_open_v2( mSrsDatabaseFileName.toUtf8().data(), &database, SQLITE_OPEN_READONLY, nullptr );
  if ( rc )
  {
    // XXX This will likely never happen since on open, sqlite creates the
    //     database if it does not exist.
    showDBMissingWarning( mSrsDatabaseFileName );
    return;
  }

  const char *tail = nullptr;
  sqlite3_stmt *stmt = nullptr;
  // Set up the query to retrieve the projection information needed to populate the list
  //note I am giving the full field names for clarity here and in case someone
  //changes the underlying view TS
  QString sql = QStringLiteral( "select description, srs_id, upper(auth_name||':'||auth_id), is_geo, name, parameters, deprecated from vw_srs where %1 order by name,description" )
                .arg( sqlFilter );

  rc = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail );
  // XXX Need to free memory from the error msg if one is set
  if ( rc == SQLITE_OK )
  {
    QTreeWidgetItem *newItem = nullptr;
    // Cache some stuff to speed up creating of the list of projected
    // spatial reference systems
    QString previousSrsType;
    QTreeWidgetItem *previousSrsTypeNode = nullptr;

    while ( sqlite3_step( stmt ) == SQLITE_ROW )
    {
      // check to see if the srs is geographic
      int isGeo = sqlite3_column_int( stmt, 3 );
      if ( isGeo )
      {
        // this is a geographic coordinate system
        // Add it to the tree (field 0)
        newItem = new QTreeWidgetItem( mGeoList, QStringList( QString::fromUtf8( ( char * )sqlite3_column_text( stmt, 0 ) ) ) );

        // display the authority name (field 2) in the second column of the list view
        newItem->setText( AuthidColumn, QString::fromUtf8( ( char * )sqlite3_column_text( stmt, 2 ) ) );

        // display the qgis srs_id (field 1) in the third column of the list view
        newItem->setText( QgisCrsIdColumn, QString::fromUtf8( ( char * )sqlite3_column_text( stmt, 1 ) ) );
      }
      else
      {
        // This is a projected srs
        QTreeWidgetItem *node = nullptr;
        QString srsType = QString::fromUtf8( ( char * )sqlite3_column_text( stmt, 4 ) );
        // Find the node for this type and add the projection to it
        // If the node doesn't exist, create it
        if ( srsType == previousSrsType )
        {
          node = previousSrsTypeNode;
        }
        else
        {
          // Different from last one, need to search
          QList<QTreeWidgetItem *> nodes = lstCoordinateSystems->findItems( srsType, Qt::MatchExactly | Qt::MatchRecursive, NameColumn );
          if ( nodes.isEmpty() )
          {
            // the node doesn't exist -- create it
            // Make in an italic font to distinguish them from real projections
            node = new QTreeWidgetItem( mProjList, QStringList( srsType ) );
            QFont fontTemp = node->font( 0 );
            fontTemp.setItalic( true );
            node->setFont( 0, fontTemp );
          }
          else
          {
            node = nodes.first();
          }
          // Update the cache.
          previousSrsType = srsType;
          previousSrsTypeNode = node;
        }
        // add the item, setting the projection name in the first column of the list view
        newItem = new QTreeWidgetItem( node, QStringList( QString::fromUtf8( ( char * )sqlite3_column_text( stmt, 0 ) ) ) );
        // display the authority id (field 2) in the second column of the list view
        newItem->setText( AuthidColumn, QString::fromUtf8( ( char * )sqlite3_column_text( stmt, 2 ) ) );
        // display the qgis srs_id (field 1) in the third column of the list view
        newItem->setText( QgisCrsIdColumn, QString::fromUtf8( ( char * )sqlite3_column_text( stmt, 1 ) ) );
        // expand also parent node
        newItem->parent()->setExpanded( true );
      }

      // display the qgis deprecated in the user data of the item
      newItem->setData( 0, RoleDeprecated, QString::fromUtf8( ( char * )sqlite3_column_text( stmt, 6 ) ) );
      newItem->setHidden( cbxHideDeprecated->isChecked() );
    }
    mProjList->setExpanded( true );
  }

  // close the sqlite3 statement
  sqlite3_finalize( stmt );
  // close the database
  sqlite3_close( database );

  mProjListDone = true;
}
void QgsProjectionSelector::loadCrsList( QSet<QString> * crsFilter )
{
    // convert our Coordinate Reference System filter into the SQL expression
    QString sqlFilter = ogcWmsCrsFilterAsSqlExpression( crsFilter );

    // Create the top-level nodes for the list view of projections
    // Make in an italic font to distinguish them from real projections
    //
    // Geographic coordinate system node
    mGeoList = new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr( "Geographic Coordinate Systems" ) ) );

    QFont fontTemp = mGeoList->font( 0 );
    fontTemp.setItalic( TRUE );
    fontTemp.setBold( TRUE );
    mGeoList->setFont( 0, fontTemp );
    mGeoList->setIcon( 0, QIcon( QgsApplication::activeThemePath() + "geographic.png" ) );

    // Projected coordinate system node
    mProjList = new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr( "Projected Coordinate Systems" ) ) );

    fontTemp = mProjList->font( 0 );
    fontTemp.setItalic( TRUE );
    fontTemp.setBold( TRUE );
    mProjList->setFont( 0, fontTemp );
    mProjList->setIcon( 0, QIcon( QgsApplication::activeThemePath() + "transformed.png" ) );

    //bail out in case the projections db does not exist
    //this is neccessary in case the pc is running linux with a
    //read only filesystem because otherwise sqlite will try
    //to create the db file on the fly

    QFileInfo myFileInfo;
    myFileInfo.setFile( mSrsDatabaseFileName );
    if ( !myFileInfo.exists( ) )
    {
        mProjListDone = TRUE;
        return;
    }

    // open the database containing the spatial reference data
    sqlite3 *db;
    int rc;
    rc = sqlite3_open( mSrsDatabaseFileName.toUtf8().data(), &db );
    if ( rc )
    {
        // XXX This will likely never happen since on open, sqlite creates the
        //     database if it does not exist.
        showDBMissingWarning( mSrsDatabaseFileName );
        return ;
    }
    // prepare the sql statement
    const char *pzTail;
    sqlite3_stmt *ppStmt;
    // get total count of records in the projection table
    QString sql = "select count(*) from tbl_srs";

    rc = sqlite3_prepare( db, sql.toUtf8(), sql.length(), &ppStmt, &pzTail );
    assert( rc == SQLITE_OK );
    sqlite3_step( ppStmt );

    sqlite3_finalize( ppStmt );

    // Set up the query to retrieve the projection information needed to populate the list
    //note I am giving the full field names for clarity here and in case someown
    //changes the underlying view TS
    sql = "select description, srs_id, epsg, is_geo, name, parameters from vw_srs ";
    sql += "where ";
    sql += sqlFilter;
    sql += " order by name, description";

    rc = sqlite3_prepare( db, sql.toUtf8(), sql.length(), &ppStmt, &pzTail );
    // XXX Need to free memory from the error msg if one is set
    if ( rc == SQLITE_OK )
    {
        QTreeWidgetItem *newItem;
        // Cache some stuff to speed up creating of the list of projected
        // spatial reference systems
        QString previousSrsType( "" );
        QTreeWidgetItem* previousSrsTypeNode = NULL;

        while ( sqlite3_step( ppStmt ) == SQLITE_ROW )
        {
            // check to see if the srs is geographic
            int isGeo = sqlite3_column_int( ppStmt, 3 );
            if ( isGeo )
            {
                // this is a geographic coordinate system
                // Add it to the tree (field 0)
                newItem = new QTreeWidgetItem( mGeoList, QStringList( QString::fromUtf8(( char * )sqlite3_column_text( ppStmt, 0 ) ) ) );

                // display the epsg (field 2) in the second column of the list view
                newItem->setText( EPSG_COLUMN, QString::fromUtf8(( char * )sqlite3_column_text( ppStmt, 2 ) ) );

                // display the qgis srs_id (field 1) in the third column of the list view
                newItem->setText( QGIS_CRS_ID_COLUMN, QString::fromUtf8(( char * )sqlite3_column_text( ppStmt, 1 ) ) );
            }
            else
            {
                // This is a projected srs
                QTreeWidgetItem *node;
                QString srsType = QString::fromUtf8(( char* )sqlite3_column_text( ppStmt, 4 ) );
                // Find the node for this type and add the projection to it
                // If the node doesn't exist, create it
                if ( srsType == previousSrsType )
                {
                    node = previousSrsTypeNode;
                }
                else
                {   // Different from last one, need to search
                    QList<QTreeWidgetItem*> nodes = lstCoordinateSystems->findItems( srsType, Qt::MatchExactly | Qt::MatchRecursive, 0 );
                    if ( nodes.count() == 0 )
                    {
                        // the node doesn't exist -- create it
                        // Make in an italic font to distinguish them from real projections
                        node = new QTreeWidgetItem( mProjList, QStringList( srsType ) );

                        QFont fontTemp = node->font( 0 );
                        fontTemp.setItalic( TRUE );
                        node->setFont( 0, fontTemp );
                    }
                    else
                    {
                        node = nodes.first();
                    }
                    // Update the cache.
                    previousSrsType = srsType;
                    previousSrsTypeNode = node;
                }
                // add the item, setting the projection name in the first column of the list view
                newItem = new QTreeWidgetItem( node, QStringList( QString::fromUtf8(( char * )sqlite3_column_text( ppStmt, 0 ) ) ) );
                // display the epsg (field 2) in the second column of the list view
                newItem->setText( EPSG_COLUMN, QString::fromUtf8(( char * )sqlite3_column_text( ppStmt, 2 ) ) );
                // display the qgis srs_id (field 1) in the third column of the list view
                newItem->setText( QGIS_CRS_ID_COLUMN, QString::fromUtf8(( char * )sqlite3_column_text( ppStmt, 1 ) ) );
            }
        }
        mProjList->setExpanded( true );
    }
    // close the sqlite3 statement
    sqlite3_finalize( ppStmt );
    // close the database
    sqlite3_close( db );

    mProjListDone = TRUE;
}
void QgsProjectionSelectionTreeWidget::loadUserCrsList( QSet<QString> *crsFilter )
{
  if ( mUserProjListDone )
    return;

  QgsDebugMsgLevel( "Fetching user projection list...", 4 );

  // convert our Coordinate Reference System filter into the SQL expression
  QString sqlFilter = ogcWmsCrsFilterAsSqlExpression( crsFilter );

  // User defined coordinate system node
  // Make in an italic font to distinguish them from real projections
  mUserProjList = new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr( "User Defined Coordinate Systems" ) ) );

  QFont fontTemp = mUserProjList->font( 0 );
  fontTemp.setItalic( true );
  fontTemp.setBold( true );
  mUserProjList->setFont( 0, fontTemp );
  mUserProjList->setIcon( 0, QgsApplication::getThemeIcon( QStringLiteral( "/user.svg" ) ) );

  //determine where the user proj database lives for this user. If none is found an empty
  //now only will be shown
  QString databaseFileName = QgsApplication::qgisUserDatabaseFilePath();
  // first we look for ~/.qgis/qgis.db
  // if it doesn't exist we copy it in from the global resources dir

  //return straight away if the user has not created any custom projections
  if ( !QFileInfo::exists( databaseFileName ) )
  {
    QgsDebugMsg( "Users qgis.db not found...skipping" );
    mUserProjListDone = true;
    return;
  }

  sqlite3      *database = nullptr;
  const char   *tail = nullptr;
  sqlite3_stmt *stmt = nullptr;
  //check the db is available
  int result = sqlite3_open_v2( databaseFileName.toUtf8().constData(), &database, SQLITE_OPEN_READONLY, nullptr );
  if ( result )
  {
    // XXX This will likely never happen since on open, sqlite creates the
    //     database if it does not exist. But we checked earlier for its existence
    //     and aborted in that case. This is because we may be running from read only
    //     media such as live cd and don't want to force trying to create a db.
    showDBMissingWarning( databaseFileName );
    return;
  }

  // Set up the query to retrieve the projection information needed to populate the list
  QString sql = QStringLiteral( "select description, srs_id from vw_srs where %1" ).arg( sqlFilter );

  result = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail );
  // XXX Need to free memory from the error msg if one is set
  if ( result == SQLITE_OK )
  {
    QTreeWidgetItem *newItem = nullptr;
    while ( sqlite3_step( stmt ) == SQLITE_ROW )
    {
      newItem = new QTreeWidgetItem( mUserProjList, QStringList( QString::fromUtf8( ( char * )sqlite3_column_text( stmt, 0 ) ) ) );
      // EpsgCrsId for user projections is not always defined in some dbases.
      // It's also not written from customprojections dialog.
      // display the epsg (field 2) in the second column of the list view
      // newItem->setText( EPSG_COLUMN, QString::fromUtf8(( char * )sqlite3_column_text( stmt, 2 ) ) );
      // display the qgis srs_id (field 1) in the third column of the list view
      newItem->setText( QgisCrsIdColumn, QString::fromUtf8( ( char * )sqlite3_column_text( stmt, 1 ) ) );
      newItem->setText( AuthidColumn, QStringLiteral( "USER:%1" ).arg( QString::fromUtf8( ( char * )sqlite3_column_text( stmt, 1 ) ).toInt() ) );
    }
  }
  // close the sqlite3 statement
  sqlite3_finalize( stmt );
  sqlite3_close( database );

  mUserProjListDone = true;
}
void QgsProjectionSelector::loadUserCrsList( QSet<QString> * crsFilter )
{
    QgsDebugMsg( "Fetching user projection list..." );

    // convert our Coordinate Reference System filter into the SQL expression
    QString sqlFilter = ogcWmsCrsFilterAsSqlExpression( crsFilter );

    // User defined coordinate system node
    // Make in an italic font to distinguish them from real projections
    mUserProjList = new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr( "User Defined Coordinate Systems" ) ) );

    QFont fontTemp = mUserProjList->font( 0 );
    fontTemp.setItalic( TRUE );
    fontTemp.setBold( TRUE );
    mUserProjList->setFont( 0, fontTemp );
    mUserProjList->setIcon( 0, QIcon( QgsApplication::activeThemePath() + "user.png" ) );

    //determine where the user proj database lives for this user. If none is found an empty
    //now only will be shown
    QString myDatabaseFileName = QgsApplication::qgisUserDbFilePath();
    // first we look for ~/.qgis/qgis.db
    // if it doesnt exist we copy it in from the global resources dir
    QFileInfo myFileInfo;
    myFileInfo.setFile( myDatabaseFileName );
    //return straight away if the user has not created any custom projections
    if ( !myFileInfo.exists( ) )
    {
        QgsDebugMsg( "Users qgis.db not found...skipping" );

        mUserProjListDone = TRUE;
        return;
    }

    sqlite3      *myDatabase;
    const char   *myTail;
    sqlite3_stmt *myPreparedStatement;
    int           myResult;
    //check the db is available
    myResult = sqlite3_open( QString( myDatabaseFileName ).toUtf8().data(), &myDatabase );
    if ( myResult )
    {
        // XXX This will likely never happen since on open, sqlite creates the
        //     database if it does not exist. But we checked earlier for its existance
        //     and aborted in that case. This is because we may be runnig from read only
        //     media such as live cd and dont want to force trying to create a db.
        showDBMissingWarning( myDatabaseFileName );
        return;
    }

    // Set up the query to retrieve the projection information needed to populate the list
    QString mySql = "select description, srs_id from vw_srs ";
    mySql += "where ";
    mySql += sqlFilter;

    myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.length(), &myPreparedStatement, &myTail );
    // XXX Need to free memory from the error msg if one is set
    if ( myResult == SQLITE_OK )
    {
        QTreeWidgetItem *newItem;
        while ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
        {
            newItem = new QTreeWidgetItem( mUserProjList, QStringList( QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 0 ) ) ) );
            // EpsgCrsId for user projections is not always defined in some dbases.
            // It's also not written from customprojections dialog.
            // display the epsg (field 2) in the second column of the list view
            // newItem->setText( EPSG_COLUMN, QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 2 ) ) );
            // display the qgis srs_id (field 1) in the third column of the list view
            newItem->setText( QGIS_CRS_ID_COLUMN, QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 1 ) ) );
        }
    }
    // close the sqlite3 statement
    sqlite3_finalize( myPreparedStatement );
    sqlite3_close( myDatabase );

    mUserProjListDone = TRUE;
}