00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "config.h"
00025 #include "profile.h"
00026 #include "docuparser.h"
00027
00028 #include <QApplication>
00029 #include <QDesktopWidget>
00030 #include <QLibraryInfo>
00031 #include <QFont>
00032 #include <QFontInfo>
00033 #include <QDir>
00034 #include <QFile>
00035 #include <QFileInfo>
00036 #include <QSettings>
00037 #include <QtXml>
00038 #include <QList>
00039
00040 static Config *static_configuration = 0;
00041
00042 inline QString getVersionString()
00043 {
00044 return QString::number( (QT_VERSION >> 16) & 0xff )
00045 + QLatin1String(".") + QString::number( (QT_VERSION >> 8) & 0xff );
00046 }
00047
00048 Config::Config()
00049 : profil( 0 ), hideSidebar( false ), rebuildDocs(true)
00050 {
00051 if( !static_configuration ) {
00052 static_configuration = this;
00053 } else {
00054 qWarning( "Multiple configurations not allowed!" );
00055 }
00056 }
00057
00058 Config *Config::loadConfig(const QString &profileFileName)
00059 {
00060 Config *config = new Config();
00061
00062 if (profileFileName.isEmpty()) {
00063 if (!config->defaultProfileExists()) {
00064 config->profil = Profile::createDefaultProfile();
00065 config->saveProfile(config->profil);
00066 } else {
00067 config->profil = new Profile();
00068 }
00069 config->loadDefaultProfile();
00070 config->load();
00071 return config;
00072 }
00073
00074 QFile file(profileFileName);
00075 if (!file.exists()) {
00076 qWarning( (QLatin1String("File does not exist: ") + profileFileName).toAscii().constData() );
00077 return 0;
00078 }
00079 DocuParser *parser = DocuParser::createParser( profileFileName );
00080 if (!parser) {
00081 qWarning( (QLatin1String("Failed to create parser for file: ") + profileFileName).toAscii().constData() );
00082 return 0;
00083 }
00084 if (parser->parserVersion() < DocuParser::Qt320) {
00085 qWarning( "File does not contain profile information" );
00086 return 0;
00087 }
00088 DocuParser320 *profileParser = static_cast<DocuParser320*>(parser);
00089 parser->parse(&file);
00090 config->profil = profileParser->profile();
00091 if (!config->profil) {
00092 qWarning( (QLatin1String("Config::loadConfig(), no profile in: ") + profileFileName).toAscii().constData() );
00093 return 0;
00094 }
00095 config->profil->setProfileType(Profile::UserProfile);
00096 config->profil->setDocuParser(profileParser);
00097 config->load();
00098 return config;
00099 }
00100
00101 Config *Config::configuration()
00102 {
00103 Q_ASSERT( static_configuration );
00104 return static_configuration;
00105 }
00106
00107 void Config::load()
00108 {
00109 const QString key = getVersionString() + QLatin1String("/");
00110
00111 const QString pKey = (profil->props[QLatin1String("name")] == QLatin1String("default"))
00112 ? QString::fromLatin1(QT_VERSION_STR)
00113 : getVersionString();
00114
00115 const QString profkey = pKey + QLatin1String("/Profile/") + profil->props[QLatin1String("name")] + QLatin1String("/");
00116
00117 QSettings settings;
00118
00119 home = settings.value( profkey + QLatin1String("Homepage"),
00120 QLibraryInfo::location(QLibraryInfo::DocumentationPath) + QLatin1String("/html/index.html") ).toString();
00121 src = settings.value( profkey + QLatin1String("Source") ).toStringList();
00122 sideBar = settings.value( key + QLatin1String("SideBarPage") ).toInt();
00123 if (qApp->type() != QApplication::Tty)
00124 winGeometry = settings.value(key + QLatin1String("windowGeometry")).toByteArray();
00125
00126 mainWinState = settings.value(key + QLatin1String("MainWindowState")).toByteArray();
00127 pointFntSize = settings.value(key + QLatin1String("FontSize"), qApp->font().pointSizeF()).toDouble();
00128 rebuildDocs = settings.value( key + QLatin1String("RebuildDocDB"), true ).toBool();
00129
00130 profileNames = settings.value( key + QLatin1String("Profile") ).toStringList();
00131 }
00132
00133 void Config::save()
00134 {
00135 saveSettings();
00136 saveProfile( profil );
00137 }
00138
00139 void Config::saveSettings()
00140 {
00141 const QString key = getVersionString() + QLatin1String("/");
00142
00143 const QString pKey = (profil->props[QLatin1String("name")] == QLatin1String("default"))
00144 ? QString::fromLatin1(QT_VERSION_STR)
00145 : getVersionString();
00146
00147 const QString profkey = pKey + QLatin1String("/Profile/") + profil->props[QLatin1String("name")] + QLatin1String("/");
00148
00149 QSettings settings;
00150
00151 settings.setValue( profkey + QLatin1String("Homepage"), homePage() );
00152 settings.setValue( profkey + QLatin1String("Source"), src );
00153 settings.setValue( key + QLatin1String("SideBarPage"), sideBarPage() );
00154 if (qApp->type() != QApplication::Tty)
00155 settings.setValue(key + QLatin1String("windowGeometry"), winGeometry);
00156
00157 settings.setValue( key + QLatin1String("MainWindowState"), mainWinState );
00158 settings.setValue( key + QLatin1String("FontSize"), pointFntSize);
00159 settings.setValue( key + QLatin1String("RebuildDocDB"), rebuildDocs );
00160 }
00161
00162 #ifdef ASSISTANT_DEBUG
00163 static void dumpmap( const QMap<QString,QString> &m, const QString &header )
00164 {
00165 qDebug( header );
00166 QMap<QString,QString>::ConstIterator it = m.begin();
00167 while (it != m.end()) {
00168 qDebug( " " + it.key() + ":\t\t" + *it );
00169 ++it;
00170 }
00171 }
00172 #endif
00173
00174 bool Config::defaultProfileExists()
00175 {
00176 QSettings settings;
00177 const QString profKey = QLatin1String(QT_VERSION_STR) + QLatin1String("/Profile/default/");
00178
00179 if (settings.contains(profKey + QLatin1String("DocFiles"))
00180 && settings.contains(profKey + QLatin1String("Titles"))
00181 && settings.contains(profKey + QLatin1String("ImageDirs"))) {
00182 QStringList dcfs = settings.value(profKey + QLatin1String("DocFiles") ).toStringList();
00183 foreach (QString file, dcfs) {
00184 if (file == Profile::storableFilePath(file))
00185 return true;
00186 }
00187 }
00188 return false;
00189 }
00190
00191 void Config::loadDefaultProfile()
00192 {
00193 QSettings settings;
00194 const QString profKey = QLatin1String(QT_VERSION_STR) + QLatin1String("/Profile/default/");
00195
00196 if (!defaultProfileExists())
00197 return;
00198
00199
00200 profil->icons.clear();
00201 profil->indexPages.clear();
00202 profil->imageDirs.clear();
00203 profil->docs.clear();
00204 profil->dcfTitles.clear();
00205
00206 QStringList titles = settings.value( profKey + QLatin1String("Titles") ).toStringList();
00207 QStringList iconLst = settings.value( profKey + QLatin1String("DocIcons") ).toStringList();
00208 QStringList indexLst = settings.value( profKey + QLatin1String("IndexPages") ).toStringList();
00209 QStringList imgDirLst = settings.value( profKey + QLatin1String("ImageDirs") ).toStringList();
00210 QStringList dcfs = settings.value( profKey + QLatin1String("DocFiles") ).toStringList();
00211 profil->props[QLatin1String("name")] = QLatin1String("default");
00212
00213 QString filePath;
00214 QStringList::ConstIterator it = titles.constBegin();
00215 QStringList::ConstIterator iconIt = iconLst.constBegin();
00216 QStringList::ConstIterator indexIt = indexLst.constBegin();
00217 QStringList::ConstIterator imageIt = imgDirLst.constBegin();
00218 QStringList::ConstIterator dcfIt = dcfs.constBegin();
00219 while((it != titles.constEnd())
00220 && (iconIt != iconLst.constEnd())
00221 && (indexIt != indexLst.constEnd())
00222 && (imageIt != imgDirLst.constEnd())
00223 && (dcfIt != dcfs.constEnd())) {
00224 profil->addDCFIcon( *it, *iconIt );
00225 profil->addDCFIndexPage(*it, Profile::loadableFilePath(*indexIt));
00226 profil->addDCFImageDir( *it, *imageIt );
00227 profil->addDCFTitle(Profile::loadableFilePath(*dcfIt), *it);
00228 ++it, ++iconIt, ++indexIt, ++imageIt, ++dcfIt;
00229 }
00230 #if ASSISTANT_DEBUG
00231 dumpmap( profil->icons, QLatin1String("Icons") );
00232 dumpmap( profil->indexPages, QLatin1String("IndexPages") );
00233 dumpmap( profil->imageDirs, QLatin1String("ImageDirs") );
00234 dumpmap( profil->dcfTitles, QLatin1String("dcfTitles") );
00235 qDebug( "Docfiles: \n " + profil->docs.join( "\n " ) );
00236 #endif
00237 }
00238
00239 void Config::saveProfile( Profile *profile )
00240 {
00241 if (profil->profileType() == Profile::UserProfile)
00242 return;
00243
00244 const QString key = (profile->props[QLatin1String("name")] == QLatin1String("default"))
00245 ? QString::fromLatin1(QT_VERSION_STR)
00246 : getVersionString();
00247
00248 const QString profKey = key + QLatin1String("/Profile/") + profile->props[QLatin1String("name")] + QLatin1String("/");
00249
00250 QString path = QLibraryInfo::location(QLibraryInfo::DocumentationPath).replace("\\", "/");
00251 QStringList indexes, icons, imgDirs, dcfs;
00252 QStringList titles = profile->dcfTitles.keys();
00253 QStringList::ConstIterator it = titles.constBegin();
00254 QString filePath;
00255 for ( ; it != titles.constEnd(); ++it ) {
00256
00257 indexes << Profile::storableFilePath(profile->indexPages[*it]);
00258 icons << profile->icons[*it];
00259 imgDirs << profile->imageDirs[*it];
00260 dcfs << Profile::storableFilePath(profile->dcfTitles[*it]);
00261 }
00262
00263 QSettings settings;
00264 settings.setValue( profKey + QLatin1String("Titles"), titles );
00265 settings.setValue( profKey + QLatin1String("DocFiles"), dcfs );
00266 settings.setValue( profKey + QLatin1String("IndexPages"), indexes );
00267 settings.setValue( profKey + QLatin1String("DocIcons"), icons );
00268 settings.setValue( profKey + QLatin1String("ImageDirs"), imgDirs );
00269
00270 #if ASSISTANT_DEBUG
00271 qDebug() << "Titles:\n - " << ((QStringList*)&titles)->join("\n - ");
00272 qDebug() << "Docfiles:\n - " << dcfs.join("\n - " );
00273 qDebug() << "IndexPages:\n - " << indexes.join("\n - ");
00274 qDebug() << "DocIcons:\n - " << icons.join("\n - " );
00275 qDebug() << "ImageDirs:\n - " << imgDirs.join("\n - " );
00276 #endif
00277 }
00278
00279 QStringList Config::mimePaths()
00280 {
00281 static QStringList lst;
00282
00283 if( lst.count() > 0 )
00284 return lst;
00285
00286 for (QMap<QString,QString>::ConstIterator it = profil->dcfTitles.constBegin();
00287 it != profil->dcfTitles.constEnd(); ++it ) {
00288
00289
00290 QFileInfo info( *it );
00291 QString dcfPath = info.absolutePath();
00292 if (!lst.contains(dcfPath))
00293 lst << dcfPath;
00294
00295
00296 QString imgDir = QDir::toNativeSeparators( dcfPath + QDir::separator()
00297 + profil->imageDirs[it.key()] );
00298 if (!lst.contains(imgDir))
00299 lst << imgDir;
00300 }
00301 return lst;
00302 }
00303
00304 QStringList Config::profiles() const
00305 {
00306 return profileNames;
00307 }
00308
00309 QString Config::title() const
00310 {
00311 QString s = profil->props[QLatin1String("title")];
00312 if (s.isEmpty())
00313 s = QObject::tr("Qt Assistant by Trolltech");
00314 return s;
00315 }
00316
00317 QString Config::aboutApplicationMenuText() const
00318 {
00319 return profil->props[QLatin1String("aboutmenutext")];
00320 }
00321
00322 QString Config::aboutURL() const
00323 {
00324 return profil->props[QLatin1String("abouturl")];
00325 }
00326
00327 QString Config::homePage() const
00328 {
00329 return home.isEmpty() ? profil->props[QLatin1String("startpage")] : home;
00330 }
00331
00332 QStringList Config::source() const
00333 {
00334 return src.size() == 0 ? QStringList(profil->props[QLatin1String("startpage")]) : src;
00335 }
00336
00337 QStringList Config::docFiles() const
00338 {
00339 return profil->docs;
00340 }
00341
00342 QPixmap Config::docIcon( const QString &title ) const
00343 {
00344
00345 QString name = profil->icons[title];
00346 QString resName = QLatin1String(":/trolltech/assistant/images/") + name;
00347
00348 if (QFile::exists(resName))
00349 return QPixmap(resName);
00350
00351 if (name.startsWith("file:"))
00352 name = name.mid(5);
00353 return QPixmap(name);
00354 }
00355
00356 QPixmap Config::applicationIcon() const
00357 {
00358 QString name = profil->props[QLatin1String("applicationicon")];
00359 QString resName = QLatin1String(":/trolltech/assistant/images/") + name;
00360
00361 if (QFile::exists(resName))
00362 return QPixmap(resName);
00363
00364 if (name.startsWith("file:"))
00365 name = name.mid(5);
00366 return QPixmap(name);
00367 }
00368
00369 QStringList Config::docTitles() const
00370 {
00371 return QStringList(profil->indexPages.keys());
00372 }
00373
00374 QString Config::docImageDir( const QString &docfile ) const
00375 {
00376 return profil->imageDirs[docfile];
00377 }
00378
00379 QString Config::indexPage( const QString &title ) const
00380 {
00381 return profil->indexPages[title];
00382 }
00383
00384 void Config::hideSideBar( bool b )
00385 {
00386 hideSidebar = b;
00387 }
00388
00389 bool Config::sideBarHidden() const
00390 {
00391 return hideSidebar;
00392 }
00393
00394 QString Config::assistantDocPath() const
00395 {
00396 return profil->props[QLatin1String("assistantdocs")].isEmpty()
00397 ? QLibraryInfo::location(QLibraryInfo::DocumentationPath) + QLatin1String("/html")
00398 : profil->props[QLatin1String("assistantdocs")];
00399 }