6#include <QtCore/QFileInfo>
7#include <QtCore/QLibraryInfo>
8#include <QtCore/QLocale>
9#include <QtCore/QStringList>
10#include <QtCore/QTranslator>
13#include <QtWidgets/QApplication>
14#include <QtGui/QDesktopServices>
16#include <QtHelp/QHelpEngine>
17#include <QtHelp/QHelpSearchEngine>
19#include <QtSql/QSqlDatabase>
21#if defined(BROWSER_QTWEBKIT)
23#include <QWebSettings>
26#include "../shared/collectionconfiguration.h"
37using namespace Qt::StringLiterals;
42updateLastPagesOnUnregister(QHelpEngineCore& helpEngine,
const QString& nsName)
46 QStringList currentPages = CollectionConfiguration::lastShownPages(helpEngine);
47 if (!currentPages.isEmpty()) {
48 QStringList zoomList = CollectionConfiguration::lastZoomFactors(helpEngine);
49 while (zoomList.size() < currentPages.size())
50 zoomList.append(CollectionConfiguration::DefaultZoomFactor);
52 for (
int i = currentPages.size(); --i >= 0;) {
53 if (QUrl(currentPages.at(i)).host() == nsName) {
55 currentPages.removeAt(i);
56 lastPage = (lastPage == (i + 1)) ? 1 : lastPage;
60 CollectionConfiguration::setLastShownPages(helpEngine, currentPages);
62 CollectionConfiguration::setLastZoomFactors(helpEngine, zoomList);
66void stripNonexistingDocs(QHelpEngineCore& collection)
69 const QStringList &namespaces = collection.registeredDocumentations();
70 for (
const QString &ns : namespaces) {
71 QFileInfo fi(collection.documentationFileName(ns));
72 if (!fi.exists() || !fi.isFile())
73 collection.unregisterDocumentation(ns);
77QString indexFilesFolder(
const QString &collectionFile)
80 QString indexFilesFolder =
".fulltextsearch"_L1;
81 if (!collectionFile.isEmpty()) {
82 QFileInfo fi(collectionFile);
83 const QString fileName = fi.fileName();
85 const QString baseName = fileName.endsWith(
".qhc"_L1) ? fileName.chopped(4) : QString();
86 indexFilesFolder = u'.' + (baseName.isEmpty() ? fileName +
".fulltextsearch"_L1 : baseName);
88 return indexFilesFolder;
92
93
94
95
96QString constructCachedCollectionFilePath(
const QHelpEngineCore &collection)
99 const QString &filePath = collection.collectionFile();
100 const QString &fileName = QFileInfo(filePath).fileName();
101 const QString &cacheDir = CollectionConfiguration::cacheDir(collection);
102 const QString &dir = !cacheDir.isEmpty()
103 && CollectionConfiguration::cacheDirIsRelativeToCollection(collection)
104 ? QFileInfo(filePath).dir().absolutePath()
105 + QDir::separator() + cacheDir
106 : MainWindow::collectionFileDirectory(
false, cacheDir);
107 return dir + QDir::separator() + fileName;
110bool synchronizeDocs(QHelpEngineCore &collection,
111 QHelpEngineCore &cachedCollection,
115 const QDateTime &lastCollectionRegisterTime =
116 CollectionConfiguration::lastRegisterTime(collection);
117 if (!lastCollectionRegisterTime.isValid() || lastCollectionRegisterTime
118 < CollectionConfiguration::lastRegisterTime(cachedCollection))
121 const QStringList &docs = collection.registeredDocumentations();
122 const QStringList &cachedDocs = cachedCollection.registeredDocumentations();
125
126
127
128 for (
const QString &doc : docs) {
129 if (!cachedDocs.contains(doc)) {
130 const QString &docFile = collection.documentationFileName(doc);
131 if (!cachedCollection.registerDocumentation(docFile)) {
132 cmd.showMessage(QCoreApplication::translate(
"Assistant",
133 "Error registering documentation file '%1': %2").
134 arg(docFile, cachedCollection.error()),
true);
145bool removeSearchIndex(
const QString &collectionFile)
149 QFileInfo(collectionFile).path() + u'/' + indexFilesFolder(collectionFile);
156 dir.remove(
"fts"_L1);
160QCoreApplication* createApplication(
int &argc,
char *argv[])
165 const char * cmdModeArgs[] = {
166 "-help",
"-register",
"-unregister",
"-remove-search-index",
167 "-rebuild-search-index"
169 for (
int i = 1; i < argc; ++i) {
170 for (size_t j = 0; j <
sizeof cmdModeArgs/
sizeof *cmdModeArgs; ++j) {
171 if (strcmp(argv[i], cmdModeArgs[j]) == 0)
172 return new QCoreApplication(argc, argv);
176 QApplication *app =
new QApplication(argc, argv);
177 app->connect(app, &QGuiApplication::lastWindowClosed, app,
178 &QCoreApplication::quit);
182bool registerDocumentation(QHelpEngineCore &collection,
CmdLineParser &cmd,
186 if (!collection.registerDocumentation(cmd.helpFile())) {
187 cmd.showMessage(QCoreApplication::translate(
"Assistant",
188 "Could not register documentation file\n%1\n\nReason:\n%2")
189 .arg(cmd.helpFile(), collection.error()),
true);
193 cmd.showMessage(QCoreApplication::translate(
"Assistant",
194 "Documentation successfully registered."),
200bool unregisterDocumentation(QHelpEngineCore &collection,
201 const QString &namespaceName,
CmdLineParser &cmd,
bool printSuccess)
204 if (!collection.unregisterDocumentation(namespaceName)) {
205 cmd.showMessage(QCoreApplication::translate(
"Assistant",
206 "Could not unregister documentation"
207 " file\n%1\n\nReason:\n%2").
208 arg(cmd.helpFile(), collection.error()),
true);
211 updateLastPagesOnUnregister(collection, namespaceName);
213 cmd.showMessage(QCoreApplication::translate(
"Assistant",
214 "Documentation successfully unregistered."),
219void setupTranslation(
const QString &fileName,
const QString &dir)
221 QTranslator *translator =
new QTranslator(QCoreApplication::instance());
222 if (translator->load(QLocale(), fileName,
"_"_L1, dir))
223 QCoreApplication::installTranslator(translator);
226void setupTranslations()
229 const QStringList resourceDirs
230 = QLibraryInfo::paths(QLibraryInfo::TranslationsPath);
231 for (
const QString &resourceDir : resourceDirs) {
232 setupTranslation(
"assistant"_L1, resourceDir);
233 setupTranslation(
"qt"_L1, resourceDir);
234 setupTranslation(
"qt_help"_L1, resourceDir);
249
250
251
252
253 const QString collectionFile = cmd->collectionFile();
254 const bool collectionFileGiven = !collectionFile.isEmpty();
255 std::unique_ptr<QHelpEngineCore> collection;
256 if (collectionFileGiven) {
257 collection.reset(
new QHelpEngineCore(collectionFile));
258 if (!collection->setupData()) {
259 cmd->showMessage(QCoreApplication::translate(
"Assistant",
260 "Error reading collection file '%1': %2.")
261 .arg(collectionFile, collection->error()),
true);
265 const QString &cachedCollectionFile = collectionFileGiven
266 ? constructCachedCollectionFilePath(*collection)
267 : MainWindow::defaultHelpCollectionFileName();
268 if (collectionFileGiven && !QFileInfo(cachedCollectionFile).exists()
269 && !collection->copyCollectionFile(cachedCollectionFile)) {
270 cmd->showMessage(QCoreApplication::translate(
"Assistant",
271 "Error creating collection file '%1': %2.")
272 .arg(cachedCollectionFile, collection->error()),
true);
275 QHelpEngineCore cachedCollection(cachedCollectionFile);
278 cachedCollection.setReadOnly(
false);
279 if (!cachedCollection.setupData()) {
280 cmd->showMessage(QCoreApplication::translate(
"Assistant",
281 "Error reading collection file '%1': %2.")
282 .arg(cachedCollectionFile, cachedCollection.error()),
true);
286 stripNonexistingDocs(cachedCollection);
287 if (collectionFileGiven) {
291 if (!synchronizeDocs(*collection, cachedCollection, *cmd))
296 const QStringList &cachedDocs =
297 cachedCollection.registeredDocumentations();
298 const QString &namespaceName =
299 QHelpEngineCore::namespaceName(cmd->helpFile());
301 if (collectionFileGiven
302 && !registerDocumentation(*collection, *cmd,
true))
304 if (!cachedDocs.contains(namespaceName)
305 && !registerDocumentation(cachedCollection, *cmd, !collectionFileGiven))
310 if (collectionFileGiven
311 && !unregisterDocumentation(*collection, namespaceName, *cmd,
true))
313 if (cachedDocs.contains(namespaceName)
314 && !unregisterDocumentation(cachedCollection, namespaceName,
315 *cmd, !collectionFileGiven))
322 return removeSearchIndex(cachedCollectionFile)
323 ? ExitSuccess : ExitFailure;
326 if (!QSqlDatabase::isDriverAvailable(
"QSQLITE"_L1)) {
327 cmd->showMessage(QCoreApplication::translate(
"Assistant",
328 "Cannot load sqlite database driver!"),
333 if (!cmd->currentFilter().isEmpty()) {
334 if (collectionFileGiven)
335 collection->setCurrentFilter(cmd->currentFilter());
336 cachedCollection.setCurrentFilter(cmd->currentFilter());
339 if (collectionFileGiven)
340 cmd->setCollectionFile(cachedCollectionFile);
345int main(
int argc,
char *argv[])
348 std::unique_ptr<QCoreApplication> a(createApplication(argc, argv));
349#if QT_CONFIG(library)
350 a->addLibraryPath(a->applicationDirPath() +
"/plugins"_L1);
354#if defined(BROWSER_QTWEBKIT)
355 if (qobject_cast<QApplication *>(a.data())) {
357 f.setStyleHint(QFont::SansSerif);
358 QWebSettings::globalSettings()->setFontFamily(QWebSettings::StandardFont, f.defaultFamily());
364 CmdLineParser::Result res = cmd.parse();
365 if (res == CmdLineParser::Help)
367 else if (res == CmdLineParser::Error)
372 case ExitFailure:
return EXIT_FAILURE;
373 case ExitSuccess:
return EXIT_SUCCESS;
381
382
383
384
385 const int retval = a->exec();
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)
int main(int argc, char *argv[])
[ctor_close]