25 #include <QFileOpenEvent>
26 #include <QMessageBox>
34 #include <netinet/in.h>
39 #include "qgsconfig.h"
46 QObject *
ABISYM( QgsApplication::mFileOpenEventReceiver );
47 QStringList
ABISYM( QgsApplication::mFileOpenEventList );
48 QString
ABISYM( QgsApplication::mPrefixPath );
49 QString
ABISYM( QgsApplication::mPluginPath );
50 QString
ABISYM( QgsApplication::mPkgDataPath );
51 QString
ABISYM( QgsApplication::mLibraryPath );
52 QString
ABISYM( QgsApplication::mLibexecPath );
53 QString
ABISYM( QgsApplication::mThemeName );
54 QStringList
ABISYM( QgsApplication::mDefaultSvgPaths );
55 QMap<QString, QString>
ABISYM( QgsApplication::mSystemEnvVars );
56 QString
ABISYM( QgsApplication::mConfigPath );
57 bool ABISYM( QgsApplication::mRunningFromBuildDir ) =
false;
58 QString
ABISYM( QgsApplication::mBuildSourcePath );
60 QString
ABISYM( QgsApplication::mCfgIntDir );
62 QString
ABISYM( QgsApplication::mBuildOutputPath );
63 QStringList
ABISYM( QgsApplication::mGdalSkipList );
79 : QApplication( argc, argv, GUIenabled )
81 init( customConfigPath );
86 if ( customConfigPath.isEmpty() )
91 qRegisterMetaType<QgsGeometry::Error>(
"QgsGeometry::Error" );
93 QString
prefixPath( getenv(
"QGIS_PREFIX_PATH" ) ? getenv(
"QGIS_PREFIX_PATH" ) : applicationDirPath() );
99 foreach ( QString path, QStringList() <<
"" <<
"/.." <<
"/bin" <<
"/../../.." )
101 f.setFileName( prefixPath + path +
"/qgisbuildpath.txt" );
105 if ( f.exists() && f.open( QIODevice::ReadOnly ) )
107 ABISYM( mRunningFromBuildDir ) =
true;
108 ABISYM( mBuildSourcePath ) = f.readLine().trimmed();
109 ABISYM( mBuildOutputPath ) = f.readLine().trimmed();
110 qDebug(
"Running from build directory!" );
111 qDebug(
"- source directory: %s",
ABISYM( mBuildSourcePath ).toUtf8().data() );
112 qDebug(
"- output directory of the build: %s",
ABISYM( mBuildOutputPath ).toUtf8().data() );
114 ABISYM( mCfgIntDir ) = prefixPath.split(
"/", QString::SkipEmptyParts ).last();
115 qDebug(
"- cfg: %s",
ABISYM( mCfgIntDir ).toUtf8().data() );
119 if (
ABISYM( mRunningFromBuildDir ) )
122 ABISYM( mPrefixPath ) = QString();
123 #if defined(_MSC_VER) && !defined(USING_NMAKE)
129 ABISYM( mLibraryPath ) =
ABISYM( mBuildOutputPath ) +
"/" + QGIS_LIB_SUBDIR +
"/";
130 #if defined(_MSC_VER) && !defined(USING_NMAKE)
131 ABISYM( mLibexecPath ) =
ABISYM( mBuildOutputPath ) +
"/" + QGIS_LIBEXEC_SUBDIR +
"/" +
ABISYM( mCfgIntDir ) +
"/";
133 ABISYM( mLibexecPath ) =
ABISYM( mBuildOutputPath ) +
"/" + QGIS_LIBEXEC_SUBDIR +
"/";
138 char *prefixPath = getenv(
"QGIS_PREFIX_PATH" );
141 #if defined(Q_WS_MACX) || defined(Q_WS_WIN32) || defined(WIN32)
143 #elif defined(ANDROID)
145 QDir myDir( QDir::homePath() );
147 QString myPrefix = myDir.absolutePath();
150 QDir myDir( applicationDirPath() );
152 QString myPrefix = myDir.absolutePath();
162 if ( !customConfigPath.isEmpty() )
164 ABISYM( mConfigPath ) = customConfigPath +
"/";
170 QMap<QString, QString> systemEnvVarMap;
171 foreach (
const QString &varStr, QProcess::systemEnvironment() )
173 int pos = varStr.indexOf( QLatin1Char(
'=' ) );
176 QString varStrName = varStr.left( pos );
177 QString varStrValue = varStr.mid( pos + 1 );
178 systemEnvVarMap.insert( varStrName, varStrValue );
180 ABISYM( mSystemEnvVars ) = systemEnvVarMap;
191 if ( event->type() == QEvent::FileOpen )
194 if (
ABISYM( mFileOpenEventReceiver ) )
197 done =
notify(
ABISYM( mFileOpenEventReceiver ), event );
204 ABISYM( mFileOpenEventList ).append( static_cast<QFileOpenEvent *>( event )->
file() );
220 if ( thread() == receiver->thread() )
221 emit
preNotify( receiver, event, &done );
234 QMessageBox::critical( activeWindow(),
tr(
"Exception" ), e.
what() );
236 catch ( std::exception & e )
238 QMessageBox::critical( activeWindow(),
tr(
"Exception" ), e.what() );
242 QMessageBox::critical( activeWindow(),
tr(
"Exception" ),
tr(
"unknown exception" ) );
251 ABISYM( mFileOpenEventReceiver ) = receiver;
253 if (
ABISYM( mFileOpenEventList ).count() > 0 )
255 QStringListIterator i(
ABISYM( mFileOpenEventList ) );
256 while ( i.hasNext() )
258 QFileOpenEvent foe( i.next() );
259 QgsApplication::sendEvent(
ABISYM( mFileOpenEventReceiver ), &foe );
261 ABISYM( mFileOpenEventList ).clear();
267 ABISYM( mPrefixPath ) = thePrefixPath;
268 #if defined(_MSC_VER)
269 if (
ABISYM( mPrefixPath ).endsWith(
"/bin" ) )
271 ABISYM( mPrefixPath ).chop( 4 );
274 if ( useDefaultPaths && !
ABISYM( mRunningFromBuildDir ) )
279 ABISYM( mLibraryPath ) =
ABISYM( mPrefixPath ) +
"/" + QGIS_LIB_SUBDIR +
"/";
280 ABISYM( mLibexecPath ) =
ABISYM( mPrefixPath ) +
"/" + QGIS_LIBEXEC_SUBDIR +
"/";
285 ABISYM( mPluginPath ) = thePluginPath;
290 ABISYM( mPkgDataPath ) = thePkgDataPath;
291 QString mySvgPath = thePkgDataPath + (
ABISYM( mRunningFromBuildDir ) ?
"/images/svg/" :
"/svg/" );
293 if ( !
ABISYM( mDefaultSvgPaths ).contains( mySvgPath ) )
294 ABISYM( mDefaultSvgPaths ) << mySvgPath;
299 ABISYM( mDefaultSvgPaths ) = pathList;
304 if (
ABISYM( mRunningFromBuildDir ) )
306 qWarning(
"!!! prefix path was requested, but it is not valid - we do not run from installed path !!!" );
309 return ABISYM( mPrefixPath );
313 return ABISYM( mPluginPath );
317 return ABISYM( mPkgDataPath );
321 return ":/images/themes/default/";
325 return ":/images/themes/" +
themeName() +
"/";
333 if ( QFile::exists( path + iconFile ) )
334 return path + iconFile;
342 QString myPreferredPath =
activeThemePath() + QDir::separator() + theName;
344 if ( QFile::exists( myPreferredPath ) )
346 return QIcon( myPreferredPath );
348 else if ( QFile::exists( myDefaultPath ) )
352 return QIcon( myDefaultPath );
363 QString myPreferredPath =
activeThemePath() + QDir::separator() + theName;
365 if ( QFile::exists( myPreferredPath ) )
367 return QPixmap( myPreferredPath );
373 return QPixmap( myDefaultPath );
382 QString myPath =
":/images/themes/" + theThemeName +
"/";
384 if ( QFile::exists( myPath ) )
386 ABISYM( mThemeName ) = theThemeName;
390 ABISYM( mThemeName ) =
"default";
398 return ABISYM( mThemeName );
405 return ABISYM( mPkgDataPath ) + QString(
"/doc/AUTHORS" );
412 return ABISYM( mPkgDataPath ) + QString(
"/doc/CONTRIBUTORS" );
419 return ABISYM( mPkgDataPath ) + QString(
"/doc/SPONSORS" );
427 return ABISYM( mPkgDataPath ) + QString(
"/doc/DONORS" );
436 return ABISYM( mPkgDataPath ) + QString(
"/doc/TRANSLATORS" );
444 return ABISYM( mPkgDataPath ) + QString(
"/doc/LICENCE" );
454 helpAppPath = applicationDirPath() +
"/bin/qgis_help.app/Contents/MacOS";
458 helpAppPath +=
"/qgis_help";
460 helpAppPath +=
".exe";
469 if (
ABISYM( mRunningFromBuildDir ) )
470 return ABISYM( mBuildOutputPath ) + QString(
"/i18n" );
472 return ABISYM( mPkgDataPath ) + QString(
"/i18n/" );
480 return ABISYM( mPkgDataPath ) + QString(
"/resources/qgis.db" );
488 return ABISYM( mConfigPath );
504 return QString(
":/images/splash/" );
512 return ABISYM( mPkgDataPath ) + QString(
"/images/icons/" );
519 if (
ABISYM( mRunningFromBuildDir ) )
521 QString tempCopy = QDir::tempPath() +
"/srs.db";
523 if ( !QFile( tempCopy ).exists() )
525 QFile f(
ABISYM( mPkgDataPath ) +
"/resources/srs.db" );
526 if ( !f.copy( tempCopy ) )
528 qFatal(
"Could not create temporary copy" );
536 return ABISYM( mPkgDataPath ) + QString(
"/resources/srs.db" );
548 QStringList myPathList;
549 QString myPaths = settings.value(
"svg/searchPathsForSVG",
"" ).toString();
550 if ( !myPaths.isEmpty() )
552 myPathList = myPaths.split(
"|" );
555 myPathList <<
ABISYM( mDefaultSvgPaths );
566 return ABISYM( mPkgDataPath ) + QString(
"/resources/symbology-ng-style.db" );
571 return ABISYM( mLibraryPath );
576 return ABISYM( mLibexecPath );
581 return ( htonl( 1 ) == 1 ) ?
XDR :
NDR ;
600 QString myEnvironmentVar( getenv(
"QGIS_PREFIX_PATH" ) );
601 QString myState =
tr(
"Application state:\n"
602 "QGIS_PREFIX_PATH env var:\t\t%1\n"
604 "Plugin Path:\t\t%3\n"
605 "Package Data Path:\t%4\n"
606 "Active Theme Name:\t%5\n"
607 "Active Theme Path:\t%6\n"
608 "Default Theme Path:\t%7\n"
609 "SVG Search Paths:\t%8\n"
610 "User DB Path:\t%9\n" )
611 .arg( myEnvironmentVar )
618 .arg(
svgPaths().join(
tr(
"\n\t\t",
"match indentation of application state" ) ) )
630 QColor myColor1( Qt::lightGray );
631 QColor myColor2 = myColor1;
632 myColor2 = myColor2.lighter( 110 );
634 myStyle =
"p.glossy{ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
635 " stop: 0 " + myColor1.name() +
","
636 " stop: 0.1 " + myColor2.name() +
","
637 " stop: 0.5 " + myColor1.name() +
","
638 " stop: 0.9 " + myColor2.name() +
","
639 " stop: 1 " + myColor1.name() +
");"
641 " padding-left: 4px;"
642 " padding-top: 20px;"
643 " padding-bottom: 8px;"
644 " border: 1px solid #6c6c6c;"
646 "p.subheaderglossy{ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
647 " stop: 0 " + myColor1.name() +
","
648 " stop: 0.1 " + myColor2.name() +
","
649 " stop: 0.5 " + myColor1.name() +
","
650 " stop: 0.9 " + myColor2.name() +
","
651 " stop: 1 " + myColor1.name() +
");"
652 " font-weight: bold;"
653 " font-size: medium;"
654 " line-height: 1.1em;"
657 " padding-left: 4px;"
658 " padding-right: 4px;"
659 " padding-top: 20px;"
660 " padding-bottom: 8px;"
661 " border: 1px solid #6c6c6c;"
663 "th.glossy{ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
664 " stop: 0 " + myColor1.name() +
","
665 " stop: 0.1 " + myColor2.name() +
","
666 " stop: 0.5 " + myColor1.name() +
","
667 " stop: 0.9 " + myColor2.name() +
","
668 " stop: 1 " + myColor1.name() +
");"
670 " border: 1px solid #6c6c6c;"
672 ".overview{ font: 1.82em; font-weight: bold;}"
673 "body{ background: white;"
675 " font-family: arial,sans-serif;"
677 "h1{ background-color: #F6F6F6;"
679 " font-size: x-large; "
680 " font-weight: normal;"
681 " font-family: luxi serif, georgia, times new roman, times, serif;"
683 " padding: 0.75em 0 0;"
687 "h2{ background-color: #F6F6F6;"
689 " font-size: medium; "
690 " font-weight: normal;"
691 " font-family: luxi serif, georgia, times new roman, times, serif;"
693 " padding: 0.75em 0 0;"
695 " line-height: 1.1em;"
697 "h3{ background-color: #F6F6F6;"
699 " font-family: luxi serif, georgia, times new roman, times, serif;"
700 " font-weight: bold;"
702 " text-align: right;"
703 " border-bottom: 5px solid #DCEB5C;"
705 "h4{ background-color: #F6F6F6;"
707 " font-family: luxi serif, georgia, times new roman, times, serif;"
708 " font-weight: bold;"
709 " font-size: medium;"
710 " text-align: right;"
712 "h5{ background-color: #F6F6F6;"
714 " font-family: luxi serif, georgia, times new roman, times, serif;"
715 " font-weight: bold;"
717 " text-align: right;"
720 " font-family: arial,sans-serif;"
723 "label{ background-color: #FFFFCC;"
724 " border: 1px solid black;"
726 " padding: 0px 3px; "
734 if ( 0 >= OGRGetDriverCount() )
742 #if defined( Q_OS_WIN )
743 const Qt::CaseSensitivity cs = Qt::CaseInsensitive;
745 aPath.replace(
"\\",
"/" );
746 if ( aPath.startsWith(
"//" ) )
749 aPath =
"\\\\" + aPath.mid( 2 );
752 targetPath.replace(
"\\",
"/" );
753 if ( targetPath.startsWith(
"//" ) )
756 targetPath =
"\\\\" + targetPath.mid( 2 );
759 const Qt::CaseSensitivity cs = Qt::CaseSensitive;
762 QStringList targetElems = targetPath.split(
"/", QString::SkipEmptyParts );
763 QStringList aPathElems = aPath.split(
"/", QString::SkipEmptyParts );
765 targetElems.removeAll(
"." );
766 aPathElems.removeAll(
"." );
770 while ( aPathElems.size() > 0 &&
771 targetElems.size() > 0 &&
772 aPathElems[0].compare( targetElems[0], cs ) == 0 )
774 aPathElems.removeFirst();
775 targetElems.removeFirst();
785 if ( targetElems.size() > 0 )
788 for (
int i = 0; i < targetElems.size(); i++ )
790 aPathElems.insert( 0,
".." );
797 aPathElems.insert( 0,
"." );
800 return aPathElems.join(
"/" );
806 if ( !rpath.startsWith(
"./" ) && !rpath.startsWith(
"../" ) )
811 #if defined(Q_OS_WIN)
812 rpath.replace(
"\\",
"/" );
813 targetPath.replace(
"\\",
"/" );
815 bool uncPath = targetPath.startsWith(
"//" );
818 QStringList srcElems = rpath.split(
"/", QString::SkipEmptyParts );
819 QStringList targetElems = targetPath.split(
"/", QString::SkipEmptyParts );
821 #if defined(Q_OS_WIN)
824 targetElems.insert( 0,
"" );
825 targetElems.insert( 0,
"" );
830 targetElems << srcElems;
831 targetElems.removeAll(
"." );
835 while (( pos = targetElems.indexOf(
".." ) ) > 0 )
838 targetElems.removeAt( pos - 1 );
839 targetElems.removeAt( pos - 1 );
842 #if !defined(Q_OS_WIN)
844 targetElems.prepend(
"" );
847 return targetElems.join(
"/" );
852 if (
ABISYM( mGdalSkipList ).contains( theDriver ) || theDriver.isEmpty() )
856 ABISYM( mGdalSkipList ) << theDriver;
862 if ( !
ABISYM( mGdalSkipList ).contains( theDriver ) )
866 int myPos =
ABISYM( mGdalSkipList ).indexOf( theDriver );
869 ABISYM( mGdalSkipList ).removeAt( myPos );
876 ABISYM( mGdalSkipList ).removeDuplicates();
877 QString myDriverList =
ABISYM( mGdalSkipList ).join(
" " );
880 CPLSetConfigOption(
"GDAL_SKIP", myDriverList.toUtf8() );
890 QDir myDir( myPamPath );
891 if ( !myDir.exists() )
893 myDir.mkpath( myPamPath );
896 #if defined(Q_WS_WIN32) || defined(WIN32)
897 CPLSetConfigOption(
"GDAL_PAM_PROXY_DIR", myPamPath.toUtf8() );
901 int myChangeFlag = 0;
902 setenv(
"GDAL_PAM_PROXY_DIR", myPamPath.toUtf8(), myChangeFlag );
909 if ( !qgisPrivateDbFile.exists() )
913 QFile masterFile( qgisMasterDbFileName );
919 bool isDbFileCopied = masterFile.copy( qgisPrivateDbFile.fileName() );
921 if ( !isDbFileCopied )
925 *errorMessage =
tr(
"[ERROR] Can not make qgis.db private copy" );
938 *errorMessage =
tr(
"Could not open qgis.db" );
944 int res = sqlite3_exec( db,
"SELECT epsg FROM tbl_srs LIMIT 0", 0, 0, &errmsg );
945 if ( res == SQLITE_OK )
948 if ( sqlite3_exec( db,
949 "ALTER TABLE tbl_srs RENAME TO tbl_srs_bak;"
950 "CREATE TABLE tbl_srs ("
951 "srs_id INTEGER PRIMARY KEY,"
952 "description text NOT NULL,"
953 "projection_acronym text NOT NULL,"
954 "ellipsoid_acronym NOT NULL,"
955 "parameters text NOT NULL,"
959 "is_geo integer NOT NULL,"
960 "deprecated boolean);"
961 "CREATE INDEX idx_srsauthid on tbl_srs(auth_name,auth_id);"
962 "INSERT INTO tbl_srs(srs_id,description,projection_acronym,ellipsoid_acronym,parameters,srid,auth_name,auth_id,is_geo,deprecated) SELECT srs_id,description,projection_acronym,ellipsoid_acronym,parameters,srid,'','',is_geo,0 FROM tbl_srs_bak;"
963 "DROP TABLE tbl_srs_bak", 0, 0, &errmsg ) != SQLITE_OK
968 *errorMessage =
tr(
"Migration of private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
970 sqlite3_free( errmsg );
977 sqlite3_free( errmsg );
980 if ( sqlite3_exec( db,
"DROP VIEW vw_srs", 0, 0, &errmsg ) != SQLITE_OK )
982 QgsDebugMsg( QString(
"vw_srs didn't exists in private qgis.db: %1" ).arg( errmsg ) );
985 if ( sqlite3_exec( db,
986 "CREATE VIEW vw_srs AS"
988 " a.description AS description"
989 ",a.srs_id AS srs_id"
990 ",a.is_geo AS is_geo"
991 ",coalesce(b.name,a.projection_acronym) AS name"
992 ",a.parameters AS parameters"
993 ",a.auth_name AS auth_name"
994 ",a.auth_id AS auth_id"
995 ",a.deprecated AS deprecated"
997 " LEFT OUTER JOIN tbl_projection b ON a.projection_acronym=b.acronym"
998 " ORDER BY coalesce(b.name,a.projection_acronym),a.description", 0, 0, &errmsg ) != SQLITE_OK
1003 *errorMessage =
tr(
"Update of view in private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
1005 sqlite3_free( errmsg );
1006 sqlite3_close( db );
1010 sqlite3_close( db );