|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the Qt Assistant of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include "config.h" |
|
43 #include "profile.h" |
|
44 #include "docuparser.h" |
|
45 |
|
46 #include <QApplication> |
|
47 #include <QDesktopWidget> |
|
48 #include <QLibraryInfo> |
|
49 #include <QFont> |
|
50 #include <QFontInfo> |
|
51 #include <QDir> |
|
52 #include <QFile> |
|
53 #include <QFileInfo> |
|
54 #include <QSettings> |
|
55 #include <QList> |
|
56 |
|
57 QT_BEGIN_NAMESPACE |
|
58 |
|
59 static Config *static_configuration = 0; |
|
60 |
|
61 inline QString getVersionString() |
|
62 { |
|
63 return QString::number( (QT_VERSION >> 16) & 0xff ) |
|
64 + QLatin1String(".") + QString::number( (QT_VERSION >> 8) & 0xff ); |
|
65 } |
|
66 |
|
67 Config::Config() |
|
68 : profil( 0 ), hideSidebar( false ), rebuildDocs(true) |
|
69 { |
|
70 if( !static_configuration ) { |
|
71 static_configuration = this; |
|
72 } else { |
|
73 qWarning( "Multiple configurations not allowed!" ); |
|
74 } |
|
75 } |
|
76 |
|
77 Config *Config::loadConfig(const QString &profileFileName) |
|
78 { |
|
79 Config *config = new Config(); |
|
80 |
|
81 if (profileFileName.isEmpty()) { // no profile |
|
82 if (!config->defaultProfileExists()) { |
|
83 config->profil = Profile::createDefaultProfile(); |
|
84 config->saveProfile(config->profil); |
|
85 } else { |
|
86 config->profil = new Profile(); |
|
87 } |
|
88 config->loadDefaultProfile(); |
|
89 config->load(); |
|
90 return config; |
|
91 } |
|
92 |
|
93 QFile file(profileFileName); |
|
94 if (!file.exists()) { |
|
95 qWarning( "File does not exist: %s", qPrintable(profileFileName) ); |
|
96 return 0; |
|
97 } |
|
98 DocuParser *parser = DocuParser::createParser( profileFileName ); |
|
99 if (!parser) { |
|
100 qWarning( "Failed to create parser for file: %s", qPrintable(profileFileName) ); |
|
101 return 0; |
|
102 } |
|
103 if (parser->parserVersion() < DocuParser::Qt320) { |
|
104 qWarning( "File does not contain profile information" ); |
|
105 return 0; |
|
106 } |
|
107 DocuParser320 *profileParser = static_cast<DocuParser320*>(parser); |
|
108 parser->parse(&file); |
|
109 config->profil = profileParser->profile(); |
|
110 if (!config->profil) { |
|
111 qWarning( "Config::loadConfig(), no profile in: %s", qPrintable(profileFileName) ); |
|
112 return 0; |
|
113 } |
|
114 config->profil->setProfileType(Profile::UserProfile); |
|
115 config->profil->setDocuParser(profileParser); |
|
116 config->load(); |
|
117 return config; |
|
118 } |
|
119 |
|
120 Config *Config::configuration() |
|
121 { |
|
122 Q_ASSERT( static_configuration ); |
|
123 return static_configuration; |
|
124 } |
|
125 |
|
126 void Config::load() |
|
127 { |
|
128 const QString key = getVersionString() + QLatin1String("/"); |
|
129 |
|
130 bool isDefaultProfile = profil->props[QLatin1String("name")] == QLatin1String("default"); |
|
131 const QString pKey = isDefaultProfile ? QString::fromLatin1(QT_VERSION_STR) |
|
132 : getVersionString(); |
|
133 |
|
134 const QString profkey = pKey + QLatin1String("/Profile/") + profil->props[QLatin1String("name")] + QLatin1String("/"); |
|
135 |
|
136 QSettings settings; |
|
137 |
|
138 home = profil->props[QLatin1String("startpage")];; |
|
139 if (home.isEmpty() && isDefaultProfile) |
|
140 home = QLibraryInfo::location(QLibraryInfo::DocumentationPath) + QLatin1String("/html/index.html"); |
|
141 src = settings.value( profkey + QLatin1String("Source") ).toStringList(); |
|
142 sideBar = settings.value( key + QLatin1String("SideBarPage") ).toInt(); |
|
143 if (qApp->type() != QApplication::Tty) |
|
144 winGeometry = settings.value(key + QLatin1String("windowGeometry")).toByteArray(); |
|
145 |
|
146 mainWinState = settings.value(key + QLatin1String("MainWindowState")).toByteArray(); |
|
147 pointFntSize = settings.value(key + QLatin1String("FontSize"), qApp->font().pointSizeF()).toDouble(); |
|
148 rebuildDocs = settings.value( key + QLatin1String("RebuildDocDB"), true ).toBool(); |
|
149 |
|
150 profileNames = settings.value( key + QLatin1String("Profile") ).toStringList(); |
|
151 |
|
152 m_fontSettings.windowFont = qVariantValue<QFont>(settings.value(key + QLatin1String("windowfont"), qApp->font())); |
|
153 m_fontSettings.browserFont = qVariantValue<QFont>(settings.value(key + QLatin1String("browserfont"), qApp->font())); |
|
154 m_fontSettings.useWindowFont = settings.value(key + QLatin1String("usewindowfont"), false).toBool(); |
|
155 m_fontSettings.useBrowserFont = settings.value(key + QLatin1String("usebrowserfont"), false).toBool(); |
|
156 m_fontSettings.windowWritingSystem = static_cast<QFontDatabase::WritingSystem>( |
|
157 settings.value(key + QLatin1String("windowwritingsystem"), QFontDatabase::Latin).toInt()); |
|
158 m_fontSettings.browserWritingSystem = static_cast<QFontDatabase::WritingSystem>( |
|
159 settings.value(key + QLatin1String("browserwritingsystem"), QFontDatabase::Latin).toInt()); |
|
160 |
|
161 m_fontSettings.browserFont.setPointSizeF(pointFntSize); |
|
162 } |
|
163 |
|
164 void Config::save() |
|
165 { |
|
166 saveSettings(); |
|
167 saveProfile( profil ); |
|
168 } |
|
169 |
|
170 void Config::saveSettings() |
|
171 { |
|
172 const QString key = getVersionString() + QLatin1String("/"); |
|
173 |
|
174 const QString pKey = (profil->props[QLatin1String("name")] == QLatin1String("default")) |
|
175 ? QString::fromLatin1(QT_VERSION_STR) |
|
176 : getVersionString(); |
|
177 |
|
178 const QString profkey = pKey + QLatin1String("/Profile/") + profil->props[QLatin1String("name")] + QLatin1String("/"); |
|
179 |
|
180 QSettings settings; |
|
181 |
|
182 settings.setValue( profkey + QLatin1String("Source"), src ); |
|
183 settings.setValue( key + QLatin1String("SideBarPage"), sideBarPage() ); |
|
184 if (qApp->type() != QApplication::Tty) |
|
185 settings.setValue(key + QLatin1String("windowGeometry"), winGeometry); |
|
186 |
|
187 settings.setValue( key + QLatin1String("MainWindowState"), mainWinState ); |
|
188 settings.setValue( key + QLatin1String("FontSize"), pointFntSize); |
|
189 settings.setValue( key + QLatin1String("RebuildDocDB"), rebuildDocs ); |
|
190 |
|
191 settings.setValue(key + QLatin1String("windowfont"), m_fontSettings.windowFont); |
|
192 settings.setValue(key + QLatin1String("browserfont"), m_fontSettings.browserFont); |
|
193 settings.setValue(key + QLatin1String("usewindowfont"), m_fontSettings.useWindowFont); |
|
194 settings.setValue(key + QLatin1String("usebrowserfont"), m_fontSettings.useBrowserFont); |
|
195 settings.setValue(key + QLatin1String("windowwritingsystem"), m_fontSettings.windowWritingSystem); |
|
196 settings.setValue(key + QLatin1String("browserwritingsystem"), m_fontSettings.browserWritingSystem); |
|
197 } |
|
198 |
|
199 #ifdef ASSISTANT_DEBUG |
|
200 static void dumpmap( const QMap<QString,QString> &m, const QString &header ) |
|
201 { |
|
202 qDebug( header ); |
|
203 QMap<QString,QString>::ConstIterator it = m.begin(); |
|
204 while (it != m.end()) { |
|
205 qDebug( " " + it.key() + ":\t\t" + *it ); |
|
206 ++it; |
|
207 } |
|
208 } |
|
209 #endif |
|
210 |
|
211 bool Config::defaultProfileExists() |
|
212 { |
|
213 QSettings settings; |
|
214 const QString profKey = QLatin1String(QT_VERSION_STR) + QLatin1String("/Profile/default/"); |
|
215 |
|
216 if (settings.contains(profKey + QLatin1String("DocFiles")) |
|
217 && settings.contains(profKey + QLatin1String("Titles")) |
|
218 && settings.contains(profKey + QLatin1String("ImageDirs"))) { |
|
219 QStringList dcfs = settings.value(profKey + QLatin1String("DocFiles") ).toStringList(); |
|
220 foreach (QString file, dcfs) { |
|
221 if (file == Profile::storableFilePath(file)) |
|
222 return true; |
|
223 } |
|
224 } |
|
225 return false; |
|
226 } |
|
227 |
|
228 void Config::loadDefaultProfile() |
|
229 { |
|
230 QSettings settings; |
|
231 const QString profKey = QLatin1String(QT_VERSION_STR) + QLatin1String("/Profile/default/"); |
|
232 |
|
233 if (!defaultProfileExists()) |
|
234 return; |
|
235 |
|
236 // Override the defaults with settings in registry. |
|
237 profil->icons.clear(); |
|
238 profil->indexPages.clear(); |
|
239 profil->imageDirs.clear(); |
|
240 profil->docs.clear(); |
|
241 profil->dcfTitles.clear(); |
|
242 |
|
243 QStringList titles = settings.value( profKey + QLatin1String("Titles") ).toStringList(); |
|
244 QStringList iconLst = settings.value( profKey + QLatin1String("DocIcons") ).toStringList(); |
|
245 QStringList indexLst = settings.value( profKey + QLatin1String("IndexPages") ).toStringList(); |
|
246 QStringList imgDirLst = settings.value( profKey + QLatin1String("ImageDirs") ).toStringList(); |
|
247 QStringList dcfs = settings.value( profKey + QLatin1String("DocFiles") ).toStringList(); |
|
248 profil->props[QLatin1String("name")] = QLatin1String("default"); |
|
249 |
|
250 QString filePath; |
|
251 QStringList::ConstIterator it = titles.constBegin(); |
|
252 QStringList::ConstIterator iconIt = iconLst.constBegin(); |
|
253 QStringList::ConstIterator indexIt = indexLst.constBegin(); |
|
254 QStringList::ConstIterator imageIt = imgDirLst.constBegin(); |
|
255 QStringList::ConstIterator dcfIt = dcfs.constBegin(); |
|
256 while((it != titles.constEnd()) |
|
257 && (iconIt != iconLst.constEnd()) |
|
258 && (indexIt != indexLst.constEnd()) |
|
259 && (imageIt != imgDirLst.constEnd()) |
|
260 && (dcfIt != dcfs.constEnd())) { |
|
261 profil->addDCFIcon( *it, *iconIt ); |
|
262 profil->addDCFIndexPage(*it, Profile::loadableFilePath(*indexIt)); |
|
263 profil->addDCFImageDir( *it, *imageIt ); |
|
264 profil->addDCFTitle(Profile::loadableFilePath(*dcfIt), *it); |
|
265 ++it, ++iconIt, ++indexIt, ++imageIt, ++dcfIt; |
|
266 } |
|
267 #if ASSISTANT_DEBUG |
|
268 dumpmap( profil->icons, QLatin1String("Icons") ); |
|
269 dumpmap( profil->indexPages, QLatin1String("IndexPages") ); |
|
270 dumpmap( profil->imageDirs, QLatin1String("ImageDirs") ); |
|
271 dumpmap( profil->dcfTitles, QLatin1String("dcfTitles") ); |
|
272 qDebug( "Docfiles: \n " + profil->docs.join( "\n " ) ); |
|
273 #endif |
|
274 } |
|
275 |
|
276 void Config::saveProfile( Profile *profile ) |
|
277 { |
|
278 if (profil->profileType() == Profile::UserProfile) |
|
279 return; |
|
280 |
|
281 const QString key = (profile->props[QLatin1String("name")] == QLatin1String("default")) |
|
282 ? QString::fromLatin1(QT_VERSION_STR) |
|
283 : getVersionString(); |
|
284 |
|
285 const QString profKey = key + QLatin1String("/Profile/") + profile->props[QLatin1String("name")] + QLatin1String("/"); |
|
286 |
|
287 QString path = QLibraryInfo::location(QLibraryInfo::DocumentationPath).replace(QLatin1String("\\"), QLatin1String("/")); |
|
288 QStringList indexes, icons, imgDirs, dcfs; |
|
289 QStringList titles = profile->dcfTitles.keys(); |
|
290 QStringList::ConstIterator it = titles.constBegin(); |
|
291 QString filePath; |
|
292 for ( ; it != titles.constEnd(); ++it ) { |
|
293 |
|
294 indexes << Profile::storableFilePath(profile->indexPages[*it]); |
|
295 icons << profile->icons[*it]; |
|
296 imgDirs << profile->imageDirs[*it]; |
|
297 dcfs << Profile::storableFilePath(profile->dcfTitles[*it]); |
|
298 } |
|
299 |
|
300 QSettings settings; |
|
301 settings.setValue( profKey + QLatin1String("Titles"), titles ); |
|
302 settings.setValue( profKey + QLatin1String("DocFiles"), dcfs ); |
|
303 settings.setValue( profKey + QLatin1String("IndexPages"), indexes ); |
|
304 settings.setValue( profKey + QLatin1String("DocIcons"), icons ); |
|
305 settings.setValue( profKey + QLatin1String("ImageDirs"), imgDirs ); |
|
306 |
|
307 #if ASSISTANT_DEBUG |
|
308 qDebug() << "Titles:\n - " << ((QStringList*)&titles)->join("\n - "); |
|
309 qDebug() << "Docfiles:\n - " << dcfs.join("\n - " ); |
|
310 qDebug() << "IndexPages:\n - " << indexes.join("\n - "); |
|
311 qDebug() << "DocIcons:\n - " << icons.join("\n - " ); |
|
312 qDebug() << "ImageDirs:\n - " << imgDirs.join("\n - " ); |
|
313 #endif |
|
314 } |
|
315 |
|
316 QStringList Config::mimePaths() |
|
317 { |
|
318 static QStringList lst; |
|
319 |
|
320 if( lst.count() > 0 ) |
|
321 return lst; |
|
322 |
|
323 for (QMap<QString,QString>::ConstIterator it = profil->dcfTitles.constBegin(); |
|
324 it != profil->dcfTitles.constEnd(); ++it ) { |
|
325 |
|
326 // Mime source for .dcf file path |
|
327 QFileInfo info( *it ); |
|
328 QString dcfPath = info.absolutePath(); |
|
329 if (!lst.contains(dcfPath)) |
|
330 lst << dcfPath; |
|
331 |
|
332 // Image dir for .dcf |
|
333 QString imgDir = QDir::toNativeSeparators( dcfPath + QDir::separator() |
|
334 + profil->imageDirs[it.key()] ); |
|
335 if (!lst.contains(imgDir)) |
|
336 lst << imgDir; |
|
337 } |
|
338 return lst; |
|
339 } |
|
340 |
|
341 QStringList Config::profiles() const |
|
342 { |
|
343 return profileNames; |
|
344 } |
|
345 |
|
346 QString Config::title() const |
|
347 { |
|
348 QString s = profil->props[QLatin1String("title")]; |
|
349 if (s.isEmpty()) |
|
350 s = QObject::tr("Qt Assistant by Nokia"); |
|
351 return s; |
|
352 } |
|
353 |
|
354 QString Config::aboutApplicationMenuText() const |
|
355 { |
|
356 return profil->props[QLatin1String("aboutmenutext")]; |
|
357 } |
|
358 |
|
359 QString Config::aboutURL() const |
|
360 { |
|
361 return profil->props[QLatin1String("abouturl")]; |
|
362 } |
|
363 |
|
364 QString Config::homePage() const |
|
365 { |
|
366 return home.isEmpty() ? profil->props[QLatin1String("startpage")] : home; |
|
367 } |
|
368 |
|
369 QStringList Config::source() const |
|
370 { |
|
371 return src.size() == 0 ? QStringList(profil->props[QLatin1String("startpage")]) : src; |
|
372 } |
|
373 |
|
374 QStringList Config::docFiles() const |
|
375 { |
|
376 return profil->docs; |
|
377 } |
|
378 |
|
379 QPixmap Config::docIcon( const QString &title ) const |
|
380 { |
|
381 // ### To allow qdoc generated dcf files to reference the doc icons from qmake_image_col |
|
382 QString name = profil->icons[title]; |
|
383 QString resName = QLatin1String(":/trolltech/assistant/images/") + name; |
|
384 |
|
385 if (QFile::exists(resName)) |
|
386 return QPixmap(resName); |
|
387 |
|
388 if (name.startsWith(QLatin1String("file:"))) |
|
389 name = name.mid(5); |
|
390 return QPixmap(name); |
|
391 } |
|
392 |
|
393 QPixmap Config::applicationIcon() const |
|
394 { |
|
395 QString name = profil->props[QLatin1String("applicationicon")]; |
|
396 QString resName = QLatin1String(":/trolltech/assistant/images/") + name; |
|
397 |
|
398 if (QFile::exists(resName)) |
|
399 return QPixmap(resName); |
|
400 |
|
401 if (name.startsWith(QLatin1String("file:"))) |
|
402 name = name.mid(5); |
|
403 return QPixmap(name); |
|
404 } |
|
405 |
|
406 QStringList Config::docTitles() const |
|
407 { |
|
408 return QStringList(profil->indexPages.keys()); |
|
409 } |
|
410 |
|
411 QString Config::docImageDir( const QString &docfile ) const |
|
412 { |
|
413 return profil->imageDirs[docfile]; |
|
414 } |
|
415 |
|
416 QString Config::indexPage( const QString &title ) const |
|
417 { |
|
418 return profil->indexPages[title]; |
|
419 } |
|
420 |
|
421 void Config::hideSideBar( bool b ) |
|
422 { |
|
423 hideSidebar = b; |
|
424 } |
|
425 |
|
426 bool Config::sideBarHidden() const |
|
427 { |
|
428 return hideSidebar; |
|
429 } |
|
430 |
|
431 QString Config::assistantDocPath() const |
|
432 { |
|
433 return profil->props[QLatin1String("assistantdocs")].isEmpty() |
|
434 ? QLibraryInfo::location(QLibraryInfo::DocumentationPath) + QLatin1String("/html") |
|
435 : profil->props[QLatin1String("assistantdocs")]; |
|
436 } |
|
437 |
|
438 QT_END_NAMESPACE |