source: visorpdf/sources/main.cpp @ 8964fdc

Last change on this file since 8964fdc was 8964fdc, checked in by Pedro Buitrago <pbuitrago@…>, 8 years ago

Se realiza las modificaciones para agregar el nombre del proyecto murrupuy y la información sobre el proyecto

  • Property mode set to 100644
File size: 15.0 KB
Line 
1/*
2
3Copyright 2012-2013 Adam Reichold
4Copyright 2014 Dorian Scholz
5Copyright 2012 Michał Trybus
6Copyright 2013 Chris Young
7
8This file is part of qpdfview.
9
10qpdfview is free software: you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation, either version 2 of the License, or
13(at your option) any later version.
14
15qpdfview is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with qpdfview.  If not, see <http://www.gnu.org/licenses/>.
22
23*/
24
25#include <iostream>
26
27#include <QApplication>
28#include <QDebug>
29#include <QDir>
30#include <QInputDialog>
31#include <QLibraryInfo>
32#include <QMessageBox>
33#include <QScopedPointer>
34#include <QTranslator>
35
36#ifdef WITH_DBUS
37
38#include <QDBusInterface>
39#include <QDBusReply>
40
41#endif // WITH_DBUS
42
43#ifdef WITH_SYNCTEX
44
45#include <synctex_parser.h>
46
47#endif // WITH_SYNCTEX
48
49#include "renderparam.h"
50#include "documentview.h"
51#include "database.h"
52#include "mainwindow.h"
53
54#ifdef WITH_SIGNALS
55
56#include "signalhandler.h"
57
58#endif // WITH_SIGNALS
59
60#ifdef __amigaos4__
61
62#include <proto/dos.h>
63#include <workbench/startup.h>
64
65const char* __attribute__((used)) stack_cookie = "\0$STACK:500000\0";
66
67#endif // __amigaos4__
68
69namespace
70{
71
72using namespace qpdfview;
73
74struct File
75{
76    QString filePath;
77    int page;
78
79    QString sourceName;
80    int sourceLine;
81    int sourceColumn;
82    QRectF enclosingBox;
83
84    File() : filePath(), page(-1), sourceName(), sourceLine(-1), sourceColumn(-1), enclosingBox() {}
85
86};
87
88enum ExitStatus
89{
90    ExitOk = 0,
91    ExitUnknownArgument = 1,
92    ExitIllegalArgument = 2,
93    ExitInconsistentArguments = 3,
94    ExitDBusError = 4
95};
96
97bool unique = false;
98bool quiet = false;
99
100QString instanceName;
101QString searchText;
102
103QList< File > files;
104
105MainWindow* mainWindow = 0;
106
107void loadTranslators()
108{
109    QTranslator* toolkitTranslator = new QTranslator(qApp);
110    QTranslator* applicationTranslator = new QTranslator(qApp);
111
112#if QT_VERSION >= QT_VERSION_CHECK(4,8,0)
113
114    if(toolkitTranslator->load(QLocale::system(), "qt", "_", QLibraryInfo::location(QLibraryInfo::TranslationsPath))) { qApp->installTranslator(toolkitTranslator); }
115
116    if(applicationTranslator->load(QLocale::system(), "murrupuy", "_", QDir(QApplication::applicationDirPath()).filePath("data"))) { qApp->installTranslator(applicationTranslator); }
117    else if(applicationTranslator->load(QLocale::system(), "murrupuy", "_", DATA_INSTALL_PATH)) { qApp->installTranslator(applicationTranslator); }
118    //if(applicationTranslator->load(QLocale::system(), "TibisayPDFView", "_", QDir(QApplication::applicationDirPath()).filePath("data"))) { qApp->installTranslator(applicationTranslator); }
119    //else if(applicationTranslator->load(QLocale::system(), "TibisayPDFView", "_", DATA_INSTALL_PATH)) { qApp->installTranslator(applicationTranslator); }
120
121#else
122
123    if(toolkitTranslator->load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath))) { qApp->installTranslator(toolkitTranslator); }
124
125    if(applicationTranslator->load("murrupuy" + QLocale::system().name(), QDir(QApplication::applicationDirPath()).filePath("data"))) { qApp->installTranslator(applicationTranslator); }
126    else if(applicationTranslator->load("murrupuy_" + QLocale::system().name(), DATA_INSTALL_PATH)) { qApp->installTranslator(applicationTranslator); }
127//    if(applicationTranslator->load("TibisayPDFView_" + QLocale::system().name(), QDir(QApplication::applicationDirPath()).filePath("data"))) { qApp->installTranslator(applicationTranslator); }
128//    else if(applicationTranslator->load("TibisayPDFView_" + QLocale::system().name(), DATA_INSTALL_PATH)) { qApp->installTranslator(applicationTranslator); }
129#endif // QT_VERSION
130}
131
132void parseCommandLineArguments()
133{
134    bool instanceNameIsNext = false;
135    bool searchTextIsNext = false;
136    bool noMoreOptions = false;
137
138    QRegExp fileAndPageRegExp("(.+)#(\\d+)");
139    QRegExp fileAndSourceRegExp("(.+)#src:(.+):(\\d+):(\\d+)");
140    QRegExp instanceNameRegExp("[A-Za-z_]+[A-Za-z0-9_]*");
141
142    QStringList arguments = QApplication::arguments();
143
144    if(!arguments.isEmpty())
145    {
146        arguments.removeFirst();
147    }
148
149    foreach(const QString& argument, arguments)
150    {
151        if(instanceNameIsNext)
152        {
153            if(argument.isEmpty())
154            {
155                qCritical() << QObject::tr("An empty instance name is not allowed.");
156                exit(ExitIllegalArgument);
157            }
158
159            instanceNameIsNext = false;
160            instanceName = argument;
161        }
162        else if(searchTextIsNext)
163        {
164            if(argument.isEmpty())
165            {
166                qCritical() << QObject::tr("An empty search text is not allowed.");
167                exit(ExitIllegalArgument);
168            }
169
170            searchTextIsNext = false;
171            searchText = argument;
172        }
173        else if(!noMoreOptions && argument.startsWith("--"))
174        {
175            if(argument == QLatin1String("--unique"))
176            {
177                unique = true;
178            }
179            else if(argument == QLatin1String("--quiet"))
180            {
181                quiet = true;
182            }
183            else if(argument == QLatin1String("--instance"))
184            {
185                instanceNameIsNext = true;
186            }
187            else if(argument == QLatin1String("--search"))
188            {
189                searchTextIsNext = true;
190            }
191            else if(argument == QLatin1String("--choose-instance"))
192            {
193                bool ok = false;
194                const QString chosenInstanceName = QInputDialog::getItem(0, QObject::tr("Choose instance"), QObject::tr("Instance:"), Database::instance()->loadInstanceNames(), 0, true, &ok);
195
196                if(ok)
197                {
198                    instanceName = chosenInstanceName;
199                }
200            }
201            else if(argument == QLatin1String("--help"))
202            {
203                std::cout << "Usage: qpdfview [options] [--] [file[#page]] [file[#src:name:line:column]] ..." << std::endl
204                          << std::endl
205                          << "Available options:" << std::endl
206                          << "  --help                      Show this information" << std::endl
207                          << "  --quiet                     Suppress warning messages when opening files" << std::endl
208                          << "  --search text               Search for text in the current tab" << std::endl
209                          << "  --unique                    Open files as tabs in unique window" << std::endl
210                          << "  --unique --instance name    Open files as tabs in named instance" << std::endl
211                          << "  --unique --choose-instance  Open files as tabs after choosing an instance name" << std::endl
212                          << std::endl
213                          << "Please report bugs at \"https://launchpad.net/qpdfview\"." << std::endl;
214
215                exit(ExitOk);
216            }
217            else if(argument == QLatin1String("--"))
218            {
219                noMoreOptions = true;
220            }
221            else
222            {
223                qCritical() << QObject::tr("Unknown command-line option '%1'.").arg(argument);
224                exit(ExitUnknownArgument);
225            }
226        }
227        else
228        {
229            File file;
230
231            if(fileAndPageRegExp.exactMatch(argument))
232            {
233                file.filePath = fileAndPageRegExp.cap(1);
234                file.page = fileAndPageRegExp.cap(2).toInt();
235            }
236            else if(fileAndSourceRegExp.exactMatch(argument))
237            {
238                file.filePath = fileAndSourceRegExp.cap(1);
239                file.sourceName = fileAndSourceRegExp.cap(2);
240                file.sourceLine = fileAndSourceRegExp.cap(3).toInt();
241                file.sourceColumn = fileAndSourceRegExp.cap(4).toInt();
242            }
243            else
244            {
245                file.filePath = argument;
246            }
247
248            files.append(file);
249        }
250    }
251
252    if(instanceNameIsNext)
253    {
254        qCritical() << QObject::tr("Using '--instance' requires an instance name.");
255        exit(ExitInconsistentArguments);
256    }
257
258    if(!unique && !instanceName.isEmpty())
259    {
260        qCritical() << QObject::tr("Using '--instance' is not allowed without using '--unique'.");
261        exit(ExitInconsistentArguments);
262    }
263
264    if(!instanceName.isEmpty() && !instanceNameRegExp.exactMatch(instanceName))
265    {
266        qCritical() << QObject::tr("An instance name must only contain the characters \"[A-Z][a-z][0-9]_\" and must not begin with a digit.");
267        exit(ExitIllegalArgument);
268    }
269
270    if(searchTextIsNext)
271    {
272        qCritical() << QObject::tr("Using '--search' requires a search text.");
273        exit(ExitInconsistentArguments);
274    }
275}
276
277void parseWorkbenchExtendedSelection(int argc, char** argv)
278{
279#ifdef __amigaos4__
280
281    if(argc == 0)
282    {
283        const int pathLength = 1024;
284        const QScopedArrayPointer< char > filePath(new char[pathLength]);
285
286        const struct WBStartup* wbStartup = reinterpret_cast< struct WBStartup* >(argv);
287
288        for(int index = 1; index < wbStartup->sm_NumArgs; ++index)
289        {
290            const struct WBArg* wbArg = wbStartup->sm_ArgList + index;
291
292            if((wbArg->wa_Lock) && (*wbArg->wa_Name))
293            {
294                IDOS->DevNameFromLock(wbArg->wa_Lock, filePath.data(), pathLength, DN_FULLPATH);
295                IDOS->AddPart(filePath.data(), wbArg->wa_Name, pathLength);
296
297                File file;
298                file.filePath = filePath.data();
299
300                files.append(file);
301            }
302        }
303    }
304
305#else
306
307    Q_UNUSED(argc);
308    Q_UNUSED(argv);
309
310#endif // __amigaos4__
311}
312
313void resolveSourceReferences()
314{
315#ifdef WITH_SYNCTEX
316
317    for(int index = 0; index < files.count(); ++index)
318    {
319        File& file = files[index];
320
321        if(!file.sourceName.isNull())
322        {
323            synctex_scanner_t scanner = synctex_scanner_new_with_output_file(file.filePath.toLocal8Bit(), 0, 1);
324
325            if(scanner != 0)
326            {
327                if(synctex_display_query(scanner, file.sourceName.toLocal8Bit(), file.sourceLine, file.sourceColumn) > 0)
328                {
329                    for(synctex_node_t node = synctex_next_result(scanner); node != 0; node = synctex_next_result(scanner))
330                    {
331                        int page = synctex_node_page(node);
332                        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));
333
334                        if(file.page != page)
335                        {
336                            file.page = page;
337                            file.enclosingBox = enclosingBox;
338                        }
339                        else
340                        {
341                            file.enclosingBox = file.enclosingBox.united(enclosingBox);
342                        }
343                    }
344                }
345
346                synctex_scanner_free(scanner);
347            }
348            else
349            {
350                qWarning() << QObject::tr("SyncTeX data for '%1' could not be found.").arg(file.filePath);
351            }
352        }
353    }
354
355#endif // WITH_SYNCTEX
356}
357
358void activateUniqueInstance()
359{
360    qApp->setObjectName(instanceName);
361
362#ifdef WITH_DBUS
363
364    if(unique)
365    {
366        QString serviceName = QApplication::organizationDomain();
367
368        if(!instanceName.isEmpty())
369        {
370            serviceName.append('.');
371            serviceName.append(instanceName);
372        }
373
374        QScopedPointer< QDBusInterface > interface(new QDBusInterface(serviceName, "/MainWindow", "local.qpdfview.MainWindow", QDBusConnection::sessionBus()));
375
376        if(interface->isValid())
377        {
378            interface->call("raiseAndActivate");
379
380            foreach(const File& file, files)
381            {
382                QDBusReply< bool > reply = interface->call("jumpToPageOrOpenInNewTab", QFileInfo(file.filePath).absoluteFilePath(), file.page, true, file.enclosingBox, quiet);
383
384                if(!reply.isValid())
385                {
386                    qCritical() << QDBusConnection::sessionBus().lastError().message();
387
388                    exit(ExitDBusError);
389                }
390            }
391
392            if(!searchText.isEmpty())
393            {
394                interface->call("startSearch", searchText);
395            }
396
397            exit(ExitOk);
398        }
399        else
400        {
401            mainWindow = new MainWindow();
402
403            new MainWindowAdaptor(mainWindow);
404
405            if(!QDBusConnection::sessionBus().registerService(serviceName))
406            {
407                qCritical() << QDBusConnection::sessionBus().lastError().message();
408
409                delete mainWindow;
410                exit(ExitDBusError);
411            }
412
413            if(!QDBusConnection::sessionBus().registerObject("/MainWindow", mainWindow))
414            {
415                qCritical() << QDBusConnection::sessionBus().lastError().message();
416
417                delete mainWindow;
418                exit(ExitDBusError);
419            }
420        }
421
422        return;
423    }
424    else
425    {
426        mainWindow = new MainWindow();
427    }
428
429#else
430
431    mainWindow = new MainWindow();
432
433#endif // WITH_DBUS
434}
435
436void prepareSignalHandler()
437{
438#ifdef WITH_SIGNALS
439
440    if(SignalHandler::prepareSignals())
441    {
442        SignalHandler* signalHandler = new SignalHandler(mainWindow);
443
444        QObject::connect(signalHandler, SIGNAL(sigIntReceived()), mainWindow, SLOT(close()));
445        QObject::connect(signalHandler, SIGNAL(sigTermReceived()), mainWindow, SLOT(close()));
446    }
447    else
448    {
449        qWarning() << QObject::tr("Could not prepare signal handler.");
450    }
451
452#endif // WITH_SIGNALS
453}
454
455} // anonymous
456
457int main(int argc, char** argv)
458{
459    qRegisterMetaType< QList< QRectF > >("QList<QRectF>");
460    qRegisterMetaType< Rotation >("Rotation");
461    qRegisterMetaType< RenderParam >("RenderParam");
462
463    parseWorkbenchExtendedSelection(argc, argv);
464
465    QApplication application(argc, argv);
466    QApplication::setOrganizationDomain("local.murrupuy");
467  //  QApplication::setOrganizationDomain("local.qpdfview");
468//    QApplication::setOrganizationName("qpdfview");
469//    QApplication::setApplicationName("qpdfview");
470    QApplication::setOrganizationName("murrupuy");
471    QApplication::setApplicationName("murrupuy");
472
473    QApplication::setApplicationVersion(APPLICATION_VERSION);
474
475    QApplication::setWindowIcon(QIcon(":icons/qpdfview.svg"));
476
477    loadTranslators();
478
479    parseCommandLineArguments();
480
481    resolveSourceReferences();
482
483    activateUniqueInstance();
484
485    prepareSignalHandler();
486
487    mainWindow->show();
488    mainWindow->setAttribute(Qt::WA_DeleteOnClose);
489
490    foreach(const File& file, files)
491    {
492        mainWindow->jumpToPageOrOpenInNewTab(file.filePath, file.page, true, file.enclosingBox, quiet);
493    }
494
495    if(!searchText.isEmpty())
496    {
497        mainWindow->startSearch(searchText);
498    }
499
500    return application.exec();
501}
Note: See TracBrowser for help on using the repository browser.