src/corelib/global/qlibraryinfo.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.
00004 **
00005 ** This file is part of the QtCore module of the Qt Toolkit.
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://www.trolltech.com/products/qt/opensource.html
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://www.trolltech.com/products/qt/licensing.html or contact the
00017 ** sales department at sales@trolltech.com.
00018 **
00019 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00020 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 **
00022 ****************************************************************************/
00023 
00024 #include "qdir.h"
00025 #include "qfile.h"
00026 #include "qconfig.h"
00027 #include "qsettings.h"
00028 #include "qlibraryinfo.h"
00029 #include "qpointer.h"
00030 #ifdef QT_BUILD_QMAKE
00031 extern QString qmake_libraryInfoFile();
00032 #else
00033 # include "qcoreapplication.h"
00034 #endif
00035 #ifdef Q_OS_MAC
00036 #  include "private/qcore_mac_p.h"
00037 #endif
00038 
00039 #include "qconfig.cpp"
00040 
00041 #ifndef QT_NO_SETTINGS
00042 
00043 
00044 
00045 struct QLibrarySettings
00046 {
00047     QLibrarySettings();
00048     ~QLibrarySettings() { delete static_cast<QSettings *>(settings); }
00049     QSettings *settings;
00050 };
00051 
00052 class QLibraryInfoPrivate
00053 {
00054 public:
00055     static QSettings *findConfiguration();
00056     static void cleanup()
00057     {
00058         QLibrarySettings *ls = qt_library_settings();
00059         if (ls) {
00060             delete static_cast<QSettings *>(ls->settings);
00061             ls->settings = 0;
00062         }
00063     }
00064     static QSettings *configuration()
00065     {
00066 #ifdef QT_NO_THREAD
00067         // This recursion guard should be a temporary solution; the recursive
00068         // dependency should be found and removed.
00069         static bool initializing = false;
00070         if (initializing)
00071             return 0;
00072         initializing = true;
00073 #endif
00074         QLibrarySettings *ls = qt_library_settings();
00075 #ifdef QT_NO_THREAD
00076         initializing = false;
00077 #endif
00078         return ls ? static_cast<QSettings *>(qt_library_settings()->settings) : (QSettings*)0;
00079     }
00080 
00081     Q_GLOBAL_STATIC(QLibrarySettings, qt_library_settings)
00082 };
00083 
00084 QLibrarySettings::QLibrarySettings()
00085 {
00086     settings = QLibraryInfoPrivate::findConfiguration();
00087 #ifndef QT_BUILD_QMAKE
00088     qAddPostRoutine(QLibraryInfoPrivate::cleanup);
00089 #endif
00090 }
00091 
00092 QSettings *QLibraryInfoPrivate::findConfiguration()
00093 {
00094     QString qtconfig = QLatin1String(":/qt/etc/qt.conf");
00095 #ifdef QT_BUILD_QMAKE
00096     if(!QFile::exists(qtconfig))
00097         qtconfig = qmake_libraryInfoFile();
00098 #else
00099     if (!QFile::exists(qtconfig) && QCoreApplication::instance()) {
00100 #ifdef Q_OS_MAC
00101   CFBundleRef bundleRef = CFBundleGetMainBundle();
00102         if (bundleRef) {
00103       QCFType<CFURLRef> urlRef = CFBundleCopyResourceURL(bundleRef,
00104                      QCFString(QLatin1String("qt.conf")),
00105                      0,
00106                      0);
00107       if (urlRef) {
00108           QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle);
00109     qtconfig = QDir::cleanPath(path);
00110       }
00111   }
00112   if (qtconfig.isEmpty())
00113 #endif
00114             {
00115                 QDir pwd(QCoreApplication::applicationDirPath());
00116                 qtconfig = pwd.filePath(QLatin1String("qt.conf"));
00117       }
00118     }
00119 #endif
00120     if (QFile::exists(qtconfig))
00121         return new QSettings(qtconfig, QSettings::IniFormat);
00122     return 0;     //no luck
00123 }
00124 
00162 QLibraryInfo::QLibraryInfo()
00163 { }
00164 
00171 QString
00172 QLibraryInfo::licensee()
00173 {
00174     const char *str = QT_CONFIGURE_LICENSEE;
00175     return QString::fromLocal8Bit(str);
00176 }
00177 
00184 QString
00185 QLibraryInfo::licensedProducts()
00186 {
00187     const char *str = QT_CONFIGURE_LICENSED_PRODUCTS;
00188     return QString::fromLatin1(str);
00189 }
00190 
00200 QString
00201 QLibraryInfo::buildKey()
00202 {
00203     return QString::fromLatin1(QT_BUILD_KEY);
00204 }
00205 
00211 QString
00212 QLibraryInfo::location(LibraryLocation loc)
00213 {
00214     QString ret;
00215     if(!QLibraryInfoPrivate::configuration()) {
00216         const char *path = 0;
00217         switch (loc) {
00218 #ifdef QT_CONFIGURE_PREFIX_PATH
00219         case PrefixPath:
00220             path = QT_CONFIGURE_PREFIX_PATH;
00221             break;
00222 #endif
00223 #ifdef QT_CONFIGURE_DOCUMENTATION_PATH
00224         case DocumentationPath:
00225             path = QT_CONFIGURE_DOCUMENTATION_PATH;
00226             break;
00227 #endif
00228 #ifdef QT_CONFIGURE_HEADERS_PATH
00229         case HeadersPath:
00230             path = QT_CONFIGURE_HEADERS_PATH;
00231             break;
00232 #endif
00233 #ifdef QT_CONFIGURE_LIBRARIES_PATH
00234         case LibrariesPath:
00235             path = QT_CONFIGURE_LIBRARIES_PATH;
00236             break;
00237 #endif
00238 #ifdef QT_CONFIGURE_BINARIES_PATH
00239         case BinariesPath:
00240             path = QT_CONFIGURE_BINARIES_PATH;
00241             break;
00242 #endif
00243 #ifdef QT_CONFIGURE_PLUGINS_PATH
00244         case PluginsPath:
00245             path = QT_CONFIGURE_PLUGINS_PATH;
00246             break;
00247 #endif
00248 #ifdef QT_CONFIGURE_DATA_PATH
00249         case DataPath:
00250             path = QT_CONFIGURE_DATA_PATH;
00251             break;
00252 #endif
00253 #ifdef QT_CONFIGURE_TRANSLATIONS_PATH
00254         case TranslationsPath:
00255             path = QT_CONFIGURE_TRANSLATIONS_PATH;
00256             break;
00257 #endif
00258 #ifdef QT_CONFIGURE_SETTINGS_PATH
00259         case SettingsPath:
00260             path = QT_CONFIGURE_SETTINGS_PATH;
00261             break;
00262 #endif
00263 #ifdef QT_CONFIGURE_EXAMPLES_PATH
00264         case ExamplesPath:
00265             path = QT_CONFIGURE_EXAMPLES_PATH;
00266             break;
00267 #endif
00268 #ifdef QT_CONFIGURE_DEMOS_PATH
00269         case DemosPath:
00270             path = QT_CONFIGURE_DEMOS_PATH;
00271             break;
00272 #endif
00273         default:
00274             break;
00275         }
00276 
00277         if (path)
00278             ret = QString::fromLocal8Bit(path);
00279     } else {
00280         QString key;
00281         QString defaultValue;
00282         switch(loc) {
00283         case PrefixPath:
00284             key = QLatin1String("Prefix");
00285             break;
00286         case DocumentationPath:
00287             key = QLatin1String("Documentation");
00288             defaultValue = QLatin1String("doc");
00289             break;
00290         case HeadersPath:
00291             key = QLatin1String("Headers");
00292             defaultValue = QLatin1String("include");
00293             break;
00294         case LibrariesPath:
00295             key = QLatin1String("Libraries");
00296             defaultValue = QLatin1String("lib");
00297             break;
00298         case BinariesPath:
00299             key = QLatin1String("Binaries");
00300             defaultValue = QLatin1String("bin");
00301             break;
00302         case PluginsPath:
00303             key = QLatin1String("Plugins");
00304             defaultValue = QLatin1String("plugins");
00305             break;
00306         case DataPath:
00307             key = QLatin1String("Data");
00308             break;
00309         case TranslationsPath:
00310             key = QLatin1String("Translations");
00311             defaultValue = QLatin1String("translations");
00312             break;
00313         case SettingsPath:
00314             key = QLatin1String("Settings");
00315             break;
00316         case ExamplesPath:
00317             key = QLatin1String("Examples");
00318             break;
00319         case DemosPath:
00320             key = QLatin1String("Demos");
00321             break;
00322         default:
00323             break;
00324         }
00325 
00326         if(!key.isNull()) {
00327             QSettings *config = QLibraryInfoPrivate::configuration();
00328             config->beginGroup(QLatin1String("Paths"));
00329 
00330             QString subKey;
00331             {
00332                 /*
00333                   find the child group whose version number is closest
00334                   to the library version.  for example and we have the
00335                   following groups:
00336 
00337                   Paths
00338                   Paths/4.0
00339                   Paths/4.1.2
00340                   Paths/4.2.5
00341                   Paths/5
00342 
00343                   if QT_VERSION is 4.0.1, then we use 'Paths/4.0'
00344                   if QT_VERSION is 4.1.5, then we use 'Paths/4.1.2'
00345                   if QT_VERSION is 4.6.3, then we use 'Paths/4.2.5'
00346                   if QT_VERSION is 6.0.2, then we use 'Paths/5'
00347 
00348                   note: any of the trailing version numbers may be
00349                   omitted (in which case, they default to zero),
00350                   i.e. 4 == 4.0.0, 4.1 == 4.1.0, and so on
00351                 */
00352                 enum {
00353                     QT_MAJOR = ((QT_VERSION >> 16) & 0xFF),
00354                     QT_MINOR = ((QT_VERSION >> 8) & 0xFF),
00355                     QT_PATCH = (QT_VERSION & 0xFF)
00356                 };
00357                 int maj = 0, min = 0, pat = 0;
00358                 QStringList children = config->childGroups();
00359                 for(int child = 0; child < children.size(); ++child) {
00360                     QString cver = children.at(child);
00361                     QStringList cver_list = cver.split(QLatin1Char('.'));
00362                     if(cver_list.size() > 0 && cver_list.size() < 4) {
00363                         bool ok;
00364                         int cmaj = -1, cmin = -1, cpat = -1;
00365                         cmaj = cver_list[0].toInt(&ok);
00366                         if(!ok || cmaj < 0)
00367                             continue;
00368                         if(cver_list.size() >= 2) {
00369                             cmin = cver_list[1].toInt(&ok);
00370                             if(!ok)
00371                                 continue;
00372                             if(cmin < 0)
00373                                 cmin = -1;
00374                         }
00375                         if(cver_list.size() >= 3) {
00376                             cpat = cver_list[2].toInt(&ok);
00377                             if(!ok)
00378                                 continue;
00379                             if(cpat < 0)
00380                                 cpat = -1;
00381                         }
00382                         if((cmaj >= maj && cmaj <= QT_MAJOR) &&
00383                            (cmin == -1 || (cmin >= min && cmin <= QT_MINOR)) &&
00384                            (cpat == -1 || (cpat >= pat && cpat <= QT_PATCH)) &&
00385                            config->contains(cver + QLatin1Char('/') + key)) {
00386                             subKey = cver + QLatin1Char('/');
00387                             maj = cmaj;
00388                             min = cmin;
00389                             pat = cpat;
00390                         }
00391                     }
00392                 }
00393             }
00394             ret = config->value(subKey + key, defaultValue).toString();
00395             // expand environment variables in the form $(ENVVAR)
00396             int rep;
00397             QRegExp reg_var(QLatin1String("\\$\\(.*\\)"));
00398             reg_var.setMinimal(true);
00399             while((rep = reg_var.indexIn(ret)) != -1) {
00400                 ret.replace(rep, reg_var.matchedLength(),
00401                             QString::fromLocal8Bit(qgetenv(ret.mid(rep + 2,
00402                                 reg_var.matchedLength() - 3).toLatin1().constData()).constData()));
00403             }
00404             config->endGroup();
00405         }
00406     }
00407 
00408     if (QDir::isRelativePath(ret)) {
00409         if (loc == PrefixPath) {
00410             // we make the prefix path absolute to the executable's directory
00411 #ifdef QT_BUILD_QMAKE
00412             return QFileInfo(qmake_libraryInfoFile()).absolutePath();
00413 #else
00414             if (QCoreApplication::instance()) {
00415 #ifdef Q_OS_MAC
00416           CFBundleRef bundleRef = CFBundleGetMainBundle();
00417     if (bundleRef) {
00418         QCFType<CFURLRef> urlRef = CFBundleCopyBundleURL(bundleRef);
00419         if (urlRef) {
00420             QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle);
00421             return QDir::cleanPath(path + QLatin1String("/Contents"));
00422         }
00423     }
00424 #endif
00425                 return QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(ret);
00426             } else {
00427                 return QDir::current().absoluteFilePath(ret);
00428             }
00429 #endif
00430         } else {
00431             // we make any other path absolute to the prefix directory
00432             return QDir(location(PrefixPath)).absoluteFilePath(ret);
00433         }
00434     }
00435     return ret;
00436 }
00437 
00461 #endif // QT_NO_SETTINGS

Generated on Thu Mar 15 11:53:08 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1