6#include <QtCore/QFileInfo>
7#include <QtCore/QLibraryInfo>
8#include <QtCore/QLocale>
9#include <QtCore/QScopedPointer>
10#include <QtCore/QStringList>
11#include <QtCore/QTranslator>
14#include <QtWidgets/QApplication>
15#include <QtGui/QDesktopServices>
17#include <QtHelp/QHelpEngine>
18#include <QtHelp/QHelpSearchEngine>
20#include <QtSql/QSqlDatabase>
22#if defined(BROWSER_QTWEBKIT)
24#include <QWebSettings>
27#include "../shared/collectionconfiguration.h"
36using namespace Qt::StringLiterals;
41updateLastPagesOnUnregister(QHelpEngineCore& helpEngine,
const QString& nsName)
45 QStringList currentPages = CollectionConfiguration::lastShownPages(helpEngine);
46 if (!currentPages.isEmpty()) {
47 QStringList zoomList = CollectionConfiguration::lastZoomFactors(helpEngine);
48 while (zoomList.size() < currentPages.size())
49 zoomList.append(CollectionConfiguration::DefaultZoomFactor);
51 for (
int i = currentPages.size(); --i >= 0;) {
52 if (QUrl(currentPages.at(i)).host() == nsName) {
54 currentPages.removeAt(i);
55 lastPage = (lastPage == (i + 1)) ? 1 : lastPage;
59 CollectionConfiguration::setLastShownPages(helpEngine, currentPages);
61 CollectionConfiguration::setLastZoomFactors(helpEngine, zoomList);
65void stripNonexistingDocs(QHelpEngineCore& collection)
68 const QStringList &namespaces = collection.registeredDocumentations();
69 for (
const QString &ns : namespaces) {
70 QFileInfo fi(collection.documentationFileName(ns));
71 if (!fi.exists() || !fi.isFile())
72 collection.unregisterDocumentation(ns);
76QString indexFilesFolder(
const QString &collectionFile)
79 QString indexFilesFolder =
".fulltextsearch"_L1;
80 if (!collectionFile.isEmpty()) {
81 QFileInfo fi(collectionFile);
82 indexFilesFolder = u'.' + fi.fileName().left(fi.fileName().lastIndexOf(
".qhc"_L1));
84 return indexFilesFolder;
88
89
90
91
92QString constructCachedCollectionFilePath(
const QHelpEngineCore &collection)
95 const QString &filePath = collection.collectionFile();
96 const QString &fileName = QFileInfo(filePath).fileName();
97 const QString &cacheDir = CollectionConfiguration::cacheDir(collection);
98 const QString &dir = !cacheDir.isEmpty()
99 && CollectionConfiguration::cacheDirIsRelativeToCollection(collection)
100 ? QFileInfo(filePath).dir().absolutePath()
101 + QDir::separator() + cacheDir
102 : MainWindow::collectionFileDirectory(
false, cacheDir);
103 return dir + QDir::separator() + fileName;
106bool synchronizeDocs(QHelpEngineCore &collection,
107 QHelpEngineCore &cachedCollection,
111 const QDateTime &lastCollectionRegisterTime =
112 CollectionConfiguration::lastRegisterTime(collection);
113 if (!lastCollectionRegisterTime.isValid() || lastCollectionRegisterTime
114 < CollectionConfiguration::lastRegisterTime(cachedCollection))
117 const QStringList &docs = collection.registeredDocumentations();
118 const QStringList &cachedDocs = cachedCollection.registeredDocumentations();
121
122
123
124 for (
const QString &doc : docs) {
125 if (!cachedDocs.contains(doc)) {
126 const QString &docFile = collection.documentationFileName(doc);
127 if (!cachedCollection.registerDocumentation(docFile)) {
128 cmd.showMessage(QCoreApplication::translate(
"Assistant",
129 "Error registering documentation file '%1': %2").
130 arg(docFile).arg(cachedCollection.error()),
true);
141bool removeSearchIndex(
const QString &collectionFile)
145 QFileInfo(collectionFile).path() + u'/' + indexFilesFolder(collectionFile);
151 const QStringList &list = dir.entryList(QDir::Files | QDir::Hidden);
152 for (
const QString &item : list)
157QCoreApplication* createApplication(
int &argc,
char *argv[])
162 const char * cmdModeArgs[] = {
163 "-help",
"-register",
"-unregister",
"-remove-search-index",
164 "-rebuild-search-index"
166 for (
int i = 1; i < argc; ++i) {
167 for (size_t j = 0; j <
sizeof cmdModeArgs/
sizeof *cmdModeArgs; ++j) {
168 if (strcmp(argv[i], cmdModeArgs[j]) == 0)
169 return new QCoreApplication(argc, argv);
173 QApplication *app =
new QApplication(argc, argv);
174 app->connect(app, &QGuiApplication::lastWindowClosed, app,
175 &QCoreApplication::quit);
179bool registerDocumentation(QHelpEngineCore &collection,
CmdLineParser &cmd,
183 if (!collection.registerDocumentation(cmd.helpFile())) {
184 cmd.showMessage(QCoreApplication::translate(
"Assistant",
185 "Could not register documentation file\n%1\n\nReason:\n%2")
186 .arg(cmd.helpFile()).arg(collection.error()),
true);
190 cmd.showMessage(QCoreApplication::translate(
"Assistant",
191 "Documentation successfully registered."),
197bool unregisterDocumentation(QHelpEngineCore &collection,
198 const QString &namespaceName,
CmdLineParser &cmd,
bool printSuccess)
201 if (!collection.unregisterDocumentation(namespaceName)) {
202 cmd.showMessage(QCoreApplication::translate(
"Assistant",
203 "Could not unregister documentation"
204 " file\n%1\n\nReason:\n%2").
205 arg(cmd.helpFile()).arg(collection.error()),
true);
208 updateLastPagesOnUnregister(collection, namespaceName);
210 cmd.showMessage(QCoreApplication::translate(
"Assistant",
211 "Documentation successfully unregistered."),
216void setupTranslation(
const QString &fileName,
const QString &dir)
218 QTranslator *translator =
new QTranslator(QCoreApplication::instance());
219 if (translator->load(QLocale(), fileName,
"_"_L1, dir))
220 QCoreApplication::installTranslator(translator);
223void setupTranslations()
226 const QString &resourceDir
227 = QLibraryInfo::path(QLibraryInfo::TranslationsPath);
228 setupTranslation(
"assistant"_L1, resourceDir);
229 setupTranslation(
"qt"_L1, resourceDir);
230 setupTranslation(
"qt_help"_L1, resourceDir);
244
245
246
247
248 const QString collectionFile = cmd->collectionFile();
249 const bool collectionFileGiven = !collectionFile.isEmpty();
250 QScopedPointer<QHelpEngineCore> collection;
251 if (collectionFileGiven) {
252 collection.reset(
new QHelpEngineCore(collectionFile));
253 if (!collection->setupData()) {
254 cmd->showMessage(QCoreApplication::translate(
"Assistant",
255 "Error reading collection file '%1': %2.")
256 .arg(collectionFile).arg(collection->error()),
true);
260 const QString &cachedCollectionFile = collectionFileGiven
261 ? constructCachedCollectionFilePath(*collection)
262 : MainWindow::defaultHelpCollectionFileName();
263 if (collectionFileGiven && !QFileInfo(cachedCollectionFile).exists()
264 && !collection->copyCollectionFile(cachedCollectionFile)) {
265 cmd->showMessage(QCoreApplication::translate(
"Assistant",
266 "Error creating collection file '%1': %2.")
267 .arg(cachedCollectionFile).arg(collection->error()),
true);
270 QHelpEngineCore cachedCollection(cachedCollectionFile);
271 if (!cachedCollection.setupData()) {
272 cmd->showMessage(QCoreApplication::translate(
"Assistant",
273 "Error reading collection file '%1': %2.")
274 .arg(cachedCollectionFile)
275 .arg(cachedCollection.error()),
true);
279 stripNonexistingDocs(cachedCollection);
280 if (collectionFileGiven) {
284 if (!synchronizeDocs(*collection, cachedCollection, *cmd))
289 const QStringList &cachedDocs =
290 cachedCollection.registeredDocumentations();
291 const QString &namespaceName =
292 QHelpEngineCore::namespaceName(cmd->helpFile());
294 if (collectionFileGiven
295 && !registerDocumentation(*collection, *cmd,
true))
297 if (!cachedDocs.contains(namespaceName)
298 && !registerDocumentation(cachedCollection, *cmd, !collectionFileGiven))
303 if (collectionFileGiven
304 && !unregisterDocumentation(*collection, namespaceName, *cmd,
true))
306 if (cachedDocs.contains(namespaceName)
307 && !unregisterDocumentation(cachedCollection, namespaceName,
308 *cmd, !collectionFileGiven))
315 return removeSearchIndex(cachedCollectionFile)
316 ? ExitSuccess : ExitFailure;
319 if (!QSqlDatabase::isDriverAvailable(
"QSQLITE"_L1)) {
320 cmd->showMessage(QCoreApplication::translate(
"Assistant",
321 "Cannot load sqlite database driver!"),
326 if (!cmd->currentFilter().isEmpty()) {
327 if (collectionFileGiven)
328 collection->setCurrentFilter(cmd->currentFilter());
329 cachedCollection.setCurrentFilter(cmd->currentFilter());
332 if (collectionFileGiven)
333 cmd->setCollectionFile(cachedCollectionFile);
338int main(
int argc,
char *argv[])
341 QScopedPointer<QCoreApplication> a(createApplication(argc, argv));
342#if QT_CONFIG(library)
343 a->addLibraryPath(a->applicationDirPath() +
"/plugins"_L1);
347#if defined(BROWSER_QTWEBKIT)
348 if (qobject_cast<QApplication *>(a.data())) {
350 f.setStyleHint(QFont::SansSerif);
351 QWebSettings::globalSettings()->setFontFamily(QWebSettings::StandardFont, f.defaultFamily());
357 CmdLineParser::Result res = cmd.parse();
358 if (res == CmdLineParser::Help)
360 else if (res == CmdLineParser::Error)
365 case ExitFailure:
return EXIT_FAILURE;
366 case ExitSuccess:
return EXIT_SUCCESS;
374
375
376
377
378 const int retval = a->exec();
int main(int argc, char *argv[])
[2]
RegisterState registerRequest() const
bool removeSearchIndex() const
static bool isNewer(const QHelpEngineCore &newer, const QHelpEngineCore &older)
static void setLastTabPage(QHelpEngineCore &helpEngine, int lastPage)
static void copyConfiguration(const QHelpEngineCore &source, QHelpEngineCore &target)
static void updateLastRegisterTime(QHelpEngineCore &helpEngine)
static int lastTabPage(const QHelpEngineCore &helpEngine)
static void removeInstance()
static ExitStatus preliminarySetup(CmdLineParser *cmd)