~adamreichold/qpdfview/trunk

360 by Adam Reichold
manual merge of future branch
1
/*
2
2066 by Adam Reichold
Also try to load application translations from embedded resources to facilitate single binary builds.
3
Copyright 2018 Marshall Banana
4
Copyright 2012-2013, 2018 Adam Reichold
1501 by Adam Reichold
Fix inconsistency when using '--unique' to the start the first instance.
5
Copyright 2014 Dorian Scholz
755 by Adam Reichold
Merged named instances by Michal Trybus with small changes:
6
Copyright 2012 MichaƂ Trybus
1308.1.2 by Adam Reichold
update copyright notice and contributors list
7
Copyright 2013 Chris Young
360 by Adam Reichold
manual merge of future branch
8
9
This file is part of qpdfview.
10
11
qpdfview is free software: you can redistribute it and/or modify
12
it under the terms of the GNU General Public License as published by
13
the Free Software Foundation, either version 2 of the License, or
14
(at your option) any later version.
15
16
qpdfview is distributed in the hope that it will be useful,
17
but WITHOUT ANY WARRANTY; without even the implied warranty of
18
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
GNU General Public License for more details.
20
21
You should have received a copy of the GNU General Public License
22
along with qpdfview.  If not, see <http://www.gnu.org/licenses/>.
23
24
*/
25
1097.1.2 by Adam Reichold
prepare '--help' command-line option
26
#include <iostream>
27
815 by Adam Reichold
finished simplifying header handling
28
#include <QApplication>
29
#include <QDebug>
30
#include <QDir>
1337 by Adam Reichold
move user interaction code out of the database class
31
#include <QInputDialog>
1263 by Adam Reichold
actually load Qt's translations so that its dialog etc. are translated as well
32
#include <QLibraryInfo>
846 by Adam Reichold
added plug-in infrastructure
33
#include <QMessageBox>
1046.1.62 by Adam Reichold
and use QScopedPointer in main as well
34
#include <QScopedPointer>
815 by Adam Reichold
finished simplifying header handling
35
#include <QTranslator>
36
37
#ifdef WITH_DBUS
38
39
#include <QDBusInterface>
40
#include <QDBusReply>
41
42
#endif // WITH_DBUS
43
793.1.1 by Alexander Volkov
reduce header interdependence
44
#ifdef WITH_SYNCTEX
45
46
#include <synctex_parser.h>
47
2070 by Adam Reichold
Adapt for compatibility with SyncTeX parser version 1.19 and later.
48
#ifndef HAS_SYNCTEX_2
49
50
typedef synctex_scanner_t synctex_scanner_p;
51
typedef synctex_node_t synctex_node_p;
52
53
#define synctex_scanner_next_result(scanner) synctex_next_result(scanner)
54
#define synctex_display_query(scanner, file, line, column, page) synctex_display_query(scanner, file, line, column)
55
56
#endif // HAS_SYNCTEX_2
57
793.1.1 by Alexander Volkov
reduce header interdependence
58
#endif // WITH_SYNCTEX
59
846 by Adam Reichold
added plug-in infrastructure
60
#include "documentview.h"
1241.1.2 by Adam Reichold
actually replace all database access in main window by calls to or signals from database singleton
61
#include "database.h"
1046.1.23 by Adam Reichold
minor code cleaning
62
#include "mainwindow.h"
846 by Adam Reichold
added plug-in infrastructure
63
833 by Adam Reichold
added support for handling UNIX signals
64
#ifdef WITH_SIGNALS
65
66
#include "signalhandler.h"
67
68
#endif // WITH_SIGNALS
69
1308.1.1 by Adam Reichold
adjust command-line handling for AmigaOS 4
70
#ifdef __amigaos4__
71
72
#include <proto/dos.h>
73
#include <workbench/startup.h>
74
75
const char* __attribute__((used)) stack_cookie = "\0$STACK:500000\0";
76
77
#endif // __amigaos4__
78
1520 by Adam Reichold
Make use of anonymous namespace for application entry.
79
namespace
80
{
81
1518 by Adam Reichold
Make proper use of application and anonymous namespaces and fix a few header guards.
82
using namespace qpdfview;
83
373 by Adam Reichold
minor cleanups
84
struct File
85
{
86
    QString filePath;
87
    int page;
447 by Adam Reichold
version bump
88
588 by Adam Reichold
add SyncTeX support
89
    QString sourceName;
90
    int sourceLine;
91
    int sourceColumn;
92
    QRectF enclosingBox;
93
684 by Adam Reichold
initialize page to minus one to prevent jumping to page one even though this was not requested by the user
94
    File() : filePath(), page(-1), sourceName(), sourceLine(-1), sourceColumn(-1), enclosingBox() {}
447 by Adam Reichold
version bump
95
373 by Adam Reichold
minor cleanups
96
};
97
1326 by Adam Reichold
add a useful enumeration of exit codes to indicate exit status
98
enum ExitStatus
99
{
100
    ExitOk = 0,
101
    ExitUnknownArgument = 1,
102
    ExitIllegalArgument = 2,
103
    ExitInconsistentArguments = 3,
104
    ExitDBusError = 4
105
};
106
1520 by Adam Reichold
Make use of anonymous namespace for application entry.
107
bool unique = false;
108
bool quiet = false;
109
110
QString instanceName;
111
QString searchText;
112
113
QList< File > files;
114
115
MainWindow* mainWindow = 0;
116
2065 by Adam Reichold
Refactor loading of translators to simplify Qt version handling.
117
bool loadTranslator(QTranslator* const translator, const QString& fileName, const QString& path)
118
{
119
#if QT_VERSION >= QT_VERSION_CHECK(4,8,0)
120
121
    const bool ok = translator->load(QLocale::system(), fileName, "_", path);
122
123
#else
124
125
    const bool ok = translator->load(fileName + "_" + QLocale::system().name(), path);
126
127
#endif // QT_VERSION
128
129
    if(ok)
130
    {
131
        qApp->installTranslator(translator);
132
    }
133
134
    return ok;
135
}
136
1520 by Adam Reichold
Make use of anonymous namespace for application entry.
137
void loadTranslators()
1327 by Adam Reichold
refactor out loading of translation from main function as well
138
{
1520 by Adam Reichold
Make use of anonymous namespace for application entry.
139
    QTranslator* toolkitTranslator = new QTranslator(qApp);
2065 by Adam Reichold
Refactor loading of translators to simplify Qt version handling.
140
    loadTranslator(toolkitTranslator, "qt", QLibraryInfo::location(QLibraryInfo::TranslationsPath));
141
1520 by Adam Reichold
Make use of anonymous namespace for application entry.
142
    QTranslator* applicationTranslator = new QTranslator(qApp);
2098 by Adam Reichold
Make the data subdirectory in the application directory compile-time-configurable as it has a special meaning on Mac OS X and must be ../Resources instead of data.
143
    if(loadTranslator(applicationTranslator, "qpdfview", QDir(QApplication::applicationDirPath()).filePath(APP_DIR_DATA_PATH))) {}
2065 by Adam Reichold
Refactor loading of translators to simplify Qt version handling.
144
    else if(loadTranslator(applicationTranslator, "qpdfview", DATA_INSTALL_PATH)) {}
2066 by Adam Reichold
Also try to load application translations from embedded resources to facilitate single binary builds.
145
    else if(loadTranslator(applicationTranslator, "qpdfview", ":/")) {}
1327 by Adam Reichold
refactor out loading of translation from main function as well
146
}
147
1520 by Adam Reichold
Make use of anonymous namespace for application entry.
148
void parseCommandLineArguments()
360 by Adam Reichold
manual merge of future branch
149
{
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
150
    bool instanceNameIsNext = false;
151
    bool searchTextIsNext = false;
152
    bool noMoreOptions = false;
153
154
    QRegExp fileAndPageRegExp("(.+)#(\\d+)");
155
    QRegExp fileAndSourceRegExp("(.+)#src:(.+):(\\d+):(\\d+)");
156
    QRegExp instanceNameRegExp("[A-Za-z_]+[A-Za-z0-9_]*");
157
158
    QStringList arguments = QApplication::arguments();
159
160
    if(!arguments.isEmpty())
161
    {
162
        arguments.removeFirst();
163
    }
164
165
    foreach(const QString& argument, arguments)
166
    {
167
        if(instanceNameIsNext)
168
        {
169
            if(argument.isEmpty())
170
            {
171
                qCritical() << QObject::tr("An empty instance name is not allowed.");
1326 by Adam Reichold
add a useful enumeration of exit codes to indicate exit status
172
                exit(ExitIllegalArgument);
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
173
            }
174
175
            instanceNameIsNext = false;
1333 by Adam Reichold
removing 'instanceName' was a mistake as it did make the code less clear
176
            instanceName = argument;
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
177
        }
178
        else if(searchTextIsNext)
179
        {
180
            if(argument.isEmpty())
181
            {
182
                qCritical() << QObject::tr("An empty search text is not allowed.");
1326 by Adam Reichold
add a useful enumeration of exit codes to indicate exit status
183
                exit(ExitIllegalArgument);
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
184
            }
185
186
            searchTextIsNext = false;
187
            searchText = argument;
188
        }
189
        else if(!noMoreOptions && argument.startsWith("--"))
190
        {
191
            if(argument == QLatin1String("--unique"))
192
            {
193
                unique = true;
194
            }
195
            else if(argument == QLatin1String("--quiet"))
196
            {
197
                quiet = true;
198
            }
199
            else if(argument == QLatin1String("--instance"))
200
            {
201
                instanceNameIsNext = true;
202
            }
203
            else if(argument == QLatin1String("--search"))
204
            {
205
                searchTextIsNext = true;
206
            }
207
            else if(argument == QLatin1String("--choose-instance"))
208
            {
1337 by Adam Reichold
move user interaction code out of the database class
209
                bool ok = false;
1999 by Adam Reichold
Add context menu option to move document to different instance after small refactoring of D-Bus handling.
210
                const QString chosenInstanceName = QInputDialog::getItem(0, MainWindow::tr("Choose instance"), MainWindow::tr("Instance:"), Database::instance()->knownInstanceNames(), 0, true, &ok);
1337 by Adam Reichold
move user interaction code out of the database class
211
212
                if(ok)
213
                {
214
                    instanceName = chosenInstanceName;
215
                }
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
216
            }
217
            else if(argument == QLatin1String("--help"))
218
            {
219
                std::cout << "Usage: qpdfview [options] [--] [file[#page]] [file[#src:name:line:column]] ..." << std::endl
220
                          << std::endl
221
                          << "Available options:" << std::endl
222
                          << "  --help                      Show this information" << std::endl
223
                          << "  --quiet                     Suppress warning messages when opening files" << std::endl
224
                          << "  --search text               Search for text in the current tab" << std::endl
225
                          << "  --unique                    Open files as tabs in unique window" << std::endl
226
                          << "  --unique --instance name    Open files as tabs in named instance" << std::endl
227
                          << "  --unique --choose-instance  Open files as tabs after choosing an instance name" << std::endl
228
                          << std::endl
229
                          << "Please report bugs at \"https://launchpad.net/qpdfview\"." << std::endl;
230
1326 by Adam Reichold
add a useful enumeration of exit codes to indicate exit status
231
                exit(ExitOk);
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
232
            }
233
            else if(argument == QLatin1String("--"))
234
            {
235
                noMoreOptions = true;
236
            }
237
            else
238
            {
239
                qCritical() << QObject::tr("Unknown command-line option '%1'.").arg(argument);
1326 by Adam Reichold
add a useful enumeration of exit codes to indicate exit status
240
                exit(ExitUnknownArgument);
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
241
            }
242
        }
243
        else
244
        {
245
            File file;
246
247
            if(fileAndPageRegExp.exactMatch(argument))
248
            {
249
                file.filePath = fileAndPageRegExp.cap(1);
250
                file.page = fileAndPageRegExp.cap(2).toInt();
251
            }
252
            else if(fileAndSourceRegExp.exactMatch(argument))
253
            {
254
                file.filePath = fileAndSourceRegExp.cap(1);
255
                file.sourceName = fileAndSourceRegExp.cap(2);
256
                file.sourceLine = fileAndSourceRegExp.cap(3).toInt();
257
                file.sourceColumn = fileAndSourceRegExp.cap(4).toInt();
258
            }
259
            else
260
            {
261
                file.filePath = argument;
262
            }
263
264
            files.append(file);
265
        }
266
    }
267
268
    if(instanceNameIsNext)
269
    {
270
        qCritical() << QObject::tr("Using '--instance' requires an instance name.");
1326 by Adam Reichold
add a useful enumeration of exit codes to indicate exit status
271
        exit(ExitInconsistentArguments);
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
272
    }
273
1333 by Adam Reichold
removing 'instanceName' was a mistake as it did make the code less clear
274
    if(!unique && !instanceName.isEmpty())
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
275
    {
276
        qCritical() << QObject::tr("Using '--instance' is not allowed without using '--unique'.");
1326 by Adam Reichold
add a useful enumeration of exit codes to indicate exit status
277
        exit(ExitInconsistentArguments);
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
278
    }
279
1333 by Adam Reichold
removing 'instanceName' was a mistake as it did make the code less clear
280
    if(!instanceName.isEmpty() && !instanceNameRegExp.exactMatch(instanceName))
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
281
    {
282
        qCritical() << QObject::tr("An instance name must only contain the characters \"[A-Z][a-z][0-9]_\" and must not begin with a digit.");
1326 by Adam Reichold
add a useful enumeration of exit codes to indicate exit status
283
        exit(ExitIllegalArgument);
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
284
    }
285
286
    if(searchTextIsNext)
287
    {
288
        qCritical() << QObject::tr("Using '--search' requires a search text.");
1326 by Adam Reichold
add a useful enumeration of exit codes to indicate exit status
289
        exit(ExitInconsistentArguments);
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
290
    }
291
}
583 by Adam Reichold
register meta types only once
292
1520 by Adam Reichold
Make use of anonymous namespace for application entry.
293
void parseWorkbenchExtendedSelection(int argc, char** argv)
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
294
{
1328 by Adam Reichold
go for the empty body pattern on AmigaOS as well and fix a missing semicolon
295
#ifdef __amigaos4__
296
1308.1.5 by Adam Reichold
move the processing of the Workbench extended selection before QApplication's constructor as it will trash the argv pointer
297
    if(argc == 0)
298
    {
299
        const int pathLength = 1024;
300
        const QScopedArrayPointer< char > filePath(new char[pathLength]);
301
302
        const struct WBStartup* wbStartup = reinterpret_cast< struct WBStartup* >(argv);
303
1308.1.6 by Adam Reichold
minimally improve variable naming
304
        for(int index = 1; index < wbStartup->sm_NumArgs; ++index)
1308.1.5 by Adam Reichold
move the processing of the Workbench extended selection before QApplication's constructor as it will trash the argv pointer
305
        {
1308.1.6 by Adam Reichold
minimally improve variable naming
306
            const struct WBArg* wbArg = wbStartup->sm_ArgList + index;
1308.1.5 by Adam Reichold
move the processing of the Workbench extended selection before QApplication's constructor as it will trash the argv pointer
307
308
            if((wbArg->wa_Lock) && (*wbArg->wa_Name))
309
            {
310
                IDOS->DevNameFromLock(wbArg->wa_Lock, filePath.data(), pathLength, DN_FULLPATH);
311
                IDOS->AddPart(filePath.data(), wbArg->wa_Name, pathLength);
312
313
                File file;
314
                file.filePath = filePath.data();
315
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
316
                files.append(file);
317
            }
318
        }
319
    }
1328 by Adam Reichold
go for the empty body pattern on AmigaOS as well and fix a missing semicolon
320
321
#else
322
323
    Q_UNUSED(argc);
324
    Q_UNUSED(argv);
325
326
#endif // __amigaos4__
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
327
}
328
1520 by Adam Reichold
Make use of anonymous namespace for application entry.
329
void resolveSourceReferences()
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
330
{
331
#ifdef WITH_SYNCTEX
332
333
    for(int index = 0; index < files.count(); ++index)
334
    {
335
        File& file = files[index];
336
337
        if(!file.sourceName.isNull())
338
        {
2070 by Adam Reichold
Adapt for compatibility with SyncTeX parser version 1.19 and later.
339
            if(synctex_scanner_p scanner = synctex_scanner_new_with_output_file(file.filePath.toLocal8Bit(), 0, 1))
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
340
            {
2070 by Adam Reichold
Adapt for compatibility with SyncTeX parser version 1.19 and later.
341
                if(synctex_display_query(scanner, file.sourceName.toLocal8Bit(), file.sourceLine, file.sourceColumn, -1) > 0)
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
342
                {
2070 by Adam Reichold
Adapt for compatibility with SyncTeX parser version 1.19 and later.
343
                    for(synctex_node_p node = synctex_scanner_next_result(scanner); node != 0; node = synctex_scanner_next_result(scanner))
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
344
                    {
345
                        int page = synctex_node_page(node);
346
                        QRectF enclosingBox(synctex_node_box_visible_h(node), synctex_node_box_visible_v(node), synctex_node_box_visible_width(node), synctex_node_box_visible_height(node));
347
348
                        if(file.page != page)
349
                        {
350
                            file.page = page;
351
                            file.enclosingBox = enclosingBox;
352
                        }
353
                        else
354
                        {
355
                            file.enclosingBox = file.enclosingBox.united(enclosingBox);
356
                        }
357
                    }
358
                }
359
360
                synctex_scanner_free(scanner);
361
            }
362
            else
363
            {
1999 by Adam Reichold
Add context menu option to move document to different instance after small refactoring of D-Bus handling.
364
                qWarning() << DocumentView::tr("SyncTeX data for '%1' could not be found.").arg(file.filePath);
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
365
            }
366
        }
367
    }
368
369
#endif // WITH_SYNCTEX
370
}
371
1520 by Adam Reichold
Make use of anonymous namespace for application entry.
372
void activateUniqueInstance()
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
373
{
1333 by Adam Reichold
removing 'instanceName' was a mistake as it did make the code less clear
374
    qApp->setObjectName(instanceName);
375
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
376
#ifdef WITH_DBUS
377
378
    if(unique)
379
    {
1999 by Adam Reichold
Add context menu option to move document to different instance after small refactoring of D-Bus handling.
380
        QScopedPointer< QDBusInterface > interface(MainWindowAdaptor::createInterface());
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
381
382
        if(interface->isValid())
383
        {
384
            interface->call("raiseAndActivate");
385
386
            foreach(const File& file, files)
387
            {
388
                QDBusReply< bool > reply = interface->call("jumpToPageOrOpenInNewTab", QFileInfo(file.filePath).absoluteFilePath(), file.page, true, file.enclosingBox, quiet);
389
390
                if(!reply.isValid())
391
                {
392
                    qCritical() << QDBusConnection::sessionBus().lastError().message();
393
1326 by Adam Reichold
add a useful enumeration of exit codes to indicate exit status
394
                    exit(ExitDBusError);
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
395
                }
396
            }
397
1990 by Adam Reichold
Also immediately save the database if files were opened on start-up so that choosing an instance will possible immediately.
398
            if(!files.isEmpty())
399
            {
400
                interface->call("saveDatabase");
401
            }
402
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
403
            if(!searchText.isEmpty())
404
            {
405
                interface->call("startSearch", searchText);
406
            }
407
1326 by Adam Reichold
add a useful enumeration of exit codes to indicate exit status
408
            exit(ExitOk);
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
409
        }
410
        else
411
        {
412
            mainWindow = new MainWindow();
413
1999 by Adam Reichold
Add context menu option to move document to different instance after small refactoring of D-Bus handling.
414
            if(MainWindowAdaptor::createAdaptor(mainWindow) == 0)
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
415
            {
416
                qCritical() << QDBusConnection::sessionBus().lastError().message();
417
418
                delete mainWindow;
1326 by Adam Reichold
add a useful enumeration of exit codes to indicate exit status
419
                exit(ExitDBusError);
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
420
            }
421
        }
422
    }
423
    else
424
    {
425
        mainWindow = new MainWindow();
426
    }
427
428
#else
429
430
    mainWindow = new MainWindow();
431
432
#endif // WITH_DBUS
433
}
434
1520 by Adam Reichold
Make use of anonymous namespace for application entry.
435
void prepareSignalHandler()
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
436
{
437
#ifdef WITH_SIGNALS
438
439
    if(SignalHandler::prepareSignals())
440
    {
441
        SignalHandler* signalHandler = new SignalHandler(mainWindow);
442
443
        QObject::connect(signalHandler, SIGNAL(sigIntReceived()), mainWindow, SLOT(close()));
444
        QObject::connect(signalHandler, SIGNAL(sigTermReceived()), mainWindow, SLOT(close()));
445
    }
446
    else
447
    {
448
        qWarning() << QObject::tr("Could not prepare signal handler.");
449
    }
450
451
#endif // WITH_SIGNALS
452
}
453
1520 by Adam Reichold
Make use of anonymous namespace for application entry.
454
} // anonymous
455
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
456
int main(int argc, char** argv)
457
{
458
    qRegisterMetaType< QList< QRectF > >("QList<QRectF>");
459
    qRegisterMetaType< Rotation >("Rotation");
1594 by Adam Reichold
Slightly shorted variable names and centrally adjust resolutions for scale and rotation.
460
    qRegisterMetaType< RenderParam >("RenderParam");
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
461
1328 by Adam Reichold
go for the empty body pattern on AmigaOS as well and fix a missing semicolon
462
    parseWorkbenchExtendedSelection(argc, argv);
1308.1.5 by Adam Reichold
move the processing of the Workbench extended selection before QApplication's constructor as it will trash the argv pointer
463
360 by Adam Reichold
manual merge of future branch
464
    QApplication application(argc, argv);
465
755 by Adam Reichold
Merged named instances by Michal Trybus with small changes:
466
    QApplication::setOrganizationDomain("local.qpdfview");
360 by Adam Reichold
manual merge of future branch
467
    QApplication::setOrganizationName("qpdfview");
468
    QApplication::setApplicationName("qpdfview");
469
974 by Adam Reichold
updated information about application capabilities in the documentation
470
    QApplication::setApplicationVersion(APPLICATION_VERSION);
361 by Adam Reichold
updated documentation
471
1986 by Adam Reichold
Use resource aliases to make the source references to icons format-independent, i.e. remove the svg suffix.
472
    QApplication::setWindowIcon(QIcon(":icons/qpdfview"));
360 by Adam Reichold
manual merge of future branch
473
2089 by Adam Reichold
Enable high-DPI pixmaps for icons when using Qt 5.
474
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
475
476
    QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
477
478
#endif // QT_VERSION
479
1327 by Adam Reichold
refactor out loading of translation from main function as well
480
    loadTranslators();
611 by Adam Reichold
make loading of translations compatible with older Qt versions again
481
1325 by Adam Reichold
reorganize sprawling main function using static variables and helper functions
482
    parseCommandLineArguments();
483
484
    resolveSourceReferences();
485
486
    activateUniqueInstance();
487
488
    prepareSignalHandler();
833 by Adam Reichold
added support for handling UNIX signals
489
360 by Adam Reichold
manual merge of future branch
490
    mainWindow->show();
491
    mainWindow->setAttribute(Qt::WA_DeleteOnClose);
492
1147 by Adam Reichold
begin to make local variables immutable by default
493
    foreach(const File& file, files)
360 by Adam Reichold
manual merge of future branch
494
    {
1501 by Adam Reichold
Fix inconsistency when using '--unique' to the start the first instance.
495
        mainWindow->jumpToPageOrOpenInNewTab(file.filePath, file.page, true, file.enclosingBox, quiet);
360 by Adam Reichold
manual merge of future branch
496
    }
1046.1.21 by Adam Reichold
add '--search' to trigger search in current tab
497
1990 by Adam Reichold
Also immediately save the database if files were opened on start-up so that choosing an instance will possible immediately.
498
    if(!files.isEmpty())
499
    {
500
        mainWindow->saveDatabase();
501
    }
502
1046.1.21 by Adam Reichold
add '--search' to trigger search in current tab
503
    if(!searchText.isEmpty())
504
    {
505
        mainWindow->startSearch(searchText);
506
    }
1501 by Adam Reichold
Fix inconsistency when using '--unique' to the start the first instance.
507
360 by Adam Reichold
manual merge of future branch
508
    return application.exec();
509
}