BibleTime
main.cpp
Go to the documentation of this file.
1 /*********
2 *
3 * In the name of the Father, and of the Son, and of the Holy Spirit.
4 *
5 * This file is part of BibleTime's source code, https://bibletime.info/
6 *
7 * Copyright 1999-2021 by the BibleTime developers.
8 * The BibleTime source code is licensed under the GNU General Public License
9 * version 2.0.
10 *
11 **********/
12 
13 #include <iostream>
14 #include <QDateTime>
15 #include <QLibraryInfo>
16 #include <QLocale>
17 #include <QQmlEngine>
18 #include <QTranslator>
19 #include "../backend/bookshelfmodel/btbookshelftreemodel.h"
20 #include "../backend/config/btconfig.h"
21 #include "../backend/managers/cswordbackend.h"
22 #include "../util/directory.h"
23 #include "bibletime.h"
24 #include "bibletimeapp.h"
27 
28 // Sword includes:
29 #include <swmgr.h>
30 
31 /// \todo Reimplement signal handler which handles consecutive crashes.
32 
33 namespace {
34 
35 /*******************************************************************************
36  Printing command-line help.
37 *******************************************************************************/
38 
39 /**
40  Prints command-line help text for BibleTime when --help is used.
41  \param[in] executable The executed file name (argv[0]).
42 */
43 void printHelp(const QString &executable) {
44  std::cout << qPrintable(executable) << std::endl << std::endl
45  << " --help, -h" << std::endl << " "
46  << qPrintable(QObject::tr("Show this help message and exit"))
47  << std::endl << std::endl
48  << " --version, -V" << std::endl << " "
49  << qPrintable(QObject::tr("Output BibleTime version and exit"))
50  << std::endl << std::endl
51  << " --ignore-session" << std::endl << " "
52  << qPrintable(QObject::tr("Open a clean session"))
53  << std::endl << std::endl
54  << " --open-default-bible <ref>" << std::endl << " "
55  << qPrintable(QObject::tr("Open the default Bible with the "
56  "reference <ref>"))
57  << std::endl << std::endl
58  << qPrintable(QObject::tr("For command-line arguments parsed by the"
59  " Qt toolkit, see %1.")
60  .arg("http://doc.qt.nokia.com/latest/qapplication.html"))
61  << std::endl;
62 }
63 
64 /*******************************************************************************
65  Parsing command-line arguments
66 *******************************************************************************/
67 
68 /**
69  Parses all command-line arguments.
70  \param[out] ignoreSession Whether --ignore-session was specified.
71  \param[out] openBibleKey Will be set to --open-default-bible if specified.
72  \retval -1 Parsing was successful, the application should exit with
73  EXIT_SUCCESS.
74  \retval 0 Parsing was successful.
75  \retval 1 Parsing failed, the application should exit with EXIT_FAILURE.
76 */
77 int parseCommandLine(bool & showDebugMessages,
78  bool & ignoreSession,
79  QString & openBibleKey)
80 {
81  QStringList args = BibleTimeApp::arguments();
82  for (int i = 1; i < args.size(); i++) {
83  const QString &arg = args.at(i);
84  if (arg == QStringLiteral("--help")
85  || arg == QStringLiteral("-h")
86  || arg == QStringLiteral("/?")
87  || arg == QStringLiteral("/h"))
88  {
89  printHelp(args.at(0));
90  return -1;
91  } else if (arg == QStringLiteral("--version")
92  || arg == QStringLiteral("-V")
93  || arg == QStringLiteral("/V"))
94  {
95  std::cout << "BibleTime " BT_VERSION << std::endl;
96  return -1;
97  } else if (arg == QStringLiteral("--debug")) {
98  showDebugMessages = true;
99  } else if (arg == QStringLiteral("--ignore-session")) {
100  ignoreSession = true;
101  } else if (arg == QStringLiteral("--open-default-bible")) {
102  i++;
103  if (i < args.size()) {
104  openBibleKey = args.at(i);
105  } else {
106  std::cerr
107  << qPrintable(
108  QObject::tr("Error: %1 expects an argument. See "
109  "--help for details.")
110  .arg(QStringLiteral("--open-default-bible")))
111  << std::endl;
112  return 1;
113  }
114  } else {
115  std::cerr << qPrintable(QObject::tr(
116  "Error: Invalid command-line argument: %1")
117  .arg(arg)) << std::endl;
118  return 1;
119  }
120  }
121  return 0;
122 }
123 
124 /*******************************************************************************
125  Handle Qt's meta type system.
126 *******************************************************************************/
127 
129  qRegisterMetaType<FilterOptions>("FilterOptions");
130  qRegisterMetaType<DisplayOptions>("DisplayOptions");
131  qRegisterMetaType<alignmentMode>("alignmentMode");
132  qRegisterMetaType<CSwordModuleSearch::SearchType>("SearchType");
133  qRegisterMetaType<BtConfig::StringMap>("StringMap");
134  qRegisterMetaType<QList<int> >("QList<int>");
135  qRegisterMetaType<BtBookshelfTreeModel::Grouping>(
136  "BtBookshelfTreeModel::Grouping");
137 
138 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
139  qRegisterMetaTypeStreamOperators<BtBookshelfTreeModel::Grouping>(
140  "BtBookshelfTreeModel::Grouping");
141  qRegisterMetaTypeStreamOperators<alignmentMode>("alignmentMode");
142  qRegisterMetaTypeStreamOperators<CSwordModuleSearch::SearchType>(
143  "SearchType");
144  qRegisterMetaTypeStreamOperators<BtConfig::StringMap>("StringMap");
145  qRegisterMetaTypeStreamOperators<QList<int> >("QList<int>");
146 #endif
147 
149  qmlRegisterSingletonType<BtQmlInterface>(
150  "BibleTime",
151  1,
152  0,
153  "BtQmlInterface",
154  [](QQmlEngine *, QJSEngine *) { return new BtQmlInterface(); });
155 }
156 
157 } // anonymous namespace
158 
159 
160 /*******************************************************************************
161  Program main entry point.
162 *******************************************************************************/
163 
164 int main(int argc, char* argv[]) {
165  namespace DU = util::directory;
166 
167  if (!sword::SWMgr::isICU) {
168  qFatal("SWORD library is required to be built against ICU!");
169  return EXIT_FAILURE;
170  }
171 
173 
174  BibleTimeApp app(argc, argv); //for QApplication
175 
176  // Parse command line arguments:
177  bool ignoreSession = false;
178  QString openBibleKey;
179  {
180  bool showDebugMessages = false;
181  if (int const r = parseCommandLine(showDebugMessages,
182  ignoreSession,
183  openBibleKey))
184  return r < 0 ? EXIT_SUCCESS : EXIT_FAILURE;
185  app.setDebugMode(showDebugMessages);
186  }
187 
188  if (!DU::initDirectoryCache()) {
189  qFatal("Error initializing directory cache!");
190  return EXIT_FAILURE;
191  }
192 
193  app.startInit();
194  if (!app.initBtConfig()) {
195  return EXIT_FAILURE;
196  }
197 
198  app.initLightDarkPalette();
199 
200 #ifdef Q_OS_WIN
201  // change directory to the Sword or .sword directory in the $HOME dir so that
202  // the sword.conf is found. It points to the sword/locales.d directory
203  QString homeSwordDir = util::directory::getUserHomeDir().absolutePath();
204  QDir dir;
205  dir.setCurrent(homeSwordDir);
206 #endif
207 
208 #ifdef Q_OS_MAC
209  // change to the user's sword dir containing the sword.conf config file, so that
210  // Sword will correctly find it.
211  QString homeSwordDir = util::directory::getUserHomeSwordDir().absolutePath();
212  QDir dir;
213  dir.setCurrent(homeSwordDir);
214 #endif
215 
216  //first install QT's own translations
217  QLocale const defaultLocale;
218  QTranslator qtTranslator;
219  if (qtTranslator.load(defaultLocale,
220  QStringLiteral("qt_"),
221  QString(),
222  #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
223  QLibraryInfo::location(
224  #else
225  QLibraryInfo::path(
226  #endif
227  QLibraryInfo::TranslationsPath)))
228  app.installTranslator(&qtTranslator);
229  //then our own
230  QTranslator bibleTimeTranslator;
231  if (bibleTimeTranslator.load(
232  defaultLocale,
233  QStringLiteral("bibletime_ui_"),
234  QString(),
235  DU::getLocaleDir().canonicalPath()))
236  app.installTranslator(&bibleTimeTranslator);
237 
238  // Initialize display template manager:
239  if (!app.initDisplayTemplateManager()) {
240  qFatal("Error initializing display template manager!");
241  return EXIT_FAILURE;
242  }
243 
244  app.initIcons();
245 
246  auto * const mainWindow = new BibleTime(app);
247  mainWindow->setAttribute(Qt::WA_DeleteOnClose);
248 
249  // a new BibleTime version was installed (maybe a completely new installation)
250  if (btConfig().value<QString>(QStringLiteral("bibletimeVersion"),
251  BT_VERSION) != BT_VERSION)
252  {
253  btConfig().setValue(QStringLiteral("bibletimeVersion"),
254  QString(BT_VERSION));
255  mainWindow->saveConfigSettings();
256  }
257 
258  auto const showWelcome = CSwordBackend::instance().moduleList().empty();
259  if (showWelcome && BtWelcomeDialog().exec() == QDialog::Accepted)
260  mainWindow->slotBookshelfWizard();
261 
262  mainWindow->show();
263 
264  // The following must be done after the bibletime window is visible:
265  mainWindow->processCommandline(ignoreSession, openBibleKey);
266 
267  if (!showWelcome
268  && btConfig().value<bool>(QStringLiteral("GUI/showTipAtStartup"), true))
269  mainWindow->slotOpenTipDialog();
270 
271  return app.exec();
272 }
273 
BtConfig & btConfig()
This is a shortchand for BtConfig::getInstance().
Definition: btconfig.h:305
void startInit()
Definition: bibletimeapp.h:38
bool initDisplayTemplateManager()
void setDebugMode(bool const debugMode) noexcept
Definition: bibletimeapp.h:47
void initLightDarkPalette()
bool initBtConfig()
void setValue(QString const &key, T const &value)
Sets a value for a key.
Definition: btconfigcore.h:73
static int typeId
QList< CSwordModuleInfo * > const & moduleList() const
static CSwordBackend & instance() noexcept
Definition: cswordbackend.h:98
if(plainSearchedText)
QStringList r(content.left(bodyIndex))
int main(int argc, char *argv[])
Definition: main.cpp:164
int parseCommandLine(bool &showDebugMessages, bool &ignoreSession, QString &openBibleKey)
Definition: main.cpp:77
void printHelp(const QString &executable)
Definition: main.cpp:43
const QDir & getLocaleDir()
Definition: directory.cpp:283
const QDir & getUserHomeSwordDir()
Definition: directory.cpp:342
const QDir & getUserHomeDir()
Definition: directory.cpp:338
bool initDirectoryCache()
Initializes the directory cache and returns whether it was successful.
Definition: directory.cpp:67