source: terepaima/terepaima-0.4.16/sources/mainwindow.cpp-old-pedro

stretch
Last change on this file was db91752, checked in by pbuitrago@…>, 6 years ago

se agregaron las funcionalidades para enviar el documento al servidor murachi

  • Property mode set to 100644
File size: 151.7 KB
Line 
1/*
2
3Copyright 2014-2015 S. Razi Alavizadeh
4Copyright 2012-2015 Adam Reichold
5Copyright 2014 Dorian Scholz
6Copyright 2012 Michał Trybus
7Copyright 2012 Alexander Volkov
8
9This file is part of qpdfview.
10
11qpdfview is free software: you can redistribute it and/or modify
12it under the terms of the GNU General Public License as published by
13the Free Software Foundation, either version 2 of the License, or
14(at your option) any later version.
15
16qpdfview is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19GNU General Public License for more details.
20
21You should have received a copy of the GNU General Public License
22along with qpdfview.  If not, see <http://www.gnu.org/licenses/>.
23
24*/
25
26#include "mainwindow.h"
27#include <stdio.h>
28#include <QApplication>
29#include <QCheckBox>
30#include <QClipboard>
31#include <QDateTime>
32#include <QDebug>
33#include <QDesktopServices>
34#include <QDockWidget>
35#include <QDragEnterEvent>
36#include <QFileDialog>
37#include <QHeaderView>
38#include <QInputDialog>
39#include <QMenuBar>
40#include <QMessageBox>
41#include <QMimeData>
42#include <QScrollBar>
43#include <QShortcut>
44#include <QStandardItemModel>
45#include <QTableView>
46#include <QTimer>
47#include <QToolBar>
48#include <QToolButton>
49#include <QUrl>
50#include <QVBoxLayout>
51#include <QWidgetAction>
52#include <QNetworkAccessManager>
53#include <QNetworkRequest>
54#include <QUrlQuery>
55#include <QJsonDocument>
56#include <QNetworkCookieJar>
57
58
59#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
60
61#include <QStandardPaths>
62
63#endif // QT_VERSION
64
65#include "model.h"
66#include "settings.h"
67#include "shortcuthandler.h"
68#include "thumbnailitem.h"
69#include "searchmodel.h"
70#include "searchitemdelegate.h"
71#include "documentview.h"
72#include "miscellaneous.h"
73#include "printdialog.h"
74#include "settingsdialog.h"
75#include "fontsdialog.h"
76#include "helpdialog.h"
77#include "recentlyusedmenu.h"
78#include "recentlyclosedmenu.h"
79#include "bookmarkmodel.h"
80#include "bookmarkmenu.h"
81#include "bookmarkdialog.h"
82#include "database.h"
83#include "Form.h"
84
85//********************************* POPPLER
86
87#include <stdio.h>
88#include <stdlib.h>
89#include <stddef.h>
90#include <string.h>
91#include <time.h>
92
93//#include "config.h"
94
95#include <poppler-config.h>
96
97#include "Object.h"
98#include "Array.h"
99#include "Page.h"
100#include "PDFDoc.h"
101#include "PDFDocFactory.h"
102#include "Error.h"
103#include "GlobalParams.h"
104#include "SignatureInfo.h"
105
106
107//********************************* POPPLER
108
109#include <QHBoxLayout>
110#include <QVBoxLayout>
111#include <QLabel>
112#include <QLineEdit>
113#include <QPushButton>
114#include <QDialog>
115
116//********************************* Signature
117
118#include <QCoreApplication>
119#include <assert.h>
120#include <iostream>
121#include <stdio.h>
122#include <QByteArray>
123#include <QUrl>
124#include <QNetworkReply>
125
126
127#include "include/pkcs11.h"
128#include "cryptotoken.h"
129
130namespace
131{
132
133using namespace qpdfview;
134
135QModelIndex synchronizeOutlineView(int currentPage, const QAbstractItemModel* model, const QModelIndex& parent)
136{
137    for(int row = 0, rowCount = model->rowCount(parent); row < rowCount; ++row)
138    {
139        const QModelIndex index = model->index(row, 0, parent);
140
141        bool ok = false;
142        const int page = model->data(index, Model::Document::PageRole).toInt(&ok);
143
144        if(ok && page == currentPage)
145        {
146            return index;
147        }
148    }
149
150    for(int row = 0, rowCount = model->rowCount(parent); row < rowCount; ++row)
151    {
152        const QModelIndex index = model->index(row, 0, parent);
153        const QModelIndex match = synchronizeOutlineView(currentPage, model, index);
154
155        if(match.isValid())
156        {
157            return match;
158        }
159    }
160
161    return QModelIndex();
162}
163
164inline void setToolButtonMenu(QToolBar* toolBar, QAction* action, QMenu* menu)
165{
166    if(QToolButton* toolButton = qobject_cast< QToolButton* >(toolBar->widgetForAction(action)))
167    {
168        toolButton->setMenu(menu);
169    }
170}
171
172inline QAction* createTemporaryAction(QObject* parent, const QString& text, const QString& objectName)
173{
174    QAction* action = new QAction(text, parent);
175
176    action->setObjectName(objectName);
177
178    return action;
179}
180
181void addWidgetActions(QWidget* widget, const QStringList& actionNames, const QList< QAction* >& actions)
182{
183    foreach(const QString& actionName, actionNames)
184    {
185        if(actionName == QLatin1String("separator"))
186        {
187            QAction* separator = new QAction(widget);
188            separator->setSeparator(true);
189
190            widget->addAction(separator);
191
192            continue;
193        }
194
195        foreach(QAction* action, actions)
196        {
197            if(actionName == action->objectName())
198            {
199                widget->addAction(action);
200
201                break;
202            }
203        }
204    }
205}
206
207class SignalBlocker
208{
209public:
210    SignalBlocker(QObject* object) : m_object(object)
211    {
212        m_object->blockSignals(true);
213    }
214
215    ~SignalBlocker()
216    {
217        m_object->blockSignals(false);
218    }
219
220private:
221    Q_DISABLE_COPY(SignalBlocker)
222
223    QObject* m_object;
224
225};
226
227} // anonymous
228
229namespace qpdfview
230{
231
232class MainWindow::RestoreTab : public Database::RestoreTab
233{
234private:
235    MainWindow* that;
236
237public:
238    RestoreTab(MainWindow* that) : that(that) {}
239
240    DocumentView* operator()(const QString& absoluteFilePath) const
241    {
242        if(that->openInNewTab(absoluteFilePath, -1, QRectF(), true))
243        {
244            return that->currentTab();
245        }
246        else
247        {
248            return 0;
249        }
250    }
251
252};
253
254class MainWindow::TextValueMapper : public MappingSpinBox::TextValueMapper
255{
256private:
257    MainWindow* that;
258
259public:
260    TextValueMapper(MainWindow* that) : that(that) {}
261
262    QString textFromValue(int val, bool& ok) const
263    {
264        const DocumentView* currentTab = that->currentTab();
265
266        if(currentTab == 0 || !(currentTab->hasFrontMatter() || that->s_settings->mainWindow().usePageLabel()))
267        {
268            ok = false;
269            return QString();
270        }
271
272        ok = true;
273        return currentTab->pageLabelFromNumber(val);
274    }
275
276    int valueFromText(const QString& text, bool& ok) const
277    {
278        const DocumentView* currentTab = that->currentTab();
279
280        if(currentTab == 0 || !(currentTab->hasFrontMatter() || that->s_settings->mainWindow().usePageLabel()))
281        {
282            ok = false;
283            return 0;
284        }
285
286        const QString& prefix = that->m_currentPageSpinBox->prefix();
287        const QString& suffix = that->m_currentPageSpinBox->suffix();
288
289        int from = 0;
290        int size = text.size();
291
292        if(!prefix.isEmpty() && text.startsWith(prefix))
293        {
294            from += prefix.size();
295            size -= from;
296        }
297
298        if(!suffix.isEmpty() && text.endsWith(suffix))
299        {
300            size -= suffix.size();
301        }
302
303        const QString& trimmedText = text.mid(from, size).trimmed();
304
305        ok = true;
306        return currentTab->pageNumberFromLabel(trimmedText);
307    }
308
309};
310
311Settings* MainWindow::s_settings = 0;
312Database* MainWindow::s_database = 0;
313ShortcutHandler* MainWindow::s_shortcutHandler = 0;
314
315MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent),
316    m_outlineView(0),
317    m_thumbnailsView(0),
318    manager(NULL)
319{
320    if(s_settings == 0)
321    {
322        s_settings = Settings::instance();
323    }
324
325    if(s_shortcutHandler == 0)
326    {
327        s_shortcutHandler = ShortcutHandler::instance();
328    }
329
330    prepareStyle();
331
332    setAcceptDrops(true);
333
334    createWidgets();
335    createActions();
336    createToolBars();
337    createDocks();
338    createMenus();
339
340    restoreGeometry(s_settings->mainWindow().geometry());
341    restoreState(s_settings->mainWindow().state());
342
343    prepareDatabase();
344
345    on_tabWidget_currentChanged(m_tabWidget->currentIndex());
346}
347
348QSize MainWindow::sizeHint() const
349{
350    return QSize(600, 800);
351}
352
353QMenu* MainWindow::createPopupMenu()
354{
355    qDebug("createPopupMenu()");
356    QMenu* menu = new QMenu();
357
358    menu->addAction(m_fileToolBar->toggleViewAction());
359    menu->addAction(m_editToolBar->toggleViewAction());
360    menu->addAction(m_viewToolBar->toggleViewAction());
361    menu->addSeparator();
362    menu->addAction(m_outlineDock->toggleViewAction());
363    menu->addAction(m_propertiesDock->toggleViewAction());
364    menu->addAction(m_thumbnailsDock->toggleViewAction());
365    menu->addAction(m_bookmarksDock->toggleViewAction());
366    menu->addAction(m_detailsSignatureDock->toggleViewAction());
367
368    return menu;
369}
370
371void MainWindow::show()
372{
373    QMainWindow::show();
374
375    if(s_settings->mainWindow().restoreTabs())
376    {
377        s_database->restoreTabs(RestoreTab(this));
378    }
379
380    if(s_settings->mainWindow().restoreBookmarks())
381    {
382        s_database->restoreBookmarks();
383    }
384}
385
386
387bool MainWindow::open(const QString& filePath, int page, const QRectF& highlight, bool quiet)
388{
389    if(m_tabWidget->currentIndex() != -1)
390    {
391        saveModifications(currentTab());
392
393        if(currentTab()->open(filePath))
394        {
395            s_settings->mainWindow().setOpenPath(currentTab()->fileInfo().absolutePath());
396            m_recentlyUsedMenu->addOpenAction(currentTab()->fileInfo());
397
398            m_tabWidget->setTabText(m_tabWidget->currentIndex(), currentTab()->title());
399            m_tabWidget->setTabToolTip(m_tabWidget->currentIndex(), currentTab()->fileInfo().absoluteFilePath());
400
401            s_database->restorePerFileSettings(currentTab());
402            scheduleSaveTabs();
403
404            currentTab()->jumpToPage(page, false);
405            currentTab()->setFocus();
406
407            if(!highlight.isNull())
408            {
409                currentTab()->temporaryHighlight(page, highlight);
410            }
411
412            return true;
413        }
414        else
415        {
416            if(!quiet)
417            {
418                QMessageBox::warning(this, tr("Warning"), tr("Could not open '%1'.").arg(filePath));
419            }
420        }
421    }
422
423    return false;
424}
425
426bool MainWindow::openInNewTab(const QString& filePath, int page, const QRectF& highlight, bool quiet)
427{
428    DocumentView* newTab = new DocumentView(this);
429
430    if(newTab->open(filePath))
431    {
432        s_settings->mainWindow().setOpenPath(newTab->fileInfo().absolutePath());
433        m_recentlyUsedMenu->addOpenAction(newTab->fileInfo());
434
435        const int index = addTab(newTab);
436
437        QAction* tabAction = new QAction(m_tabWidget->tabText(index), newTab);
438        connect(tabAction, SIGNAL(triggered()), SLOT(on_tabAction_triggered()));
439
440        tabAction->setData(true); // Flag action for search-as-you-type
441
442        m_tabsMenu->addAction(tabAction);
443
444        on_thumbnails_dockLocationChanged(dockWidgetArea(m_thumbnailsDock));
445
446        connect(newTab, SIGNAL(documentChanged()), SLOT(on_currentTab_documentChanged()));
447        connect(newTab, SIGNAL(documentModified()), SLOT(on_currentTab_documentModified()));
448
449        connect(newTab, SIGNAL(numberOfPagesChanged(int)), SLOT(on_currentTab_numberOfPagesChaned(int)));
450        connect(newTab, SIGNAL(currentPageChanged(int)), SLOT(on_currentTab_currentPageChanged(int)));
451
452        connect(newTab, SIGNAL(canJumpChanged(bool,bool)), SLOT(on_currentTab_canJumpChanged(bool,bool)));
453
454        connect(newTab, SIGNAL(continuousModeChanged(bool)), SLOT(on_currentTab_continuousModeChanged(bool)));
455        connect(newTab, SIGNAL(layoutModeChanged(LayoutMode)), SLOT(on_currentTab_layoutModeChanged(LayoutMode)));
456        connect(newTab, SIGNAL(rightToLeftModeChanged(bool)), SLOT(on_currentTab_rightToLeftModeChanged(bool)));
457        connect(newTab, SIGNAL(scaleModeChanged(ScaleMode)), SLOT(on_currentTab_scaleModeChanged(ScaleMode)));
458        connect(newTab, SIGNAL(scaleFactorChanged(qreal)), SLOT(on_currentTab_scaleFactorChanged(qreal)));
459        connect(newTab, SIGNAL(rotationChanged(Rotation)), SLOT(on_currentTab_rotationChanged(Rotation)));
460
461        connect(newTab, SIGNAL(linkClicked(int)), SLOT(on_currentTab_linkClicked(int)));
462        connect(newTab, SIGNAL(linkClicked(bool,QString,int)), SLOT(on_currentTab_linkClicked(bool,QString,int)));
463
464        connect(newTab, SIGNAL(renderFlagsChanged(qpdfview::RenderFlags)), SLOT(on_currentTab_renderFlagsChanged(qpdfview::RenderFlags)));
465
466        connect(newTab, SIGNAL(invertColorsChanged(bool)), SLOT(on_currentTab_invertColorsChanged(bool)));
467        connect(newTab, SIGNAL(convertToGrayscaleChanged(bool)), SLOT(on_currentTab_convertToGrayscaleChanged(bool)));
468        connect(newTab, SIGNAL(trimMarginsChanged(bool)), SLOT(on_currentTab_trimMarginsChanged(bool)));
469
470        connect(newTab, SIGNAL(compositionModeChanged(CompositionMode)), SLOT(on_currentTab_compositionModeChanged(CompositionMode)));
471
472        connect(newTab, SIGNAL(highlightAllChanged(bool)), SLOT(on_currentTab_highlightAllChanged(bool)));
473        connect(newTab, SIGNAL(rubberBandModeChanged(RubberBandMode)), SLOT(on_currentTab_rubberBandModeChanged(RubberBandMode)));
474
475        connect(newTab, SIGNAL(searchFinished()), SLOT(on_currentTab_searchFinished()));
476        connect(newTab, SIGNAL(searchProgressChanged(int)), SLOT(on_currentTab_searchProgressChanged(int)));
477
478        connect(newTab, SIGNAL(customContextMenuRequested(QPoint)), SLOT(on_currentTab_customContextMenuRequested(QPoint)));
479
480        newTab->show();
481
482        s_database->restorePerFileSettings(newTab);
483        scheduleSaveTabs();
484
485        newTab->jumpToPage(page, false);
486        newTab->setFocus();
487
488        if(!highlight.isNull())
489        {
490            newTab->temporaryHighlight(page, highlight);
491        }
492
493        return true;
494    }
495    else
496    {
497        delete newTab;
498
499        if(!quiet)
500        {
501            QMessageBox::warning(this, tr("Warning"), tr("Could not open '%1'.").arg(filePath));
502        }
503    }
504
505    return false;
506}
507
508bool MainWindow::jumpToPageOrOpenInNewTab(const QString& filePath, int page, bool refreshBeforeJump, const QRectF& highlight, bool quiet)
509{
510    const QFileInfo fileInfo(filePath);
511
512    for(int index = 0, count = m_tabWidget->count(); index < count; ++index)
513    {
514        if(tab(index)->fileInfo() == fileInfo)
515        {
516            m_tabWidget->setCurrentIndex(index);
517
518            if(refreshBeforeJump)
519            {
520                if(!currentTab()->refresh())
521                {
522                    return false;
523                }
524            }
525
526            currentTab()->jumpToPage(page);
527            currentTab()->setFocus();
528
529            if(!highlight.isNull())
530            {
531                currentTab()->temporaryHighlight(page, highlight);
532            }
533
534            return true;
535        }
536    }
537
538    return openInNewTab(filePath, page, highlight, quiet);
539}
540
541void MainWindow::startSearch(const QString& text)
542{
543    if(m_tabWidget->currentIndex() != -1)
544    {
545        m_searchDock->setVisible(true);
546
547        m_searchLineEdit->setText(text);
548        m_searchLineEdit->startSearch();
549
550        currentTab()->setFocus();
551    }
552}
553
554void MainWindow::on_tabWidget_currentChanged(int index)
555{
556    const bool hasCurrent = index != -1;
557
558    m_openCopyInNewTabAction->setEnabled(hasCurrent);
559    m_openContainingFolderAction->setEnabled(hasCurrent);
560    m_refreshAction->setEnabled(hasCurrent);
561    m_printAction->setEnabled(hasCurrent);
562    m_verify_signature->setEnabled(hasCurrent);
563    m_signature->setEnabled(hasCurrent);
564    //m_detailsSignatureDock->setEnabled(hasCurrent);
565
566    m_previousPageAction->setEnabled(hasCurrent);
567    m_nextPageAction->setEnabled(hasCurrent);
568    m_firstPageAction->setEnabled(hasCurrent);
569    m_lastPageAction->setEnabled(hasCurrent);
570
571    m_setFirstPageAction->setEnabled(hasCurrent);
572
573    m_jumpToPageAction->setEnabled(hasCurrent);
574
575    m_searchAction->setEnabled(hasCurrent);
576
577    m_copyToClipboardModeAction->setEnabled(hasCurrent);
578    m_addAnnotationModeAction->setEnabled(hasCurrent);
579
580    m_continuousModeAction->setEnabled(hasCurrent);
581    m_twoPagesModeAction->setEnabled(hasCurrent);
582    m_twoPagesWithCoverPageModeAction->setEnabled(hasCurrent);
583    m_multiplePagesModeAction->setEnabled(hasCurrent);
584    m_rightToLeftModeAction->setEnabled(hasCurrent);
585
586    m_zoomInAction->setEnabled(hasCurrent);
587    m_zoomOutAction->setEnabled(hasCurrent);
588    m_originalSizeAction->setEnabled(hasCurrent);
589    m_fitToPageWidthModeAction->setEnabled(hasCurrent);
590    m_fitToPageSizeModeAction->setEnabled(hasCurrent);
591
592    m_rotateLeftAction->setEnabled(hasCurrent);
593    m_rotateRightAction->setEnabled(hasCurrent);
594
595    m_invertColorsAction->setEnabled(hasCurrent);
596    m_convertToGrayscaleAction->setEnabled(hasCurrent);
597    m_trimMarginsAction->setEnabled(hasCurrent);
598
599    m_compositionModeMenu->setEnabled(hasCurrent);
600    m_darkenWithPaperColorAction->setEnabled(hasCurrent);
601    m_lightenWithPaperColorAction->setEnabled(hasCurrent);
602
603    m_fontsAction->setEnabled(hasCurrent);
604
605    m_presentationAction->setEnabled(hasCurrent);
606
607    m_previousTabAction->setEnabled(hasCurrent);
608    m_nextTabAction->setEnabled(hasCurrent);
609    m_closeTabAction->setEnabled(hasCurrent);
610    m_closeAllTabsAction->setEnabled(hasCurrent);
611    m_closeAllTabsButCurrentTabAction->setEnabled(hasCurrent);
612
613    m_previousBookmarkAction->setEnabled(hasCurrent);
614    m_nextBookmarkAction->setEnabled(hasCurrent);
615    m_addBookmarkAction->setEnabled(hasCurrent);
616    m_removeBookmarkAction->setEnabled(hasCurrent);
617
618    m_currentPageSpinBox->setEnabled(hasCurrent);
619    m_scaleFactorComboBox->setEnabled(hasCurrent);
620    m_searchLineEdit->setEnabled(hasCurrent);
621    m_matchCaseCheckBox->setEnabled(hasCurrent);
622    m_wholeWordsCheckBox->setEnabled(hasCurrent);
623    m_highlightAllCheckBox->setEnabled(hasCurrent);
624
625    m_searchDock->toggleViewAction()->setEnabled(hasCurrent);
626
627    if(hasCurrent)
628    {
629        qDebug("if(hasCurrent)");
630        m_saveCopyAction->setEnabled(currentTab()->canSave());
631        m_saveAsAction->setEnabled(currentTab()->canSave());
632
633        if(m_searchDock->isVisible())
634        {
635            m_searchLineEdit->stopTimer();
636            m_searchLineEdit->setProgress(currentTab()->searchProgress());
637        }
638
639        m_outlineView->setModel(currentTab()->outlineModel());
640        m_propertiesView->setModel(currentTab()->propertiesModel());
641        m_bookmarksView->setModel(bookmarkModelForCurrentTab());
642        m_detailsSignatureView->setModel(view_table_verify_signature());
643
644
645        m_thumbnailsView->setScene(currentTab()->thumbnailsScene());
646        currentTab()->setThumbnailsViewportSize(m_thumbnailsView->viewport()->size());
647
648        on_currentTab_documentChanged();
649
650        on_currentTab_numberOfPagesChaned(currentTab()->numberOfPages());
651        on_currentTab_currentPageChanged(currentTab()->currentPage());
652
653        on_currentTab_canJumpChanged(currentTab()->canJumpBackward(), currentTab()->canJumpForward());
654
655        on_currentTab_continuousModeChanged(currentTab()->continuousMode());
656        on_currentTab_layoutModeChanged(currentTab()->layoutMode());
657        on_currentTab_rightToLeftModeChanged(currentTab()->rightToLeftMode());
658        on_currentTab_scaleModeChanged(currentTab()->scaleMode());
659        on_currentTab_scaleFactorChanged(currentTab()->scaleFactor());
660
661        on_currentTab_invertColorsChanged(currentTab()->invertColors());
662        on_currentTab_convertToGrayscaleChanged(currentTab()->convertToGrayscale());
663        on_currentTab_trimMarginsChanged(currentTab()->trimMargins());
664
665        on_currentTab_compositionModeChanged(currentTab()->compositionMode());
666
667        on_currentTab_highlightAllChanged(currentTab()->highlightAll());
668        on_currentTab_rubberBandModeChanged(currentTab()->rubberBandMode());
669    }
670    else
671    {
672        m_saveCopyAction->setEnabled(false);
673        m_saveAsAction->setEnabled(false);
674
675        if(m_searchDock->isVisible())
676        {
677            m_searchLineEdit->stopTimer();
678            m_searchLineEdit->setProgress(0);
679
680            m_searchDock->setVisible(false);
681        }
682
683        m_outlineView->setModel(0);
684        m_propertiesView->setModel(0);
685        m_bookmarksView->setModel(0);
686
687        m_thumbnailsView->setScene(0);
688
689        setWindowTitleForCurrentTab();
690        setCurrentPageSuffixForCurrentTab();
691
692        m_currentPageSpinBox->setValue(1);
693        m_scaleFactorComboBox->setCurrentIndex(4);
694
695        m_jumpBackwardAction->setEnabled(false);
696        m_jumpForwardAction->setEnabled(false);
697
698        m_copyToClipboardModeAction->setChecked(false);
699        m_addAnnotationModeAction->setChecked(false);
700
701        m_continuousModeAction->setChecked(false);
702        m_twoPagesModeAction->setChecked(false);
703        m_twoPagesWithCoverPageModeAction->setChecked(false);
704        m_multiplePagesModeAction->setChecked(false);
705
706        m_fitToPageSizeModeAction->setChecked(false);
707        m_fitToPageWidthModeAction->setChecked(false);
708
709        m_invertColorsAction->setChecked(false);
710        m_convertToGrayscaleAction->setChecked(false);
711        m_trimMarginsAction->setChecked(false);
712
713        m_darkenWithPaperColorAction->setChecked(false);
714        m_lightenWithPaperColorAction->setChecked(false);
715    }
716}
717
718void MainWindow::on_tabWidget_tabCloseRequested(int index)
719{
720    if(saveModifications(tab(index)))
721    {
722        closeTab(tab(index));
723    }
724}
725
726void MainWindow::on_tabWidget_tabContextMenuRequested(const QPoint& globalPos, int index)
727{
728    QMenu menu;
729
730    // We block their signals since we need to handle them using the selected instead of the current tab.
731    SignalBlocker openCopyInNewTabSignalBlocker(m_openCopyInNewTabAction);
732    SignalBlocker openContainingFolderSignalBlocker(m_openContainingFolderAction);
733
734    QAction* copyFilePathAction = createTemporaryAction(&menu, tr("Copy file path"), QLatin1String("copyFilePath"));
735    QAction* selectFilePathAction = createTemporaryAction(&menu, tr("Select file path"), QLatin1String("selectFilePath"));
736
737    QAction* closeAllTabsAction = createTemporaryAction(&menu, tr("Close all tabs"), QLatin1String("closeAllTabs"));
738    QAction* closeAllTabsButThisOneAction = createTemporaryAction(&menu, tr("Close all tabs but this one"), QLatin1String("closeAllTabsButThisOne"));
739    QAction* closeAllTabsToTheLeftAction = createTemporaryAction(&menu, tr("Close all tabs to the left"), QLatin1String("closeAllTabsToTheLeft"));
740    QAction* closeAllTabsToTheRightAction = createTemporaryAction(&menu, tr("Close all tabs to the right"), QLatin1String("closeAllTabsToTheRight"));
741
742    selectFilePathAction->setVisible(QApplication::clipboard()->supportsSelection());
743
744    QList< QAction* > actions;
745
746    actions << m_openCopyInNewTabAction << m_openContainingFolderAction
747            << copyFilePathAction << selectFilePathAction
748            << closeAllTabsAction << closeAllTabsButThisOneAction
749            << closeAllTabsToTheLeftAction << closeAllTabsToTheRightAction;
750
751    addWidgetActions(&menu, s_settings->mainWindow().tabContextMenu(), actions);
752
753    const QAction* action = menu.exec(globalPos);
754
755    const DocumentView* selectedTab = tab(index);
756    QList< DocumentView* > tabsToClose;
757
758    if(action == m_openCopyInNewTabAction)
759    {
760        openInNewTab(selectedTab->fileInfo().filePath(), selectedTab->currentPage());
761
762        return;
763    }
764    else if(action == m_openContainingFolderAction)
765    {
766        QDesktopServices::openUrl(QUrl::fromLocalFile(selectedTab->fileInfo().absolutePath()));
767
768        return;
769    }
770    else if(action == copyFilePathAction)
771    {
772        QApplication::clipboard()->setText(selectedTab->fileInfo().absoluteFilePath());
773
774        return;
775    }
776    else if(action == selectFilePathAction)
777    {
778        QApplication::clipboard()->setText(selectedTab->fileInfo().absoluteFilePath(), QClipboard::Selection);
779
780        return;
781    }
782    else if(action == closeAllTabsAction)
783    {
784        tabsToClose = tabs();
785    }
786    else if(action == closeAllTabsButThisOneAction)
787    {
788        const int count = m_tabWidget->count();
789
790        for(int indexToClose = 0; indexToClose < count; ++indexToClose)
791        {
792            if(indexToClose != index)
793            {
794                tabsToClose.append(tab(indexToClose));
795            }
796        }
797    }
798    else if(action == closeAllTabsToTheLeftAction)
799    {
800        for(int indexToClose = 0; indexToClose < index; ++indexToClose)
801        {
802            tabsToClose.append(tab(indexToClose));
803        }
804    }
805    else if(action == closeAllTabsToTheRightAction)
806    {
807        const int count = m_tabWidget->count();
808
809        for(int indexToClose = count - 1; indexToClose > index; --indexToClose)
810        {
811            tabsToClose.append(tab(indexToClose));
812        }
813    }
814    else
815    {
816        return;
817    }
818
819    disconnectCurrentTabChanged();
820
821    foreach(DocumentView* tab, tabsToClose)
822    {
823        if(saveModifications(tab))
824        {
825            closeTab(tab);
826        }
827    }
828
829    reconnectCurrentTabChanged();
830}
831
832#define ONLY_IF_SENDER_IS_CURRENT_TAB if(!senderIsCurrentTab()) { return; }
833
834void MainWindow::on_currentTab_documentChanged()
835{
836    for(int index = 0, count = m_tabWidget->count(); index < count; ++index)
837    {
838        if(sender() == m_tabWidget->widget(index))
839        {
840            m_tabWidget->setTabText(index, tab(index)->title());
841            m_tabWidget->setTabToolTip(index, tab(index)->fileInfo().absoluteFilePath());
842
843            foreach(QAction* tabAction, m_tabsMenu->actions())
844            {
845                if(tabAction->parent() == m_tabWidget->widget(index))
846                {
847                    tabAction->setText(m_tabWidget->tabText(index));
848
849                    break;
850                }
851            }
852
853            break;
854        }
855    }
856
857    ONLY_IF_SENDER_IS_CURRENT_TAB
858
859    m_outlineView->restoreExpansion();
860
861    setWindowTitleForCurrentTab();
862
863    setWindowModified(currentTab() != 0 ? currentTab()->wasModified() : false);
864}
865
866void MainWindow::on_currentTab_documentModified()
867{
868    ONLY_IF_SENDER_IS_CURRENT_TAB
869
870    setWindowModified(true);
871}
872
873void MainWindow::on_currentTab_numberOfPagesChaned(int numberOfPages)
874{
875    ONLY_IF_SENDER_IS_CURRENT_TAB
876
877    m_currentPageSpinBox->setRange(1, numberOfPages);
878
879    setWindowTitleForCurrentTab();
880    setCurrentPageSuffixForCurrentTab();
881}
882
883void MainWindow::on_currentTab_currentPageChanged(int currentPage)
884{
885    scheduleSaveTabs();
886    scheduleSavePerFileSettings();
887
888    ONLY_IF_SENDER_IS_CURRENT_TAB
889
890    m_currentPageSpinBox->setValue(currentPage);
891
892    if(s_settings->mainWindow().synchronizeOutlineView() && m_outlineView->model() != 0)
893    {
894        const QModelIndex match = synchronizeOutlineView(currentPage, m_outlineView->model(), QModelIndex());
895
896        if(match.isValid())
897        {
898            m_outlineView->collapseAll();
899
900            m_outlineView->expandAbove(match);
901            m_outlineView->setCurrentIndex(match);
902        }
903    }
904
905    m_thumbnailsView->ensureVisible(currentTab()->thumbnailItems().at(currentPage - 1));
906
907    setWindowTitleForCurrentTab();
908    setCurrentPageSuffixForCurrentTab();
909}
910
911void MainWindow::on_currentTab_canJumpChanged(bool backward, bool forward)
912{
913    ONLY_IF_SENDER_IS_CURRENT_TAB
914
915    m_jumpBackwardAction->setEnabled(backward);
916    m_jumpForwardAction->setEnabled(forward);
917}
918
919void MainWindow::on_currentTab_continuousModeChanged(bool continuousMode)
920{
921    scheduleSaveTabs();
922    scheduleSavePerFileSettings();
923
924    ONLY_IF_SENDER_IS_CURRENT_TAB
925
926    m_continuousModeAction->setChecked(continuousMode);
927}
928
929void MainWindow::on_currentTab_layoutModeChanged(LayoutMode layoutMode)
930{
931    scheduleSaveTabs();
932    scheduleSavePerFileSettings();
933
934    ONLY_IF_SENDER_IS_CURRENT_TAB
935
936    m_twoPagesModeAction->setChecked(layoutMode == TwoPagesMode);
937    m_twoPagesWithCoverPageModeAction->setChecked(layoutMode == TwoPagesWithCoverPageMode);
938    m_multiplePagesModeAction->setChecked(layoutMode == MultiplePagesMode);
939}
940
941void MainWindow::on_currentTab_rightToLeftModeChanged(bool rightToLeftMode)
942{
943    scheduleSaveTabs();
944    scheduleSavePerFileSettings();
945
946    ONLY_IF_SENDER_IS_CURRENT_TAB
947
948    m_rightToLeftModeAction->setChecked(rightToLeftMode);
949}
950
951void MainWindow::on_currentTab_scaleModeChanged(ScaleMode scaleMode)
952{
953    scheduleSaveTabs();
954    scheduleSavePerFileSettings();
955
956    ONLY_IF_SENDER_IS_CURRENT_TAB
957
958    switch(scaleMode)
959    {
960    default:
961    case ScaleFactorMode:
962        m_fitToPageWidthModeAction->setChecked(false);
963        m_fitToPageSizeModeAction->setChecked(false);
964
965        on_currentTab_scaleFactorChanged(currentTab()->scaleFactor());
966        break;
967    case FitToPageWidthMode:
968        m_fitToPageWidthModeAction->setChecked(true);
969        m_fitToPageSizeModeAction->setChecked(false);
970
971        m_scaleFactorComboBox->setCurrentIndex(0);
972
973        m_zoomInAction->setEnabled(true);
974        m_zoomOutAction->setEnabled(true);
975        break;
976    case FitToPageSizeMode:
977        m_fitToPageWidthModeAction->setChecked(false);
978        m_fitToPageSizeModeAction->setChecked(true);
979
980        m_scaleFactorComboBox->setCurrentIndex(1);
981
982        m_zoomInAction->setEnabled(true);
983        m_zoomOutAction->setEnabled(true);
984        break;
985    }
986}
987
988void MainWindow::on_currentTab_scaleFactorChanged(qreal scaleFactor)
989{
990    if(senderIsCurrentTab())
991    {
992        if(currentTab()->scaleMode() == ScaleFactorMode)
993        {
994            m_scaleFactorComboBox->setCurrentIndex(m_scaleFactorComboBox->findData(scaleFactor));
995            m_scaleFactorComboBox->lineEdit()->setText(QString("%1 %").arg(qRound(scaleFactor * 100.0)));
996
997            m_zoomInAction->setDisabled(qFuzzyCompare(scaleFactor, s_settings->documentView().maximumScaleFactor()));
998            m_zoomOutAction->setDisabled(qFuzzyCompare(scaleFactor, s_settings->documentView().minimumScaleFactor()));
999        }
1000
1001        scheduleSaveTabs();
1002        scheduleSavePerFileSettings();
1003    }
1004}
1005
1006void MainWindow::on_currentTab_rotationChanged(Rotation rotation)
1007{
1008    Q_UNUSED(rotation);
1009
1010    if(senderIsCurrentTab())
1011    {
1012        scheduleSaveTabs();
1013        scheduleSavePerFileSettings();
1014    }
1015}
1016
1017void MainWindow::on_currentTab_linkClicked(int page)
1018{
1019    openInNewTab(currentTab()->fileInfo().filePath(), page);
1020}
1021
1022void MainWindow::on_currentTab_linkClicked(bool newTab, const QString& filePath, int page)
1023{
1024    if(newTab)
1025    {
1026        openInNewTab(filePath, page);
1027    }
1028    else
1029    {
1030        jumpToPageOrOpenInNewTab(filePath, page, true);
1031    }
1032}
1033
1034void MainWindow::on_currentTab_renderFlagsChanged(qpdfview::RenderFlags renderFlags)
1035{
1036    Q_UNUSED(renderFlags);
1037
1038    scheduleSaveTabs();
1039    scheduleSavePerFileSettings();
1040}
1041
1042void MainWindow::on_currentTab_invertColorsChanged(bool invertColors)
1043{
1044    ONLY_IF_SENDER_IS_CURRENT_TAB
1045
1046    m_invertColorsAction->setChecked(invertColors);
1047}
1048
1049void MainWindow::on_currentTab_convertToGrayscaleChanged(bool convertToGrayscale)
1050{
1051    ONLY_IF_SENDER_IS_CURRENT_TAB
1052
1053    m_convertToGrayscaleAction->setChecked(convertToGrayscale);
1054}
1055
1056void MainWindow::on_currentTab_trimMarginsChanged(bool trimMargins)
1057{
1058    ONLY_IF_SENDER_IS_CURRENT_TAB
1059
1060    m_trimMarginsAction->setChecked(trimMargins);
1061}
1062
1063void MainWindow::on_currentTab_compositionModeChanged(CompositionMode compositionMode)
1064{
1065    ONLY_IF_SENDER_IS_CURRENT_TAB
1066
1067    switch(compositionMode)
1068    {
1069    default:
1070    case DefaultCompositionMode:
1071        m_darkenWithPaperColorAction->setChecked(false);
1072        m_lightenWithPaperColorAction->setChecked(false);
1073        break;
1074    case DarkenWithPaperColorMode:
1075        m_darkenWithPaperColorAction->setChecked(true);
1076        m_lightenWithPaperColorAction->setChecked(false);
1077        break;
1078    case LightenWithPaperColorMode:
1079        m_darkenWithPaperColorAction->setChecked(false);
1080        m_lightenWithPaperColorAction->setChecked(true);
1081        break;
1082    }
1083}
1084
1085void MainWindow::on_currentTab_highlightAllChanged(bool highlightAll)
1086{
1087    ONLY_IF_SENDER_IS_CURRENT_TAB
1088
1089    m_highlightAllCheckBox->setChecked(highlightAll);
1090}
1091
1092void MainWindow::on_currentTab_rubberBandModeChanged(RubberBandMode rubberBandMode)
1093{
1094    ONLY_IF_SENDER_IS_CURRENT_TAB
1095
1096    m_copyToClipboardModeAction->setChecked(rubberBandMode == CopyToClipboardMode);
1097    m_addAnnotationModeAction->setChecked(rubberBandMode == AddAnnotationMode);
1098}
1099
1100void MainWindow::on_currentTab_searchFinished()
1101{
1102    ONLY_IF_SENDER_IS_CURRENT_TAB
1103
1104    m_searchLineEdit->setProgress(0);
1105}
1106
1107void MainWindow::on_currentTab_searchProgressChanged(int progress)
1108{
1109    ONLY_IF_SENDER_IS_CURRENT_TAB
1110
1111    m_searchLineEdit->setProgress(progress);
1112}
1113
1114void MainWindow::on_currentTab_customContextMenuRequested(const QPoint& pos)
1115{
1116    ONLY_IF_SENDER_IS_CURRENT_TAB
1117
1118    QMenu menu;
1119
1120    QAction* sourceLinkAction = sourceLinkActionForCurrentTab(&menu, pos);
1121
1122    QList< QAction* > actions;
1123
1124    actions << m_openCopyInNewTabAction << m_openContainingFolderAction
1125            << m_previousPageAction << m_nextPageAction
1126            << m_firstPageAction << m_lastPageAction
1127            << m_jumpToPageAction << m_jumpBackwardAction << m_jumpForwardAction
1128            << m_setFirstPageAction;
1129
1130    if(m_searchDock->isVisible())
1131    {
1132        actions << m_findPreviousAction << m_findNextAction << m_cancelSearchAction;
1133    }
1134
1135    menu.addAction(sourceLinkAction);
1136    menu.addSeparator();
1137
1138    addWidgetActions(&menu, s_settings->mainWindow().documentContextMenu(), actions);
1139
1140    const QAction* action = menu.exec(currentTab()->mapToGlobal(pos));
1141
1142    if(action == sourceLinkAction)
1143    {
1144        currentTab()->openInSourceEditor(sourceLinkAction->data().value< DocumentView::SourceLink >());
1145    }
1146}
1147
1148#undef ONLY_IF_SENDER_IS_CURRENT_TAB
1149
1150void MainWindow::on_currentPage_editingFinished()
1151{
1152    if(m_tabWidget->currentIndex() != -1)
1153    {
1154        currentTab()->jumpToPage(m_currentPageSpinBox->value());
1155    }
1156}
1157
1158void MainWindow::on_currentPage_returnPressed()
1159{
1160    currentTab()->setFocus();
1161}
1162
1163void MainWindow::on_scaleFactor_activated(int index)
1164{
1165    if(index == 0)
1166    {
1167        currentTab()->setScaleMode(FitToPageWidthMode);
1168    }
1169    else if(index == 1)
1170    {
1171        currentTab()->setScaleMode(FitToPageSizeMode);
1172    }
1173    else
1174    {
1175        bool ok = false;
1176        const qreal scaleFactor = m_scaleFactorComboBox->itemData(index).toReal(&ok);
1177
1178        if(ok)
1179        {
1180            currentTab()->setScaleFactor(scaleFactor);
1181            currentTab()->setScaleMode(ScaleFactorMode);
1182        }
1183    }
1184
1185    currentTab()->setFocus();
1186}
1187
1188void MainWindow::on_scaleFactor_editingFinished()
1189{
1190    if(m_tabWidget->currentIndex() != -1)
1191    {
1192        bool ok = false;
1193        qreal scaleFactor = m_scaleFactorComboBox->lineEdit()->text().toInt(&ok) / 100.0;
1194
1195        scaleFactor = qMax(scaleFactor, s_settings->documentView().minimumScaleFactor());
1196        scaleFactor = qMin(scaleFactor, s_settings->documentView().maximumScaleFactor());
1197
1198        if(ok)
1199        {
1200            currentTab()->setScaleFactor(scaleFactor);
1201            currentTab()->setScaleMode(ScaleFactorMode);
1202        }
1203
1204        on_currentTab_scaleFactorChanged(currentTab()->scaleFactor());
1205        on_currentTab_scaleModeChanged(currentTab()->scaleMode());
1206    }
1207}
1208
1209void MainWindow::on_scaleFactor_returnPressed()
1210{
1211    currentTab()->setFocus();
1212}
1213
1214void MainWindow::on_open_triggered()
1215{
1216    qDebug("***..on_open_triggereg..***");
1217    if(m_tabWidget->currentIndex() != -1)
1218    {
1219        const QString path = s_settings->mainWindow().openPath();
1220        const QString filePath = QFileDialog::getOpenFileName(this, tr("Open"), path, DocumentView::openFilter().join(";;"));
1221
1222        qDebug("*****on_open_triggereg****** FilePath %s", qPrintable(filePath));
1223
1224
1225        if(!filePath.isEmpty())
1226        {
1227            open(filePath);
1228        }
1229    }
1230    else
1231    {
1232        on_openInNewTab_triggered();
1233    }
1234}
1235
1236void MainWindow::on_openInNewTab_triggered()
1237{
1238    qDebug("***..on_openInNewTab_triggered..***");
1239    const QString path = s_settings->mainWindow().openPath();
1240    const QStringList filePaths = QFileDialog::getOpenFileNames(this, tr("Open in new tab"), path, DocumentView::openFilter().join(";;"));
1241
1242    if(!filePaths.isEmpty())
1243    {
1244        disconnectCurrentTabChanged();
1245
1246        foreach(const QString& filePath, filePaths)
1247        {
1248            qDebug("*****on_openInNewTab_triggered****** FilePath %s", qPrintable(filePath));
1249            openInNewTab(filePath);
1250
1251        }
1252
1253        reconnectCurrentTabChanged();
1254    }
1255}
1256
1257void MainWindow::on_openCopyInNewTab_triggered()
1258{
1259    openInNewTab(currentTab()->fileInfo().filePath(), currentTab()->currentPage());
1260}
1261
1262void MainWindow::on_openContainingFolder_triggered()
1263{
1264    QDesktopServices::openUrl(QUrl::fromLocalFile(currentTab()->fileInfo().absolutePath()));
1265}
1266
1267void MainWindow::on_refresh_triggered()
1268{
1269    if(!currentTab()->refresh())
1270    {
1271        QMessageBox::warning(this, tr("Warning"), tr("Could not refresh '%1'.").arg(currentTab()->fileInfo().filePath()));
1272    }
1273}
1274
1275void MainWindow::on_saveCopy_triggered()
1276{
1277    const QDir dir = QDir(s_settings->mainWindow().savePath());
1278    const QString filePath = QFileDialog::getSaveFileName(this, tr("Save copy"), dir.filePath(currentTab()->fileInfo().fileName()), currentTab()->saveFilter().join(";;"));
1279
1280    if(!filePath.isEmpty())
1281    {
1282        if(currentTab()->save(filePath, false))
1283        {
1284            s_settings->mainWindow().setSavePath(QFileInfo(filePath).absolutePath());
1285        }
1286        else
1287        {
1288            QMessageBox::warning(this, tr("Warning"), tr("Could not save copy at '%1'.").arg(filePath));
1289        }
1290    }
1291}
1292
1293void MainWindow::on_saveAs_triggered()
1294{
1295    const QString filePath = QFileDialog::getSaveFileName(this, tr("Save as"), currentTab()->fileInfo().filePath(), currentTab()->saveFilter().join(";;"));
1296
1297    if(!filePath.isEmpty())
1298    {
1299        if(currentTab()->save(filePath, true))
1300        {
1301            open(filePath, currentTab()->currentPage());
1302        }
1303        else
1304        {
1305            QMessageBox::warning(this, tr("Warning"), tr("Could not save as '%1'.").arg(filePath));
1306        }
1307    }
1308}
1309
1310void MainWindow::on_print_triggered()
1311{
1312    QScopedPointer< QPrinter > printer(PrintDialog::createPrinter());
1313    QScopedPointer< PrintDialog > printDialog(new PrintDialog(printer.data(), this));
1314
1315    printer->setDocName(currentTab()->fileInfo().completeBaseName());
1316    printer->setFullPage(true);
1317
1318    printDialog->setMinMax(1, currentTab()->numberOfPages());
1319    printDialog->setOption(QPrintDialog::PrintToFile, false);
1320
1321#if QT_VERSION >= QT_VERSION_CHECK(4,7,0)
1322
1323    printDialog->setOption(QPrintDialog::PrintCurrentPage, true);
1324
1325#endif // QT_VERSION
1326
1327    if(printDialog->exec() != QDialog::Accepted)
1328    {
1329        return;
1330    }
1331
1332#if QT_VERSION >= QT_VERSION_CHECK(4,7,0)
1333
1334    if(printDialog->printRange() == QPrintDialog::CurrentPage)
1335    {
1336        printer->setFromTo(currentTab()->currentPage(), currentTab()->currentPage());
1337    }
1338
1339#endif // QT_VERSION
1340
1341    if(!currentTab()->print(printer.data(), printDialog->printOptions()))
1342    {
1343        QMessageBox::warning(this, tr("Warning"), tr("Could not print '%1'.").arg(currentTab()->fileInfo().filePath()));
1344    }
1345}
1346
1347void MainWindow::on_recentlyUsed_openTriggered(const QString& filePath)
1348{
1349    if(!jumpToPageOrOpenInNewTab(filePath, -1, true))
1350    {
1351        m_recentlyUsedMenu->removeOpenAction(filePath);
1352    }
1353}
1354
1355void MainWindow::on_previousPage_triggered()
1356{
1357    currentTab()->previousPage();
1358}
1359
1360void MainWindow::on_nextPage_triggered()
1361{
1362    currentTab()->nextPage();
1363}
1364
1365void MainWindow::on_firstPage_triggered()
1366{
1367    currentTab()->firstPage();
1368}
1369
1370void MainWindow::on_lastPage_triggered()
1371{
1372    currentTab()->lastPage();
1373}
1374
1375void MainWindow::on_setFirstPage_triggered()
1376{
1377    bool ok = false;
1378    const int pageNumber = getMappedNumber(new TextValueMapper(this),
1379                                           this, tr("Set first page"), tr("Select the first page of the body matter:"),
1380                                           currentTab()->currentPage(), 1, currentTab()->numberOfPages(), &ok);
1381
1382    if(ok)
1383    {
1384        currentTab()->setFirstPage(pageNumber);
1385    }
1386}
1387
1388void MainWindow::on_jumpToPage_triggered()
1389{
1390    bool ok = false;
1391    const int pageNumber = getMappedNumber(new TextValueMapper(this),
1392                                           this, tr("Jump to page"), tr("Page:"),
1393                                           currentTab()->currentPage(), 1, currentTab()->numberOfPages(), &ok);
1394
1395    if(ok)
1396    {
1397        currentTab()->jumpToPage(pageNumber);
1398    }
1399}
1400
1401void MainWindow::on_jumpBackward_triggered()
1402{
1403    currentTab()->jumpBackward();
1404}
1405
1406void MainWindow::on_jumpForward_triggered()
1407{
1408    currentTab()->jumpForward();
1409}
1410
1411void MainWindow::on_search_triggered()
1412{
1413    m_searchDock->setVisible(true);
1414    m_searchDock->raise();
1415
1416    m_searchLineEdit->selectAll();
1417    m_searchLineEdit->setFocus();
1418}
1419
1420void MainWindow::on_findPrevious_triggered()
1421{
1422    if(!m_searchLineEdit->text().isEmpty())
1423    {
1424        currentTab()->findPrevious();
1425    }
1426}
1427
1428void MainWindow::on_findNext_triggered()
1429{
1430    if(!m_searchLineEdit->text().isEmpty())
1431    {
1432        currentTab()->findNext();
1433    }
1434}
1435
1436void MainWindow::on_cancelSearch_triggered()
1437{
1438    m_searchLineEdit->stopTimer();
1439    m_searchLineEdit->setProgress(0);
1440
1441    for(int index = 0, count = m_tabWidget->count(); index < count; ++index)
1442    {
1443        tab(index)->cancelSearch();
1444    }
1445
1446    if(!s_settings->mainWindow().extendedSearchDock())
1447    {
1448        m_searchDock->setVisible(false);
1449    }
1450}
1451
1452void MainWindow::on_copyToClipboardMode_triggered(bool checked)
1453{
1454    currentTab()->setRubberBandMode(checked ? CopyToClipboardMode : ModifiersMode);
1455}
1456
1457void MainWindow::on_addAnnotationMode_triggered(bool checked)
1458{
1459    currentTab()->setRubberBandMode(checked ? AddAnnotationMode : ModifiersMode);
1460}
1461
1462void MainWindow::on_settings_triggered()
1463{
1464    QScopedPointer< SettingsDialog > settingsDialog(new SettingsDialog(this));
1465
1466    if(settingsDialog->exec() != QDialog::Accepted)
1467    {
1468        return;
1469    }
1470
1471    s_settings->sync();
1472
1473    m_tabWidget->setTabPosition(static_cast< QTabWidget::TabPosition >(s_settings->mainWindow().tabPosition()));
1474    m_tabWidget->setTabBarPolicy(static_cast< TabWidget::TabBarPolicy >(s_settings->mainWindow().tabVisibility()));
1475    m_tabWidget->setSpreadTabs(s_settings->mainWindow().spreadTabs());
1476
1477    m_tabsMenu->setSearchable(s_settings->mainWindow().searchableMenus());
1478    m_bookmarksMenu->setSearchable(s_settings->mainWindow().searchableMenus());
1479
1480    m_saveDatabaseTimer->setInterval(s_settings->mainWindow().saveDatabaseInterval());
1481
1482    for(int index = 0, count = m_tabWidget->count(); index < count; ++index)
1483    {
1484        if(!tab(index)->refresh())
1485        {
1486            QMessageBox::warning(this, tr("Warning"), tr("Could not refresh '%1'.").arg(currentTab()->fileInfo().filePath()));
1487        }
1488    }
1489}
1490
1491void MainWindow::on_continuousMode_triggered(bool checked)
1492{
1493    currentTab()->setContinuousMode(checked);
1494}
1495
1496void MainWindow::on_twoPagesMode_triggered(bool checked)
1497{
1498    currentTab()->setLayoutMode(checked ? TwoPagesMode : SinglePageMode);
1499}
1500
1501void MainWindow::on_twoPagesWithCoverPageMode_triggered(bool checked)
1502{
1503    currentTab()->setLayoutMode(checked ? TwoPagesWithCoverPageMode : SinglePageMode);
1504}
1505
1506void MainWindow::on_multiplePagesMode_triggered(bool checked)
1507{
1508    currentTab()->setLayoutMode(checked ? MultiplePagesMode : SinglePageMode);
1509}
1510
1511void MainWindow::on_rightToLeftMode_triggered(bool checked)
1512{
1513    currentTab()->setRightToLeftMode(checked);
1514}
1515
1516void MainWindow::on_zoomIn_triggered()
1517{
1518    currentTab()->zoomIn();
1519}
1520
1521void MainWindow::on_zoomOut_triggered()
1522{
1523    currentTab()->zoomOut();
1524}
1525
1526void MainWindow::on_originalSize_triggered()
1527{
1528    currentTab()->originalSize();
1529}
1530
1531void MainWindow::on_fitToPageWidthMode_triggered(bool checked)
1532{
1533    currentTab()->setScaleMode(checked ? FitToPageWidthMode : ScaleFactorMode);
1534}
1535
1536void MainWindow::on_fitToPageSizeMode_triggered(bool checked)
1537{
1538    currentTab()->setScaleMode(checked ? FitToPageSizeMode : ScaleFactorMode);
1539}
1540
1541void MainWindow::on_rotateLeft_triggered()
1542{
1543    currentTab()->rotateLeft();
1544}
1545
1546void MainWindow::on_rotateRight_triggered()
1547{
1548    currentTab()->rotateRight();
1549}
1550
1551void MainWindow::on_invertColors_triggered(bool checked)
1552{
1553    currentTab()->setInvertColors(checked);
1554}
1555
1556void MainWindow::on_convertToGrayscale_triggered(bool checked)
1557{
1558    currentTab()->setConvertToGrayscale(checked);
1559}
1560
1561void MainWindow::on_trimMargins_triggered(bool checked)
1562{
1563    currentTab()->setTrimMargins(checked);
1564}
1565
1566void MainWindow::on_darkenWithPaperColor_triggered(bool checked)
1567{
1568    currentTab()->setCompositionMode(checked ? DarkenWithPaperColorMode : DefaultCompositionMode);
1569}
1570
1571void MainWindow::on_lightenWithPaperColor_triggered(bool checked)
1572{
1573    currentTab()->setCompositionMode(checked ? LightenWithPaperColorMode : DefaultCompositionMode);
1574}
1575
1576void MainWindow::on_fonts_triggered()
1577{
1578    QScopedPointer< QStandardItemModel > fontsModel(currentTab()->fontsModel());
1579    QScopedPointer< FontsDialog > dialog(new FontsDialog(fontsModel.data(), this));
1580
1581    dialog->exec();
1582}
1583
1584void MainWindow::on_fullscreen_triggered(bool checked)
1585{
1586    if(checked)
1587    {
1588        m_fullscreenAction->setData(saveGeometry());
1589
1590        showFullScreen();
1591    }
1592    else
1593    {
1594        restoreGeometry(m_fullscreenAction->data().toByteArray());
1595
1596        showNormal();
1597
1598        restoreGeometry(m_fullscreenAction->data().toByteArray());
1599    }
1600
1601    if(s_settings->mainWindow().toggleToolAndMenuBarsWithFullscreen())
1602    {
1603        m_toggleToolBarsAction->trigger();
1604        m_toggleMenuBarAction->trigger();
1605    }
1606}
1607
1608void MainWindow::on_presentation_triggered()
1609{
1610    currentTab()->startPresentation();
1611}
1612
1613void MainWindow::on_previousTab_triggered()
1614{
1615    if(m_tabWidget->currentIndex() > 0)
1616    {
1617        m_tabWidget->setCurrentIndex(m_tabWidget->currentIndex() - 1);
1618    }
1619    else
1620    {
1621        m_tabWidget->setCurrentIndex(m_tabWidget->count() - 1);
1622    }
1623}
1624
1625void MainWindow::on_nextTab_triggered()
1626{
1627    if(m_tabWidget->currentIndex() < m_tabWidget->count() - 1)
1628    {
1629        m_tabWidget->setCurrentIndex(m_tabWidget->currentIndex() + 1);
1630    }
1631    else
1632    {
1633        m_tabWidget->setCurrentIndex(0);
1634    }
1635}
1636
1637void MainWindow::on_closeTab_triggered()
1638{
1639    if(saveModifications(currentTab()))
1640    {
1641        closeTab(currentTab());
1642    }
1643}
1644
1645void MainWindow::on_closeAllTabs_triggered()
1646{
1647    disconnectCurrentTabChanged();
1648
1649    foreach(DocumentView* tab, tabs())
1650    {
1651        if(saveModifications(tab))
1652        {
1653            closeTab(tab);
1654        }
1655    }
1656
1657    reconnectCurrentTabChanged();
1658}
1659
1660void MainWindow::on_closeAllTabsButCurrentTab_triggered()
1661{
1662    disconnectCurrentTabChanged();
1663
1664    DocumentView* tab = currentTab();
1665
1666    const int oldIndex = m_tabWidget->currentIndex();
1667    const QString tabText = m_tabWidget->tabText(oldIndex);
1668    const QString tabToolTip = m_tabWidget->tabToolTip(oldIndex);
1669
1670    m_tabWidget->removeTab(oldIndex);
1671
1672    foreach(DocumentView* tab, tabs())
1673    {
1674        if(saveModifications(tab))
1675        {
1676            closeTab(tab);
1677        }
1678    }
1679
1680    const int newIndex = m_tabWidget->addTab(tab, tabText);
1681    m_tabWidget->setTabToolTip(newIndex, tabToolTip);
1682    m_tabWidget->setCurrentIndex(newIndex);
1683
1684    reconnectCurrentTabChanged();
1685}
1686
1687void MainWindow::on_restoreMostRecentlyClosedTab_triggered()
1688{
1689    m_recentlyClosedMenu->triggerLastTabAction();
1690}
1691
1692void MainWindow::on_recentlyClosed_tabActionTriggered(QAction* tabAction)
1693{
1694    DocumentView* tab = static_cast< DocumentView* >(tabAction->parent());
1695
1696    tab->setParent(m_tabWidget);
1697    tab->setVisible(true);
1698
1699    addTab(tab);
1700    m_tabsMenu->addAction(tabAction);
1701}
1702
1703void MainWindow::on_tabAction_triggered()
1704{
1705    for(int index = 0, count = m_tabWidget->count(); index < count; ++index)
1706    {
1707        if(sender()->parent() == m_tabWidget->widget(index))
1708        {
1709            m_tabWidget->setCurrentIndex(index);
1710
1711            break;
1712        }
1713    }
1714}
1715
1716void MainWindow::on_tabShortcut_activated()
1717{
1718    for(int index = 0; index < 9; ++index)
1719    {
1720        if(sender() == m_tabShortcuts[index])
1721        {
1722            m_tabWidget->setCurrentIndex(index);
1723
1724            break;
1725        }
1726    }
1727}
1728
1729void MainWindow::on_previousBookmark_triggered()
1730{
1731    if(const BookmarkModel* model = bookmarkModelForCurrentTab())
1732    {
1733        QList< int > pages;
1734
1735        for(int row = 0, rowCount = model->rowCount(); row < rowCount; ++row)
1736        {
1737            pages.append(model->index(row).data(BookmarkModel::PageRole).toInt());
1738        }
1739
1740        if(!pages.isEmpty())
1741        {
1742            qSort(pages);
1743
1744            QList< int >::const_iterator lowerBound = --qLowerBound(pages, currentTab()->currentPage());
1745
1746            if(lowerBound >= pages.constBegin())
1747            {
1748                currentTab()->jumpToPage(*lowerBound);
1749            }
1750            else
1751            {
1752                currentTab()->jumpToPage(pages.last());
1753            }
1754        }
1755    }
1756}
1757
1758void MainWindow::on_nextBookmark_triggered()
1759{
1760    if(const BookmarkModel* model = bookmarkModelForCurrentTab())
1761    {
1762        QList< int > pages;
1763
1764        for(int row = 0, rowCount = model->rowCount(); row < rowCount; ++row)
1765        {
1766            pages.append(model->index(row).data(BookmarkModel::PageRole).toInt());
1767        }
1768
1769        if(!pages.isEmpty())
1770        {
1771            qSort(pages);
1772
1773            QList< int >::const_iterator upperBound = qUpperBound(pages, currentTab()->currentPage());
1774
1775            if(upperBound < pages.constEnd())
1776            {
1777                currentTab()->jumpToPage(*upperBound);
1778            }
1779            else
1780            {
1781                currentTab()->jumpToPage(pages.first());
1782            }
1783        }
1784    }
1785}
1786
1787void MainWindow::on_addBookmark_triggered()
1788{
1789    const QString& currentPageLabel = s_settings->mainWindow().usePageLabel() || currentTab()->hasFrontMatter()
1790            ? currentTab()->pageLabelFromNumber(currentTab()->currentPage())
1791            : currentTab()->defaultPageLabelFromNumber(currentTab()->currentPage());
1792
1793    BookmarkItem bookmark(currentTab()->currentPage(), tr("Jump to page %1").arg(currentPageLabel));
1794
1795    BookmarkModel* model = bookmarkModelForCurrentTab(false);
1796
1797    if(model != 0)
1798    {
1799        model->findBookmark(bookmark);
1800    }
1801
1802    QScopedPointer< BookmarkDialog > dialog(new BookmarkDialog(bookmark, this));
1803
1804    if(dialog->exec() == QDialog::Accepted)
1805    {
1806        if(model == 0)
1807        {
1808            model = bookmarkModelForCurrentTab(true);
1809
1810            m_bookmarksView->setModel(model);
1811        }
1812
1813        model->addBookmark(bookmark);
1814
1815        m_bookmarksMenuIsDirty = true;
1816        scheduleSaveBookmarks();
1817    }
1818}
1819
1820void MainWindow::on_removeBookmark_triggered()
1821{
1822    BookmarkModel* model = bookmarkModelForCurrentTab();
1823
1824    if(model != 0)
1825    {
1826        model->removeBookmark(BookmarkItem(currentTab()->currentPage()));
1827
1828        if(model->isEmpty())
1829        {
1830            m_bookmarksView->setModel(0);
1831
1832            BookmarkModel::forgetPath(currentTab()->fileInfo().absoluteFilePath());
1833        }
1834
1835        m_bookmarksMenuIsDirty = true;
1836        scheduleSaveBookmarks();
1837    }
1838}
1839
1840void MainWindow::on_removeAllBookmarks_triggered()
1841{
1842    m_bookmarksView->setModel(0);
1843
1844    BookmarkModel::forgetAllPaths();
1845
1846    m_bookmarksMenuIsDirty = true;
1847    scheduleSaveBookmarks();
1848}
1849
1850void MainWindow::on_bookmarksMenu_aboutToShow()
1851{
1852    if(!m_bookmarksMenuIsDirty)
1853    {
1854        return;
1855    }
1856
1857    m_bookmarksMenuIsDirty = false;
1858
1859
1860    m_bookmarksMenu->clear();
1861
1862    m_bookmarksMenu->addActions(QList< QAction* >() << m_previousBookmarkAction << m_nextBookmarkAction);
1863    m_bookmarksMenu->addSeparator();
1864    m_bookmarksMenu->addActions(QList< QAction* >() << m_addBookmarkAction << m_removeBookmarkAction << m_removeAllBookmarksAction);
1865    m_bookmarksMenu->addSeparator();
1866
1867    foreach(const QString& absoluteFilePath, BookmarkModel::knownPaths())
1868    {
1869        const BookmarkModel* model = BookmarkModel::fromPath(absoluteFilePath);
1870
1871        BookmarkMenu* menu = new BookmarkMenu(QFileInfo(absoluteFilePath), m_bookmarksMenu);
1872
1873        for(int row = 0, rowCount = model->rowCount(); row < rowCount; ++row)
1874        {
1875            const QModelIndex index = model->index(row);
1876
1877            menu->addJumpToPageAction(index.data(BookmarkModel::PageRole).toInt(), index.data(BookmarkModel::LabelRole).toString());
1878        }
1879
1880        connect(menu, SIGNAL(openTriggered(QString)), SLOT(on_bookmark_openTriggered(QString)));
1881        connect(menu, SIGNAL(openInNewTabTriggered(QString)), SLOT(on_bookmark_openInNewTabTriggered(QString)));
1882        connect(menu, SIGNAL(jumpToPageTriggered(QString,int)), SLOT(on_bookmark_jumpToPageTriggered(QString,int)));
1883        connect(menu, SIGNAL(removeBookmarkTriggered(QString)), SLOT(on_bookmark_removeBookmarkTriggered(QString)));
1884
1885        m_bookmarksMenu->addMenu(menu);
1886    }
1887}
1888
1889void MainWindow::on_bookmark_openTriggered(const QString& absoluteFilePath)
1890{
1891    if(m_tabWidget->currentIndex() != -1)
1892    {
1893        open(absoluteFilePath);
1894    }
1895    else
1896    {
1897        openInNewTab(absoluteFilePath);
1898    }
1899}
1900
1901void MainWindow::on_bookmark_openInNewTabTriggered(const QString& absoluteFilePath)
1902{
1903    openInNewTab(absoluteFilePath);
1904}
1905
1906void MainWindow::on_bookmark_jumpToPageTriggered(const QString& absoluteFilePath, int page)
1907{
1908    jumpToPageOrOpenInNewTab(absoluteFilePath, page);
1909}
1910
1911void MainWindow::on_bookmark_removeBookmarkTriggered(const QString& absoluteFilePath)
1912{
1913    BookmarkModel* model = BookmarkModel::fromPath(absoluteFilePath);
1914
1915    if(model == m_bookmarksView->model())
1916    {
1917        m_bookmarksView->setModel(0);
1918    }
1919
1920    BookmarkModel::forgetPath(absoluteFilePath);
1921
1922    m_bookmarksMenuIsDirty = true;
1923    scheduleSaveBookmarks();
1924}
1925
1926void MainWindow::on_contents_triggered()
1927{
1928    if(m_helpDialog.isNull())
1929    {
1930        m_helpDialog = new HelpDialog();
1931
1932        m_helpDialog->show();
1933        m_helpDialog->setAttribute(Qt::WA_DeleteOnClose);
1934
1935        connect(this, SIGNAL(destroyed()), m_helpDialog, SLOT(close()));
1936    }
1937
1938    m_helpDialog->raise();
1939    m_helpDialog->activateWindow();
1940}
1941
1942void MainWindow::on_about_triggered()
1943{
1944    QString about1,about2,about3,about4,about5,about6,about7,about8,about9,about10;
1945    about1 = trUtf8("Terepaima es un lector de documentos PDF que verifica y muestra firmas electrónicas bajo el esquema PKI");
1946    about2 = trUtf8("Pueden visualizar el código del ");
1947    about3 = trUtf8("Para mayor información ver ");
1948    about4 = trUtf8("Esta aplicación esta basada en qpdfview ");
1949    about5 = trUtf8("Centro Nacional de Desarrollo e Investigación en Tecnologías Libres 2016");
1950    about6 = trUtf8("(Caracteristicas de firma electrónica)");
1951    about7 = trUtf8("Esta versión incluye:");
1952    about8 = trUtf8("José Sulbarán");
1953    about9 = trUtf8("José Joaquín Contreras");
1954    about10 = trUtf8("Diseñador:");
1955
1956    QMessageBox::about(this, tr("Acerca de Terepaima"), (tr("<p><b>Terepaima %1</b></p><p>").arg(APPLICATION_VERSION) + about1 + tr("</p><p>")  + about4 + tr(" <a href=\"https://launchpad.net/qpdfview\">launchpad.net/qpdfview</a></p>")
1957                                                      + "<p>" + about7 + "<ul>"
1958#ifdef WITH_PDF
1959                                                      + tr("<li>PDF support using Poppler %1</li>").arg(POPPLER_VERSION) + about6
1960#endif // WITH_PDF
1961#ifdef WITH_PS
1962                                                      + tr("<li>PS support using libspectre %1</li>").arg(LIBSPECTRE_VERSION)
1963#endif // WITH_PS
1964#ifdef WITH_DJVU
1965                                                      + tr("<li>DjVu support using DjVuLibre %1</li>").arg(DJVULIBRE_VERSION)
1966#endif // WITH_DJVU
1967#ifdef WITH_FITZ
1968                                                      + tr("<li>PDF support using Fitz %1</li>").arg(FITZ_VERSION)
1969#endif // WITH_FITZ
1970#ifdef WITH_CUPS
1971                                                      + tr("<li>Printing support using CUPS %1</li>").arg(CUPS_VERSION)
1972#endif // WITH_CUPS
1973                                                      + tr("</ul></p>"
1974                                                           "<p> Equipo de trabajo:<b> ") + about5 + tr(" </b> <a href=\"http://www.cenditel.gob.ve/\">CENDITEL</a></p></b>")
1975                                                      + tr("<b>Equipo Desarrollador:</b><ul>")
1976                                                      + tr("<li>Pedro Buitrago pbuitrago@cenditel.gob.ve</li>")
1977                                                      + tr("<li>Victor Bravo vbravo@cenditel.gob.ve</li>")
1978                                                      + tr("<li>Antonio Araujo aaraujo@cenditel.gob.ve</li>")
1979                                                      + tr("<li>Argenis Osorio aosorio@cenditel.gob.ve</li>")
1980                                                      + tr("<li>")+ about8 + tr(" jsulbaran@cenditel.gob.ve</li></ul>")
1981                                                      + tr("<b>") + about10 + tr("</b>")
1982                                                      + tr("<ul><li>Cipriano Alvarado calvarado@cenditel.gob.ve</li>")
1983                                                      + tr("</ul></p>"
1984                                                           "<p><b>Director de Desarrollo:</b><ul>")
1985                                                      + tr("<li>David Hernandez dhernandez@cenditel.gob.ve</li>")
1986                                                      + tr("</ul></p>"
1987                                                          "<p><b>Presidente de CENDITEL:</b><ul>")
1988                                                      + tr("<li>") + about9 + tr(" jcontreras@cenditel.gob.ve</li>")
1989                                                      + tr("</ul></p>"
1990                                                           "<p>") + about3 + tr("<a href=\"https://tibisay.cenditel.gob.ve/visorpdf\">Terepaima</a></p>"
1991                                                           "<p>")
1992                                                      + about2 + tr("<a href=\"https://tibisay.cenditel.gob.ve/visorpdf/browser/visorpdf\">Proyecto</a></p>")));
1993}
1994
1995void MainWindow::on_focusCurrentPage_activated()
1996{
1997    m_currentPageSpinBox->setFocus();
1998    m_currentPageSpinBox->selectAll();
1999}
2000
2001void MainWindow::on_focusScaleFactor_activated()
2002{
2003    m_scaleFactorComboBox->setFocus();
2004    m_scaleFactorComboBox->lineEdit()->selectAll();
2005}
2006
2007void MainWindow::on_toggleToolBars_triggered(bool checked)
2008{
2009    if(checked)
2010    {
2011        m_tabWidget->setTabBarPolicy(static_cast< TabWidget::TabBarPolicy >(m_tabBarHadPolicy));
2012
2013        m_fileToolBar->setVisible(m_fileToolBarWasVisible);
2014        m_editToolBar->setVisible(m_editToolBarWasVisible);
2015        m_viewToolBar->setVisible(m_viewToolBarWasVisible);
2016    }
2017    else
2018    {
2019        m_tabBarHadPolicy = static_cast< int >(m_tabWidget->tabBarPolicy());
2020
2021        m_fileToolBarWasVisible = m_fileToolBar->isVisible();
2022        m_editToolBarWasVisible = m_editToolBar->isVisible();
2023        m_viewToolBarWasVisible = m_viewToolBar->isVisible();
2024
2025        m_tabWidget->setTabBarPolicy(TabWidget::TabBarAlwaysOff);
2026
2027        m_fileToolBar->setVisible(false);
2028        m_editToolBar->setVisible(false);
2029        m_viewToolBar->setVisible(false);
2030    }
2031}
2032
2033void MainWindow::on_toggleMenuBar_triggered(bool checked)
2034{
2035    menuBar()->setVisible(checked);
2036}
2037
2038void MainWindow::on_searchInitiated(const QString& text, bool modified)
2039{
2040    if(text.isEmpty())
2041    {
2042        return;
2043    }
2044
2045    const bool allTabs = s_settings->mainWindow().extendedSearchDock() ? !modified : modified;
2046    const bool matchCase = m_matchCaseCheckBox->isChecked();
2047    const bool wholeWords = m_wholeWordsCheckBox->isChecked();
2048
2049    if(allTabs)
2050    {
2051        for(int index = 0, count = m_tabWidget->count(); index < count; ++index)
2052        {
2053            tab(index)->startSearch(text, matchCase, wholeWords);
2054        }
2055    }
2056    else
2057    {
2058        currentTab()->startSearch(text, matchCase, wholeWords);
2059    }
2060}
2061
2062void MainWindow::on_highlightAll_clicked(bool checked)
2063{
2064    currentTab()->setHighlightAll(checked);
2065}
2066
2067void MainWindow::on_dock_dockLocationChanged(Qt::DockWidgetArea area)
2068{
2069    QDockWidget* dock = qobject_cast< QDockWidget* >(sender());
2070
2071    if(dock == 0)
2072    {
2073        return;
2074    }
2075
2076    QDockWidget::DockWidgetFeatures features = dock->features();
2077
2078    if(area == Qt::TopDockWidgetArea || area == Qt::BottomDockWidgetArea)
2079    {
2080        features |= QDockWidget::DockWidgetVerticalTitleBar;
2081    }
2082    else
2083    {
2084        features &= ~QDockWidget::DockWidgetVerticalTitleBar;
2085    }
2086
2087    dock->setFeatures(features);
2088}
2089
2090void MainWindow::on_outline_sectionCountChanged()
2091{
2092    if(m_outlineView->header()->count() > 0)
2093    {
2094#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
2095
2096        m_outlineView->header()->setSectionResizeMode(0, QHeaderView::Stretch);
2097
2098#else
2099
2100        m_outlineView->header()->setResizeMode(0, QHeaderView::Stretch);
2101
2102#endif // QT_VERSION
2103    }
2104
2105    if(m_outlineView->header()->count() > 1)
2106    {
2107#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
2108
2109        m_outlineView->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
2110
2111#else
2112
2113        m_outlineView->header()->setResizeMode(1, QHeaderView::ResizeToContents);
2114
2115#endif // QT_VERSION
2116    }
2117
2118    m_outlineView->header()->setMinimumSectionSize(0);
2119    m_outlineView->header()->setStretchLastSection(false);
2120    m_outlineView->header()->setVisible(false);
2121}
2122
2123void MainWindow::on_outline_clicked(const QModelIndex& index)
2124{
2125    bool ok = false;
2126    const int page = index.data(Model::Document::PageRole).toInt(&ok);
2127    const qreal left = index.data(Model::Document::LeftRole).toReal();
2128    const qreal top = index.data(Model::Document::TopRole).toReal();
2129
2130    if(ok)
2131    {
2132        currentTab()->jumpToPage(page, true, left, top);
2133    }
2134}
2135
2136void MainWindow::on_properties_sectionCountChanged()
2137{
2138    qDebug("on_properties_sectionCountChanged()");
2139    if(m_propertiesView->horizontalHeader()->count() > 0)
2140    {
2141#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
2142
2143        m_propertiesView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
2144
2145#else
2146
2147        m_propertiesView->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch);
2148
2149#endif // QT_VERSION
2150    }
2151
2152    if(m_propertiesView->horizontalHeader()->count() > 1)
2153    {
2154#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
2155
2156        m_propertiesView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
2157
2158#else
2159
2160        m_propertiesView->horizontalHeader()->setResizeMode(1, QHeaderView::Stretch);
2161
2162#endif // QT_VERSION
2163    }
2164
2165    m_propertiesView->horizontalHeader()->setVisible(false);
2166
2167
2168    if(m_propertiesView->verticalHeader()->count() > 0)
2169    {
2170#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
2171
2172        m_propertiesView->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
2173
2174#else
2175
2176        m_propertiesView->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
2177
2178#endif // QT_VERSION
2179    }
2180
2181    m_propertiesView->verticalHeader()->setVisible(false);
2182}
2183
2184
2185void MainWindow::on_detailsSignatureView_sectionCountChanged()
2186{
2187    qDebug("Entro a on_detailsSignatureView_sectionCountChanged()");
2188}
2189
2190
2191void MainWindow::on_thumbnails_dockLocationChanged(Qt::DockWidgetArea area)
2192{
2193    qDebug("on_thumbnails_dockLocationChanged");
2194    for(int index = 0, count = m_tabWidget->count(); index < count; ++index)
2195    {
2196        tab(index)->setThumbnailsOrientation(area == Qt::TopDockWidgetArea || area == Qt::BottomDockWidgetArea ? Qt::Horizontal : Qt::Vertical);
2197    }
2198}
2199
2200void MainWindow::on_thumbnails_verticalScrollBar_valueChanged(int value)
2201{
2202    qDebug("on_thumbnails_verticalScrollBar_valueChanged");
2203    Q_UNUSED(value);
2204
2205    if(m_thumbnailsView->scene() != 0)
2206    {
2207        const QRectF visibleRect = m_thumbnailsView->mapToScene(m_thumbnailsView->viewport()->rect()).boundingRect();
2208
2209        foreach(ThumbnailItem* page, currentTab()->thumbnailItems())
2210        {
2211            if(!page->boundingRect().translated(page->pos()).intersects(visibleRect))
2212            {
2213                page->cancelRender();
2214            }
2215        }
2216    }
2217}
2218
2219void MainWindow::on_bookmarks_sectionCountChanged()
2220{
2221    qDebug("on_bookmarks_sectionCountChanged");
2222    if(m_bookmarksView->horizontalHeader()->count() > 0)
2223    {
2224#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
2225
2226        m_bookmarksView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
2227
2228#else
2229
2230        m_bookmarksView->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch);
2231
2232#endif // QT_VERSION
2233    }
2234
2235    if(m_bookmarksView->horizontalHeader()->count() > 1)
2236    {
2237#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
2238
2239        m_bookmarksView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
2240
2241#else
2242
2243        m_bookmarksView->horizontalHeader()->setResizeMode(1, QHeaderView::ResizeToContents);
2244
2245#endif // QT_VERSION
2246    }
2247
2248    m_bookmarksView->horizontalHeader()->setMinimumSectionSize(0);
2249    m_bookmarksView->horizontalHeader()->setStretchLastSection(false);
2250    m_bookmarksView->horizontalHeader()->setVisible(false);
2251
2252    if(m_bookmarksView->verticalHeader()->count() > 0)
2253    {
2254#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
2255
2256        m_bookmarksView->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
2257
2258#else
2259
2260        m_bookmarksView->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
2261
2262#endif // QT_VERSION
2263    }
2264
2265    m_bookmarksView->verticalHeader()->setVisible(false);
2266}
2267
2268void MainWindow::on_bookmarks_clicked(const QModelIndex& index)
2269{
2270    bool ok = false;
2271    const int page = index.data(BookmarkModel::PageRole).toInt(&ok);
2272
2273    if(ok)
2274    {
2275        currentTab()->jumpToPage(page);
2276    }
2277}
2278
2279void MainWindow::on_bookmarks_contextMenuRequested(const QPoint& pos)
2280{
2281    qDebug("on_bookmarks_contextMenuRequested");
2282    QMenu menu;
2283
2284    menu.addActions(QList< QAction* >() << m_previousBookmarkAction << m_nextBookmarkAction);
2285    menu.addSeparator();
2286    menu.addAction(m_addBookmarkAction);
2287
2288    QAction* removeBookmarkAction = menu.addAction(tr("&Remove bookmark"));
2289    QAction* editBookmarkAction = menu.addAction(tr("&Edit bookmark"));
2290
2291    const QModelIndex index = m_bookmarksView->indexAt(pos);
2292
2293    removeBookmarkAction->setVisible(index.isValid());
2294    editBookmarkAction->setVisible(index.isValid());
2295
2296    const QAction* action = menu.exec(m_bookmarksView->mapToGlobal(pos));
2297
2298    if(action == removeBookmarkAction)
2299    {
2300        BookmarkModel* model = qobject_cast< BookmarkModel* >(m_bookmarksView->model());
2301
2302        if(model != 0)
2303        {
2304            model->removeBookmark(BookmarkItem(index.data(BookmarkModel::PageRole).toInt()));
2305
2306            if(model->isEmpty())
2307            {
2308                m_bookmarksView->setModel(0);
2309
2310                BookmarkModel::forgetPath(currentTab()->fileInfo().absoluteFilePath());
2311            }
2312
2313            m_bookmarksMenuIsDirty = true;
2314            scheduleSaveBookmarks();
2315        }
2316
2317    }
2318    else if(action == editBookmarkAction)
2319    {
2320        BookmarkModel* model = qobject_cast< BookmarkModel* >(m_bookmarksView->model());
2321
2322        if(model != 0)
2323        {
2324            BookmarkItem bookmark(index.data(BookmarkModel::PageRole).toInt());
2325
2326            model->findBookmark(bookmark);
2327
2328            QScopedPointer< BookmarkDialog > dialog(new BookmarkDialog(bookmark, this));
2329
2330            if(dialog->exec() == QDialog::Accepted)
2331            {
2332                model->addBookmark(bookmark);
2333
2334                m_bookmarksMenuIsDirty = true;
2335                scheduleSaveBookmarks();
2336            }
2337        }
2338    }
2339}
2340
2341void MainWindow::on_search_sectionCountChanged()
2342{
2343    if(m_searchView->header()->count() > 0)
2344    {
2345#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
2346
2347        m_searchView->header()->setSectionResizeMode(0, QHeaderView::Stretch);
2348
2349#else
2350
2351        m_searchView->header()->setResizeMode(0, QHeaderView::Stretch);
2352
2353#endif // QT_VERSION
2354    }
2355
2356    m_searchView->header()->setMinimumSectionSize(0);
2357    m_searchView->header()->setStretchLastSection(false);
2358    m_searchView->header()->setVisible(false);
2359}
2360
2361void MainWindow::on_search_visibilityChanged(bool visible)
2362{
2363    if(!visible)
2364    {
2365        m_searchLineEdit->stopTimer();
2366        m_searchLineEdit->setProgress(0);
2367
2368        for(int index = 0, count = m_tabWidget->count(); index < count; ++index)
2369        {
2370            tab(index)->cancelSearch();
2371            tab(index)->clearResults();
2372        }
2373
2374        if(m_tabWidget->currentWidget() != 0)
2375        {
2376            m_tabWidget->currentWidget()->setFocus();
2377        }
2378    }
2379}
2380
2381void MainWindow::on_search_clicked(const QModelIndex& index)
2382{
2383    DocumentView* tab = SearchModel::instance()->viewForIndex(index);
2384
2385    m_tabWidget->setCurrentWidget(tab);
2386
2387    tab->findResult(index);
2388}
2389
2390void MainWindow::on_saveDatabase_timeout()
2391{
2392    if(s_settings->mainWindow().restoreTabs())
2393    {
2394        s_database->saveTabs(tabs());
2395    }
2396
2397    if(s_settings->mainWindow().restoreBookmarks())
2398    {
2399        s_database->saveBookmarks();
2400    }
2401
2402    if(s_settings->mainWindow().restorePerFileSettings())
2403    {
2404        foreach(DocumentView* tab, tabs())
2405        {
2406            s_database->savePerFileSettings(tab);
2407        }
2408    }
2409}
2410
2411bool MainWindow::eventFilter(QObject* target, QEvent* event)
2412{
2413    // This event filter is used to override any keyboard shortcuts if the outline widget has the focus.
2414    if(target == m_outlineView && event->type() == QEvent::ShortcutOverride)
2415    {
2416        QKeyEvent* keyEvent = static_cast< QKeyEvent* >(event);
2417
2418        const bool modifiers = keyEvent->modifiers().testFlag(Qt::ControlModifier) || keyEvent->modifiers().testFlag(Qt::ShiftModifier);
2419        const bool keys = keyEvent->key() == Qt::Key_Right || keyEvent->key() == Qt::Key_Left || keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down;
2420
2421        if(modifiers && keys)
2422        {
2423            keyEvent->accept();
2424            return true;
2425        }
2426    }
2427    // This event filter is used to fit the thumbnails into the thumbnails view if this is enabled in the settings.
2428    else if(target == m_thumbnailsView && event->type() == QEvent::Resize)
2429    {
2430        if(DocumentView* tab = currentTab())
2431        {
2432            tab->setThumbnailsViewportSize(m_thumbnailsView->viewport()->size());
2433        }
2434    }
2435
2436    return QMainWindow::eventFilter(target, event);
2437}
2438
2439void MainWindow::closeEvent(QCloseEvent* event)
2440{
2441    m_searchDock->setVisible(false);
2442
2443    for(int index = 0, count = m_tabWidget->count(); index < count; ++index)
2444    {
2445        if(!saveModifications(tab(index)))
2446        {
2447            m_tabWidget->setCurrentIndex(index);
2448
2449            event->setAccepted(false);
2450            return;
2451        }
2452    }
2453
2454    if(s_settings->mainWindow().restoreTabs())
2455    {
2456        s_database->saveTabs(tabs());
2457    }
2458    else
2459    {
2460        s_database->clearTabs();
2461    }
2462
2463    if(s_settings->mainWindow().restoreBookmarks())
2464    {
2465        s_database->saveBookmarks();
2466    }
2467    else
2468    {
2469        s_database->clearBookmarks();
2470    }
2471
2472    s_settings->mainWindow().setRecentlyUsed(s_settings->mainWindow().trackRecentlyUsed() ? m_recentlyUsedMenu->filePaths() : QStringList());
2473
2474    s_settings->documentView().setMatchCase(m_matchCaseCheckBox->isChecked());
2475    s_settings->documentView().setWholeWords(m_wholeWordsCheckBox->isChecked());
2476
2477    s_settings->mainWindow().setGeometry(m_fullscreenAction->isChecked() ? m_fullscreenAction->data().toByteArray() : saveGeometry());
2478    s_settings->mainWindow().setState(saveState());
2479
2480    QMainWindow::closeEvent(event);
2481}
2482
2483void MainWindow::dragEnterEvent(QDragEnterEvent* event)
2484{
2485    if(event->mimeData()->hasUrls())
2486    {
2487        event->acceptProposedAction();
2488    }
2489}
2490
2491void MainWindow::dropEvent(QDropEvent* event)
2492{
2493    if(event->mimeData()->hasUrls())
2494    {
2495        event->acceptProposedAction();
2496
2497        disconnectCurrentTabChanged();
2498
2499        foreach(const QUrl& url, event->mimeData()->urls())
2500        {
2501#if QT_VERSION >= QT_VERSION_CHECK(4,8,0)
2502            if(url.isLocalFile())
2503#else
2504            if(url.scheme() == "file")
2505#endif // QT_VERSION
2506            {
2507                openInNewTab(url.toLocalFile());
2508            }
2509        }
2510
2511        reconnectCurrentTabChanged();
2512    }
2513}
2514
2515void MainWindow::prepareStyle()
2516{
2517    if(s_settings->mainWindow().hasIconTheme())
2518    {
2519        QIcon::setThemeName(s_settings->mainWindow().iconTheme());
2520    }
2521
2522    if(s_settings->mainWindow().hasStyleSheet())
2523    {
2524        qApp->setStyleSheet(s_settings->mainWindow().styleSheet());
2525    }
2526
2527    ProxyStyle* style = new ProxyStyle();
2528
2529    style->setScrollableMenus(s_settings->mainWindow().scrollableMenus());
2530
2531    qApp->setStyle(style);
2532}
2533
2534inline DocumentView* MainWindow::currentTab() const
2535{
2536    return qobject_cast< DocumentView* >(m_tabWidget->currentWidget());
2537}
2538
2539inline DocumentView* MainWindow::tab(int index) const
2540{
2541    return qobject_cast< DocumentView* >(m_tabWidget->widget(index));
2542}
2543
2544QList< DocumentView* > MainWindow::tabs() const
2545{
2546    QList< DocumentView* > tabs;
2547
2548    for(int index = 0, count = m_tabWidget->count(); index < count; ++index)
2549    {
2550        tabs.append(tab(index));
2551    }
2552
2553    return tabs;
2554}
2555
2556bool MainWindow::senderIsCurrentTab() const
2557{
2558     return sender() == m_tabWidget->currentWidget() || qobject_cast< DocumentView* >(sender()) == 0;
2559}
2560
2561int MainWindow::addTab(DocumentView* tab)
2562{
2563    const int index = s_settings->mainWindow().newTabNextToCurrentTab() ?
2564                m_tabWidget->insertTab(m_tabWidget->currentIndex() + 1, tab, tab->title()) :
2565                m_tabWidget->addTab(tab, tab->title());
2566
2567    m_tabWidget->setTabToolTip(index, tab->fileInfo().absoluteFilePath());
2568    m_tabWidget->setCurrentIndex(index);
2569
2570    return index;
2571}
2572
2573void MainWindow::closeTab(DocumentView* tab)
2574{
2575    qDebug("** closeTab **");
2576
2577    if(s_settings->mainWindow().keepRecentlyClosed())
2578    {
2579        foreach(QAction* tabAction, m_tabsMenu->actions())
2580        {
2581            if(tabAction->parent() == tab)
2582            {
2583                m_tabsMenu->removeAction(tabAction);
2584                m_tabWidget->removeTab(m_tabWidget->indexOf(tab));
2585
2586                tab->setParent(this);
2587                tab->setVisible(false);
2588
2589                m_recentlyClosedMenu->addTabAction(tabAction);
2590
2591                break;
2592            }
2593        }
2594    }
2595    else
2596    {
2597        delete tab;
2598    }
2599
2600    if(s_settings->mainWindow().exitAfterLastTab() && m_tabWidget->count() == 0)
2601    {
2602        close();
2603    }
2604}
2605
2606bool MainWindow::saveModifications(DocumentView* tab)
2607{
2608    s_database->savePerFileSettings(tab);
2609    scheduleSaveTabs();
2610
2611    if(tab->wasModified())
2612    {
2613        const int button = QMessageBox::warning(this, tr("Warning"), tr("The document '%1' has been modified. Do you want to save your changes?").arg(tab->fileInfo().filePath()), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Save);
2614
2615        if(button == QMessageBox::Save)
2616        {
2617            const QString filePath = QFileDialog::getSaveFileName(this, tr("Save as"), tab->fileInfo().filePath(), tab->saveFilter().join(";;"));
2618
2619            if(!filePath.isEmpty())
2620            {
2621                if(tab->save(filePath, true))
2622                {
2623                    return true;
2624                }
2625                else
2626                {
2627                    QMessageBox::warning(this, tr("Warning"), tr("Could not save as '%1'.").arg(filePath));
2628                }
2629            }
2630        }
2631        else if(button == QMessageBox::Discard)
2632        {
2633            return true;
2634        }
2635
2636        return false;
2637    }
2638
2639    return true;
2640}
2641
2642void MainWindow::disconnectCurrentTabChanged()
2643{
2644    disconnect(m_tabWidget, SIGNAL(currentChanged(int)), this, SLOT(on_tabWidget_currentChanged(int)));
2645}
2646
2647void MainWindow::reconnectCurrentTabChanged()
2648{
2649    connect(m_tabWidget, SIGNAL(currentChanged(int)), this, SLOT(on_tabWidget_currentChanged(int)));
2650
2651    on_tabWidget_currentChanged(m_tabWidget->currentIndex());
2652}
2653
2654void MainWindow::setWindowTitleForCurrentTab()
2655{
2656    QString currentPage;
2657    QString tabText;
2658    QString instanceName;
2659
2660    if(m_tabWidget->currentIndex() != -1)
2661    {
2662        if(s_settings->mainWindow().currentPageInWindowTitle())
2663        {
2664            currentPage = QString(" (%1 / %2)").arg(currentTab()->currentPage()).arg(currentTab()->numberOfPages());
2665        }
2666
2667        tabText = m_tabWidget->tabText(m_tabWidget->currentIndex()) + currentPage + QLatin1String("[*] - ");
2668    }
2669
2670    if(s_settings->mainWindow().instanceNameInWindowTitle() && !qApp->objectName().isEmpty())
2671    {
2672        instanceName = QLatin1String(" (") + qApp->objectName() + QLatin1String(")");
2673    }
2674
2675//    setWindowTitle(tabText + QLatin1String("qpdfview") + instanceName);
2676    setWindowTitle(tabText + QLatin1String("Terepaima") + instanceName);
2677}
2678
2679void MainWindow::setCurrentPageSuffixForCurrentTab()
2680{
2681    QString suffix;
2682
2683    if(m_tabWidget->currentIndex() != -1)
2684    {
2685        const int currentPage = currentTab()->currentPage();
2686        const int numberOfPages = currentTab()->numberOfPages();
2687
2688        const QString& defaultPageLabel = currentTab()->defaultPageLabelFromNumber(currentPage);
2689        const QString& pageLabel = currentTab()->pageLabelFromNumber(currentPage);
2690
2691        const QString& lastDefaultPageLabel = currentTab()->defaultPageLabelFromNumber(numberOfPages);
2692
2693        if((s_settings->mainWindow().usePageLabel() || currentTab()->hasFrontMatter()) && defaultPageLabel != pageLabel)
2694        {
2695            suffix = QString(" (%1 / %2)").arg(defaultPageLabel).arg(lastDefaultPageLabel);
2696        }
2697        else
2698        {
2699            suffix = QString(" / %1").arg(lastDefaultPageLabel);
2700        }
2701    }
2702    else
2703    {
2704        suffix = QLatin1String(" / 1");
2705    }
2706
2707    m_currentPageSpinBox->setSuffix(suffix);
2708}
2709
2710BookmarkModel* MainWindow::bookmarkModelForCurrentTab(bool create)
2711{
2712    return BookmarkModel::fromPath(currentTab()->fileInfo().absoluteFilePath(), create);
2713}
2714
2715QAction* MainWindow::sourceLinkActionForCurrentTab(QObject* parent, const QPoint& pos)
2716{
2717    QAction* action = createTemporaryAction(parent, QString(), QLatin1String("openSourceLink"));
2718
2719    if(const DocumentView::SourceLink sourceLink = currentTab()->sourceLink(pos))
2720    {
2721        action->setText(tr("Edit '%1' at %2,%3...").arg(sourceLink.name).arg(sourceLink.line).arg(sourceLink.column));
2722        action->setData(QVariant::fromValue(sourceLink));
2723    }
2724    else
2725    {
2726        action->setVisible(false);
2727    }
2728
2729    return action;
2730}
2731
2732void MainWindow::prepareDatabase()
2733{
2734    if(s_database == 0)
2735    {
2736        s_database = Database::instance();
2737    }
2738
2739    m_saveDatabaseTimer = new QTimer(this);
2740    m_saveDatabaseTimer->setSingleShot(true);
2741    m_saveDatabaseTimer->setInterval(s_settings->mainWindow().saveDatabaseInterval());
2742
2743    connect(m_saveDatabaseTimer, SIGNAL(timeout()), SLOT(on_saveDatabase_timeout()));
2744}
2745
2746void MainWindow::scheduleSaveDatabase()
2747{
2748    if(!m_saveDatabaseTimer->isActive() && m_saveDatabaseTimer->interval() > 0)
2749    {
2750        m_saveDatabaseTimer->start();
2751    }
2752}
2753
2754void MainWindow::scheduleSaveTabs()
2755{
2756    if(s_settings->mainWindow().restoreTabs())
2757    {
2758        scheduleSaveDatabase();
2759    }
2760}
2761
2762void MainWindow::scheduleSaveBookmarks()
2763{
2764    if(s_settings->mainWindow().restoreBookmarks())
2765    {
2766        scheduleSaveDatabase();
2767    }
2768}
2769
2770void MainWindow::scheduleSavePerFileSettings()
2771{
2772    if(s_settings->mainWindow().restorePerFileSettings())
2773    {
2774        scheduleSaveDatabase();
2775    }
2776}
2777
2778void MainWindow::createWidgets()
2779{
2780    m_tabWidget = new TabWidget(this);
2781
2782    m_tabWidget->setDocumentMode(true);
2783    m_tabWidget->setMovable(true);
2784    m_tabWidget->setTabsClosable(true);
2785    m_tabWidget->setElideMode(Qt::ElideRight);
2786
2787    m_tabWidget->setTabPosition(static_cast< QTabWidget::TabPosition >(s_settings->mainWindow().tabPosition()));
2788    m_tabWidget->setTabBarPolicy(static_cast< TabWidget::TabBarPolicy >(s_settings->mainWindow().tabVisibility()));
2789    m_tabWidget->setSpreadTabs(s_settings->mainWindow().spreadTabs());
2790
2791    setCentralWidget(m_tabWidget);
2792
2793    connect(m_tabWidget, SIGNAL(currentChanged(int)), SLOT(on_tabWidget_currentChanged(int)));
2794    connect(m_tabWidget, SIGNAL(tabCloseRequested(int)), SLOT(on_tabWidget_tabCloseRequested(int)));
2795    connect(m_tabWidget, SIGNAL(tabContextMenuRequested(QPoint,int)), SLOT(on_tabWidget_tabContextMenuRequested(QPoint,int)));
2796
2797    // current page
2798
2799    m_currentPageSpinBox = new MappingSpinBox(new TextValueMapper(this), this);
2800
2801    m_currentPageSpinBox->setAlignment(Qt::AlignCenter);
2802    m_currentPageSpinBox->setButtonSymbols(QAbstractSpinBox::NoButtons);
2803    m_currentPageSpinBox->setKeyboardTracking(false);
2804
2805    connect(m_currentPageSpinBox, SIGNAL(editingFinished()), SLOT(on_currentPage_editingFinished()));
2806    connect(m_currentPageSpinBox, SIGNAL(returnPressed()), SLOT(on_currentPage_returnPressed()));
2807
2808    m_currentPageAction = new QWidgetAction(this);
2809
2810    m_currentPageAction->setObjectName(QLatin1String("currentPage"));
2811    m_currentPageAction->setDefaultWidget(m_currentPageSpinBox);
2812
2813    // scale factor
2814
2815    m_scaleFactorComboBox = new ComboBox(this);
2816
2817    m_scaleFactorComboBox->setEditable(true);
2818    m_scaleFactorComboBox->setInsertPolicy(QComboBox::NoInsert);
2819
2820    m_scaleFactorComboBox->addItem(tr("Page width"));
2821    m_scaleFactorComboBox->addItem(tr("Page size"));
2822    m_scaleFactorComboBox->addItem("50 %", 0.5);
2823    m_scaleFactorComboBox->addItem("75 %", 0.75);
2824    m_scaleFactorComboBox->addItem("100 %", 1.0);
2825    m_scaleFactorComboBox->addItem("125 %", 1.25);
2826    m_scaleFactorComboBox->addItem("150 %", 1.5);
2827    m_scaleFactorComboBox->addItem("200 %", 2.0);
2828    m_scaleFactorComboBox->addItem("300 %", 3.0);
2829    m_scaleFactorComboBox->addItem("400 %", 4.0);
2830    m_scaleFactorComboBox->addItem("500 %", 5.0);
2831
2832    connect(m_scaleFactorComboBox, SIGNAL(activated(int)), SLOT(on_scaleFactor_activated(int)));
2833    connect(m_scaleFactorComboBox->lineEdit(), SIGNAL(editingFinished()), SLOT(on_scaleFactor_editingFinished()));
2834    connect(m_scaleFactorComboBox->lineEdit(), SIGNAL(returnPressed()), SLOT(on_scaleFactor_returnPressed()));
2835
2836    m_scaleFactorAction = new QWidgetAction(this);
2837
2838    m_scaleFactorAction->setObjectName(QLatin1String("scaleFactor"));
2839    m_scaleFactorAction->setDefaultWidget(m_scaleFactorComboBox);
2840
2841    // search
2842
2843    m_searchLineEdit = new SearchLineEdit(this);
2844    m_matchCaseCheckBox = new QCheckBox(tr("Match &case"), this);
2845    m_wholeWordsCheckBox = new QCheckBox(tr("Whole &words"), this);
2846    m_highlightAllCheckBox = new QCheckBox(tr("Highlight &all"), this);
2847
2848    connect(m_searchLineEdit, SIGNAL(searchInitiated(QString,bool)), SLOT(on_searchInitiated(QString,bool)));
2849    connect(m_matchCaseCheckBox, SIGNAL(clicked()), m_searchLineEdit, SLOT(startTimer()));
2850    connect(m_wholeWordsCheckBox, SIGNAL(clicked()), m_searchLineEdit, SLOT(startTimer()));
2851    connect(m_highlightAllCheckBox, SIGNAL(clicked(bool)), SLOT(on_highlightAll_clicked(bool)));
2852
2853    m_matchCaseCheckBox->setChecked(s_settings->documentView().matchCase());
2854    m_wholeWordsCheckBox->setChecked(s_settings->documentView().wholeWords());
2855}
2856
2857QAction* MainWindow::createAction(const QString& text, const QString& objectName, const QIcon& icon, const QList< QKeySequence >& shortcuts, const char* member, bool checkable, bool checked)
2858{
2859    QAction* action = new QAction(text, this);
2860
2861    action->setObjectName(objectName);
2862    action->setIcon(icon);
2863    action->setShortcuts(shortcuts);
2864
2865    if(!objectName.isEmpty())
2866    {
2867        s_shortcutHandler->registerAction(action);
2868    }
2869
2870    if(checkable)
2871    {
2872        action->setCheckable(true);
2873        action->setChecked(checked);
2874
2875        connect(action, SIGNAL(triggered(bool)), member);
2876    }
2877    else
2878    {
2879        action->setIconVisibleInMenu(true);
2880
2881        connect(action, SIGNAL(triggered()), member);
2882    }
2883
2884    addAction(action);
2885
2886    return action;
2887}
2888
2889inline QAction* MainWindow::createAction(const QString& text, const QString& objectName, const QIcon& icon, const QKeySequence& shortcut, const char* member, bool checkable, bool checked)
2890{
2891    return createAction(text, objectName, icon, QList< QKeySequence >() << shortcut, member, checkable, checked);
2892}
2893
2894inline QAction* MainWindow::createAction(const QString& text, const QString& objectName, const QString& iconName, const QList< QKeySequence >& shortcuts, const char* member, bool checkable, bool checked)
2895{
2896    return createAction(text, objectName, loadIconWithFallback(iconName), shortcuts, member, checkable, checked);
2897}
2898
2899inline QAction* MainWindow::createAction(const QString& text, const QString& objectName, const QString& iconName, const QKeySequence& shortcut, const char* member, bool checkable, bool checked)
2900{
2901    return createAction(text, objectName, iconName, QList< QKeySequence >() << shortcut, member, checkable, checked);
2902}
2903
2904void MainWindow::createActions()
2905{
2906    // file
2907
2908    m_openAction = createAction(tr("&Open..."), QLatin1String("open"), QLatin1String("document-open"), QKeySequence::Open, SLOT(on_open_triggered()));
2909    m_openInNewTabAction = createAction(tr("Open in new &tab..."), QLatin1String("openInNewTab"), QLatin1String("tab-new"), QKeySequence::AddTab, SLOT(on_openInNewTab_triggered()));
2910    m_openCopyInNewTabAction = createAction(tr("Open &copy in new tab"), QLatin1String("openCopyInNewTab"), QLatin1String("tab-new"), QKeySequence(), SLOT(on_openCopyInNewTab_triggered()));
2911    m_openContainingFolderAction = createAction(tr("Open containing &folder"), QLatin1String("openContainingFolder"), QLatin1String("folder"), QKeySequence(), SLOT(on_openContainingFolder_triggered()));
2912    m_refreshAction = createAction(tr("&Refresh"), QLatin1String("refresh"), QLatin1String("view-refresh"), QKeySequence::Refresh, SLOT(on_refresh_triggered()));
2913    m_saveCopyAction = createAction(tr("&Save copy..."), QLatin1String("saveCopy"), QLatin1String("document-save"), QKeySequence::Save, SLOT(on_saveCopy_triggered()));
2914    m_saveAsAction = createAction(tr("Save &as..."), QLatin1String("saveAs"), QLatin1String("document-save-as"), QKeySequence::SaveAs, SLOT(on_saveAs_triggered()));
2915    m_printAction = createAction(tr("&Print..."), QLatin1String("print"), QLatin1String("document-print"), QKeySequence::Print, SLOT(on_print_triggered()));
2916    m_exitAction = createAction(tr("E&xit"), QLatin1String("exit"), QIcon::fromTheme("application-exit"), QKeySequence::Quit, SLOT(close()));
2917    //m_verify_signature = createAction(trUtf8("&Verificar firma electrónica..."), QLatin1String("Verify signature"), QLatin1String("icono_verificar"), QKeySequence(), SLOT(on_verify_signature()));
2918
2919    // edit
2920
2921    m_previousPageAction = createAction(tr("&Previous page"), QLatin1String("previousPage"), QLatin1String("go-previous"), QKeySequence(Qt::Key_Backspace), SLOT(on_previousPage_triggered()));
2922    m_nextPageAction = createAction(tr("&Next page"), QLatin1String("nextPage"), QLatin1String("go-next"), QKeySequence(Qt::Key_Space), SLOT(on_nextPage_triggered()));
2923    m_firstPageAction = createAction(tr("&First page"), QLatin1String("firstPage"), QLatin1String("go-first"), QList< QKeySequence >() << QKeySequence(Qt::Key_Home) << QKeySequence(Qt::KeypadModifier + Qt::Key_Home), SLOT(on_firstPage_triggered()));
2924    m_lastPageAction = createAction(tr("&Last page"), QLatin1String("lastPage"), QLatin1String("go-last"), QList< QKeySequence >() << QKeySequence(Qt::Key_End) << QKeySequence(Qt::KeypadModifier + Qt::Key_End), SLOT(on_lastPage_triggered()));
2925
2926    m_setFirstPageAction = createAction(tr("&Set first page..."), QLatin1String("setFirstPage"), QIcon(), QKeySequence(), SLOT(on_setFirstPage_triggered()));
2927
2928    m_jumpToPageAction = createAction(tr("&Jump to page..."), QLatin1String("jumpToPage"), QLatin1String("go-jump"), QKeySequence(Qt::CTRL + Qt::Key_J), SLOT(on_jumpToPage_triggered()));
2929
2930    m_jumpBackwardAction = createAction(tr("Jump &backward"), QLatin1String("jumpBackward"), QLatin1String("media-seek-backward"), QKeySequence(Qt::CTRL + Qt::Key_Return), SLOT(on_jumpBackward_triggered()));
2931    m_jumpForwardAction = createAction(tr("Jump for&ward"), QLatin1String("jumpForward"), QLatin1String("media-seek-forward"), QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Return), SLOT(on_jumpForward_triggered()));
2932
2933    m_searchAction = createAction(tr("&Search..."), QLatin1String("search"), QLatin1String("edit-find"), QKeySequence::Find, SLOT(on_search_triggered()));
2934    m_findPreviousAction = createAction(tr("Find previous"), QLatin1String("findPrevious"), QLatin1String("go-up"), QKeySequence::FindPrevious, SLOT(on_findPrevious_triggered()));
2935    m_findNextAction = createAction(tr("Find next"), QLatin1String("findNext"), QLatin1String("go-down"), QKeySequence::FindNext, SLOT(on_findNext_triggered()));
2936    m_cancelSearchAction = createAction(tr("Cancel search"), QLatin1String("cancelSearch"), QLatin1String("process-stop"), QKeySequence(Qt::Key_Escape), SLOT(on_cancelSearch_triggered()));
2937
2938    m_copyToClipboardModeAction = createAction(tr("&Copy to clipboard"), QLatin1String("copyToClipboardMode"), QLatin1String("edit-copy"), QKeySequence(Qt::CTRL + Qt::Key_C), SLOT(on_copyToClipboardMode_triggered(bool)), true);
2939    m_addAnnotationModeAction = createAction(tr("&Add annotation"), QLatin1String("addAnnotationMode"), QLatin1String("mail-attachment"), QKeySequence(Qt::CTRL + Qt::Key_A), SLOT(on_addAnnotationMode_triggered(bool)), true);
2940
2941    m_settingsAction = createAction(tr("Settings..."), QString(), QIcon(), QKeySequence(), SLOT(on_settings_triggered()));
2942
2943    // view
2944
2945    m_continuousModeAction = createAction(tr("&Continuous"), QLatin1String("continuousMode"), QIcon(QLatin1String(":icons/continuous.svg")), QKeySequence(Qt::CTRL + Qt::Key_7), SLOT(on_continuousMode_triggered(bool)), true);
2946    m_twoPagesModeAction = createAction(tr("&Two pages"), QLatin1String("twoPagesMode"), QIcon(QLatin1String(":icons/two-pages.svg")), QKeySequence(Qt::CTRL + Qt::Key_6), SLOT(on_twoPagesMode_triggered(bool)), true);
2947    m_twoPagesWithCoverPageModeAction = createAction(tr("Two pages &with cover page"), QLatin1String("twoPagesWithCoverPageMode"), QIcon(QLatin1String(":icons/two-pages-with-cover-page.svg")), QKeySequence(Qt::CTRL + Qt::Key_5), SLOT(on_twoPagesWithCoverPageMode_triggered(bool)), true);
2948    m_multiplePagesModeAction = createAction(tr("&Multiple pages"), QLatin1String("multiplePagesMode"), QIcon(QLatin1String(":icons/multiple-pages.svg")), QKeySequence(Qt::CTRL + Qt::Key_4), SLOT(on_multiplePagesMode_triggered(bool)), true);
2949
2950    m_rightToLeftModeAction = createAction(tr("Right to left"), QLatin1String("rightToLeftMode"), QIcon(QLatin1String(":icons/right-to-left.svg")), QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_R), SLOT(on_rightToLeftMode_triggered(bool)), true);
2951
2952    m_zoomInAction = createAction(tr("Zoom &in"), QLatin1String("zoomIn"), QLatin1String("zoom-in"), QKeySequence(Qt::CTRL + Qt::Key_Up), SLOT(on_zoomIn_triggered()));
2953    m_zoomOutAction = createAction(tr("Zoom &out"), QLatin1String("zoomOut"), QLatin1String("zoom-out"), QKeySequence(Qt::CTRL + Qt::Key_Down), SLOT(on_zoomOut_triggered()));
2954    m_originalSizeAction = createAction(tr("Original &size"), QLatin1String("originalSize"), QLatin1String("zoom-original"), QKeySequence(Qt::CTRL + Qt::Key_0), SLOT(on_originalSize_triggered()));
2955
2956    m_fitToPageWidthModeAction = createAction(tr("Fit to page width"), QLatin1String("fitToPageWidthMode"), QIcon(QLatin1String(":icons/fit-to-page-width.svg")), QKeySequence(Qt::CTRL + Qt::Key_9), SLOT(on_fitToPageWidthMode_triggered(bool)), true);
2957    m_fitToPageSizeModeAction = createAction(tr("Fit to page size"), QLatin1String("fitToPageSizeMode"), QIcon(QLatin1String(":icons/fit-to-page-size.svg")), QKeySequence(Qt::CTRL + Qt::Key_8), SLOT(on_fitToPageSizeMode_triggered(bool)), true);
2958
2959    m_rotateLeftAction = createAction(tr("Rotate &left"), QLatin1String("rotateLeft"), QLatin1String("object-rotate-left"), QKeySequence(Qt::CTRL + Qt::Key_Left), SLOT(on_rotateLeft_triggered()));
2960    m_rotateRightAction = createAction(tr("Rotate &right"), QLatin1String("rotateRight"), QLatin1String("object-rotate-right"), QKeySequence(Qt::CTRL + Qt::Key_Right), SLOT(on_rotateRight_triggered()));
2961
2962    m_invertColorsAction = createAction(tr("Invert colors"), QLatin1String("invertColors"), QIcon(), QKeySequence(Qt::CTRL + Qt::Key_I), SLOT(on_invertColors_triggered(bool)), true);
2963    m_convertToGrayscaleAction = createAction(tr("Convert to grayscale"), QLatin1String("convertToGrayscale"), QIcon(), QKeySequence(Qt::CTRL + Qt::Key_U), SLOT(on_convertToGrayscale_triggered(bool)), true);
2964    m_trimMarginsAction = createAction(tr("Trim margins"), QLatin1String("trimMargins"), QIcon(), QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_U), SLOT(on_trimMargins_triggered(bool)), true);
2965
2966    m_darkenWithPaperColorAction = createAction(tr("Darken with paper color"), QLatin1String("darkenWithPaperColor"), QIcon(), QKeySequence(), SLOT(on_darkenWithPaperColor_triggered(bool)), true);
2967    m_lightenWithPaperColorAction = createAction(tr("Lighten with paper color"), QLatin1String("lightenWithPaperColor"), QIcon(), QKeySequence(), SLOT(on_lightenWithPaperColor_triggered(bool)), true);
2968
2969    m_fontsAction = createAction(tr("Fonts..."), QString(), QIcon(), QKeySequence(), SLOT(on_fonts_triggered()));
2970
2971    m_fullscreenAction = createAction(tr("&Fullscreen"), QLatin1String("fullscreen"), QLatin1String("view-fullscreen"), QKeySequence(Qt::Key_F11), SLOT(on_fullscreen_triggered(bool)), true);
2972    m_presentationAction = createAction(tr("&Presentation..."), QLatin1String("presentation"), QLatin1String("x-office-presentation"), QKeySequence(Qt::Key_F12), SLOT(on_presentation_triggered()));
2973
2974    // tabs
2975
2976    m_previousTabAction = createAction(tr("&Previous tab"), QLatin1String("previousTab"), QIcon(), QKeySequence::PreviousChild, SLOT(on_previousTab_triggered()));
2977    m_nextTabAction = createAction(tr("&Next tab"), QLatin1String("nextTab"), QIcon(), QKeySequence::NextChild, SLOT(on_nextTab_triggered()));
2978
2979    m_closeTabAction = createAction(tr("&Close tab"), QLatin1String("closeTab"), QIcon::fromTheme("window-close"), QKeySequence(Qt::CTRL + Qt::Key_W), SLOT(on_closeTab_triggered()));
2980    m_closeAllTabsAction = createAction(tr("Close &all tabs"), QLatin1String("closeAllTabs"), QIcon(), QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_W), SLOT(on_closeAllTabs_triggered()));
2981    m_closeAllTabsButCurrentTabAction = createAction(tr("Close all tabs &but current tab"), QLatin1String("closeAllTabsButCurrent"), QIcon(), QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_W), SLOT(on_closeAllTabsButCurrentTab_triggered()));
2982
2983    m_restoreMostRecentlyClosedTabAction = createAction(tr("Restore &most recently closed tab"), QLatin1String("restoreMostRecentlyClosedTab"), QIcon(), QKeySequence(Qt::ALT + Qt::SHIFT + Qt::Key_W), SLOT(on_restoreMostRecentlyClosedTab_triggered()));
2984
2985    // tab shortcuts
2986
2987    for(int index = 0; index < 9; ++index)
2988    {
2989        m_tabShortcuts[index] = new QShortcut(QKeySequence(Qt::ALT + Qt::Key_1 + index), this, SLOT(on_tabShortcut_activated()));
2990    }
2991
2992    // bookmarks
2993
2994    m_previousBookmarkAction = createAction(tr("&Previous bookmark"), QLatin1String("previousBookmarkAction"), QIcon(), QKeySequence(Qt::CTRL + Qt::Key_PageUp), SLOT(on_previousBookmark_triggered()));
2995    m_nextBookmarkAction = createAction(tr("&Next bookmark"), QLatin1String("nextBookmarkAction"), QIcon(), QKeySequence(Qt::CTRL + Qt::Key_PageDown), SLOT(on_nextBookmark_triggered()));
2996
2997    m_addBookmarkAction = createAction(tr("&Add bookmark"), QLatin1String("addBookmark"), QIcon(), QKeySequence(Qt::CTRL + Qt::Key_B), SLOT(on_addBookmark_triggered()));
2998    m_removeBookmarkAction = createAction(tr("&Remove bookmark"), QLatin1String("removeBookmark"), QIcon(), QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_B), SLOT(on_removeBookmark_triggered()));
2999    m_removeAllBookmarksAction = createAction(tr("Remove all bookmarks"), QLatin1String("removeAllBookmark"), QIcon(), QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_B), SLOT(on_removeAllBookmarks_triggered()));
3000
3001    // help
3002
3003    m_contentsAction = createAction(tr("&Contents"), QLatin1String("contents"), QIcon::fromTheme("help-contents"), QKeySequence::HelpContents, SLOT(on_contents_triggered()));
3004    m_aboutAction = createAction(tr("&About"), QString(), QIcon::fromTheme("help-about"), QKeySequence(), SLOT(on_about_triggered()));
3005
3006    // tool bars and menu bar
3007
3008    m_toggleToolBarsAction = createAction(tr("Toggle tool bars"), QLatin1String("toggleToolBars"), QIcon(), QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_T), SLOT(on_toggleToolBars_triggered(bool)), true, true);
3009    m_toggleMenuBarAction = createAction(tr("Toggle menu bar"), QLatin1String("toggleMenuBar"), QIcon(), QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_M), SLOT(on_toggleMenuBar_triggered(bool)), true, true);
3010
3011    // progress and error icons
3012
3013    s_settings->pageItem().setProgressIcon(loadIconWithFallback(QLatin1String("image-loading")));
3014    s_settings->pageItem().setErrorIcon(loadIconWithFallback(QLatin1String("image-missing")));
3015
3016    //security
3017    m_signature = createAction(trUtf8("&Signature..."), QLatin1String("Signature"), QLatin1String("icono_firmar"), QKeySequence(), SLOT(on_signature()));
3018    m_verify_signature = createAction(trUtf8("&Verificar firma electrónica..."), QLatin1String("Verify signature"), QLatin1String("icono_verificar"), QKeySequence(), SLOT(on_verify_signature()));
3019}
3020
3021QToolBar* MainWindow::createToolBar(const QString& text, const QString& objectName, const QStringList& actionNames, const QList< QAction* >& actions)
3022{
3023    QToolBar* toolBar = addToolBar(text);
3024    toolBar->setObjectName(objectName);
3025
3026    addWidgetActions(toolBar, actionNames, actions);
3027
3028    toolBar->toggleViewAction()->setObjectName(objectName + QLatin1String("ToggleView"));
3029    s_shortcutHandler->registerAction(toolBar->toggleViewAction());
3030
3031    return toolBar;
3032}
3033
3034void MainWindow::createToolBars()
3035{
3036    m_fileToolBar = createToolBar(tr("&File"), QLatin1String("fileToolBar"), s_settings->mainWindow().fileToolBar(),
3037                                  //QList< QAction* >() << m_openAction << m_openInNewTabAction << m_openContainingFolderAction << m_refreshAction << m_saveCopyAction << m_saveAsAction << m_printAction << m_verify_signature);
3038                                  QList< QAction* >() << m_openAction << m_openInNewTabAction << m_openContainingFolderAction << m_refreshAction << m_saveCopyAction << m_saveAsAction << m_printAction);
3039    m_editToolBar = createToolBar(tr("&Edit"), QLatin1String("editToolBar"), s_settings->mainWindow().editToolBar(),
3040                                  QList< QAction* >() << m_currentPageAction << m_previousPageAction << m_nextPageAction << m_firstPageAction << m_lastPageAction << m_jumpToPageAction << m_searchAction << m_jumpBackwardAction << m_jumpForwardAction << m_copyToClipboardModeAction << m_addAnnotationModeAction);
3041
3042    m_viewToolBar = createToolBar(tr("&View"), QLatin1String("viewToolBar"), s_settings->mainWindow().viewToolBar(),
3043                                  QList< QAction* >() << m_scaleFactorAction << m_continuousModeAction << m_twoPagesModeAction << m_twoPagesWithCoverPageModeAction << m_multiplePagesModeAction << m_rightToLeftModeAction << m_zoomInAction << m_zoomOutAction << m_originalSizeAction << m_fitToPageWidthModeAction << m_fitToPageSizeModeAction << m_rotateLeftAction << m_rotateRightAction << m_fullscreenAction << m_presentationAction);
3044
3045    m_focusCurrentPageShortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_K), this, SLOT(on_focusCurrentPage_activated()));
3046    m_focusScaleFactorShortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_L), this, SLOT(on_focusScaleFactor_activated()));
3047}
3048
3049QDockWidget* MainWindow::createDock(const QString& text, const QString& objectName, const QKeySequence& toggleViewShortcut)
3050{
3051    QDockWidget* dock = new QDockWidget(text, this);
3052    dock->setObjectName(objectName);
3053    dock->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable);
3054
3055#ifdef Q_OS_WIN
3056
3057    dock->setWindowTitle(dock->windowTitle().remove(QLatin1Char('&')));
3058
3059#endif // Q_OS_WIN
3060
3061    addDockWidget(Qt::LeftDockWidgetArea, dock);
3062
3063    connect(dock, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)), SLOT(on_dock_dockLocationChanged(Qt::DockWidgetArea)));
3064
3065    dock->toggleViewAction()->setObjectName(objectName + QLatin1String("ToggleView"));
3066    dock->toggleViewAction()->setShortcut(toggleViewShortcut);
3067
3068    s_shortcutHandler->registerAction(dock->toggleViewAction());
3069
3070    dock->hide();
3071
3072    return dock;
3073}
3074
3075void MainWindow::createSearchDock()
3076{
3077    m_searchDock = new QDockWidget(tr("&Search"), this);
3078    m_searchDock->setObjectName(QLatin1String("searchDock"));
3079    m_searchDock->setFeatures(QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetVerticalTitleBar);
3080
3081#ifdef Q_OS_WIN
3082
3083    m_searchDock->setWindowTitle(m_searchDock->windowTitle().remove(QLatin1Char('&')));
3084
3085#endif // Q_OS_WIN
3086
3087    addDockWidget(Qt::BottomDockWidgetArea, m_searchDock);
3088
3089    connect(m_searchDock, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)), SLOT(on_dock_dockLocationChanged(Qt::DockWidgetArea)));
3090    connect(m_searchDock, SIGNAL(visibilityChanged(bool)), SLOT(on_search_visibilityChanged(bool)));
3091
3092    m_searchWidget = new QWidget(this);
3093
3094    QToolButton* findPreviousButton = new QToolButton(m_searchWidget);
3095    findPreviousButton->setAutoRaise(true);
3096    findPreviousButton->setDefaultAction(m_findPreviousAction);
3097
3098    QToolButton* findNextButton = new QToolButton(m_searchWidget);
3099    findNextButton->setAutoRaise(true);
3100    findNextButton->setDefaultAction(m_findNextAction);
3101
3102    QToolButton* cancelSearchButton = new QToolButton(m_searchWidget);
3103    cancelSearchButton->setAutoRaise(true);
3104    cancelSearchButton->setDefaultAction(m_cancelSearchAction);
3105
3106    QGridLayout* searchLayout = new QGridLayout(m_searchWidget);
3107    searchLayout->setRowStretch(2, 1);
3108    searchLayout->setColumnStretch(2, 1);
3109    searchLayout->addWidget(m_searchLineEdit, 0, 0, 1, 7);
3110    searchLayout->addWidget(m_matchCaseCheckBox, 1, 0);
3111    searchLayout->addWidget(m_wholeWordsCheckBox, 1, 1);
3112    searchLayout->addWidget(m_highlightAllCheckBox, 1, 2);
3113    searchLayout->addWidget(findPreviousButton, 1, 4);
3114    searchLayout->addWidget(findNextButton, 1, 5);
3115    searchLayout->addWidget(cancelSearchButton, 1, 6);
3116
3117    m_searchDock->setWidget(m_searchWidget);
3118
3119    connect(m_searchDock, SIGNAL(visibilityChanged(bool)), m_findPreviousAction, SLOT(setEnabled(bool)));
3120    connect(m_searchDock, SIGNAL(visibilityChanged(bool)), m_findNextAction, SLOT(setEnabled(bool)));
3121    connect(m_searchDock, SIGNAL(visibilityChanged(bool)), m_cancelSearchAction, SLOT(setEnabled(bool)));
3122
3123    m_searchDock->setVisible(false);
3124
3125    m_findPreviousAction->setEnabled(false);
3126    m_findNextAction->setEnabled(false);
3127    m_cancelSearchAction->setEnabled(false);
3128
3129    if(s_settings->mainWindow().extendedSearchDock())
3130    {
3131        m_searchDock->setFeatures(m_searchDock->features() | QDockWidget::DockWidgetClosable);
3132
3133        m_searchDock->toggleViewAction()->setObjectName(QLatin1String("searchDockToggleView"));
3134        m_searchDock->toggleViewAction()->setShortcut(QKeySequence(Qt::Key_F10));
3135
3136        s_shortcutHandler->registerAction(m_searchDock->toggleViewAction());
3137
3138        m_searchView = new QTreeView(m_searchWidget);
3139        m_searchView->setAlternatingRowColors(true);
3140        m_searchView->setUniformRowHeights(true);
3141        m_searchView->setEditTriggers(QAbstractItemView::NoEditTriggers);
3142        m_searchView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
3143        m_searchView->setSelectionMode(QAbstractItemView::SingleSelection);
3144        m_searchView->setSelectionBehavior(QAbstractItemView::SelectRows);
3145
3146        connect(m_searchView->header(), SIGNAL(sectionCountChanged(int,int)), SLOT(on_search_sectionCountChanged()));
3147        connect(m_searchView, SIGNAL(clicked(QModelIndex)), SLOT(on_search_clicked(QModelIndex)));
3148        connect(m_searchView, SIGNAL(activated(QModelIndex)), SLOT(on_search_clicked(QModelIndex)));
3149
3150        m_searchView->setItemDelegate(new SearchItemDelegate(m_searchView));
3151        m_searchView->setModel(SearchModel::instance());
3152
3153        searchLayout->addWidget(m_searchView, 2, 0, 1, 6);
3154    }
3155    else
3156    {
3157        m_searchView = 0;
3158    }
3159}
3160
3161void MainWindow::createDocks()
3162{
3163    // outline
3164    qDebug("createDocks()");
3165    m_outlineDock = createDock(tr("&Outline"), QLatin1String("outlineDock"), QKeySequence(Qt::Key_F6));
3166
3167    m_outlineView = new TreeView(Model::Document::ExpansionRole, this);
3168    m_outlineView->setAlternatingRowColors(true);
3169    m_outlineView->setEditTriggers(QAbstractItemView::NoEditTriggers);
3170    m_outlineView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
3171    m_outlineView->setSelectionMode(QAbstractItemView::SingleSelection);
3172    m_outlineView->setSelectionBehavior(QAbstractItemView::SelectRows);
3173
3174    m_outlineView->installEventFilter(this);
3175
3176    connect(m_outlineView->header(), SIGNAL(sectionCountChanged(int,int)), SLOT(on_outline_sectionCountChanged()));
3177    connect(m_outlineView, SIGNAL(clicked(QModelIndex)), SLOT(on_outline_clicked(QModelIndex)));
3178    connect(m_outlineView, SIGNAL(activated(QModelIndex)), SLOT(on_outline_clicked(QModelIndex)));
3179
3180    m_outlineDock->setWidget(m_outlineView);
3181
3182    // properties
3183
3184    m_propertiesDock = createDock(tr("&Properties"), QLatin1String("propertiesDock"), QKeySequence(Qt::Key_F7));
3185
3186    m_propertiesView = new QTableView(this);
3187    m_propertiesView->setAlternatingRowColors(true);
3188    m_propertiesView->setTabKeyNavigation(false);
3189    m_propertiesView->setEditTriggers(QAbstractItemView::NoEditTriggers);
3190    m_propertiesView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
3191
3192    connect(m_propertiesView->horizontalHeader(), SIGNAL(sectionCountChanged(int,int)), SLOT(on_properties_sectionCountChanged()));
3193
3194    m_propertiesDock->setWidget(m_propertiesView);
3195
3196    //______________________________________________________________
3197    // verify signature
3198    m_detailsSignatureDock = createDock(trUtf8("&Verificar firma electrónica"), QLatin1String("verifySignature-Dock"), QKeySequence(Qt::Key_F12));
3199    //m_detailsSignatureDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
3200    //QStringList itens;
3201    //m_detailsSignatureView = new QListWidget(m_detailsSignatureDock);
3202    m_detailsSignatureView = new QTableView(this);
3203    m_detailsSignatureView->setAlternatingRowColors(true);
3204    m_detailsSignatureView->setTabKeyNavigation(false);
3205    m_detailsSignatureView->setEditTriggers(QAbstractItemView::NoEditTriggers);
3206    m_detailsSignatureView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
3207    m_detailsSignatureView->verticalHeader()->hide();
3208
3209        //prueba->addItems(QStringList() << verify_signature().toStdString());
3210//    QStringList itens;
3211//    itens << "Cargar archivo PDF para verificar la firma ";
3212////    for(int i = 0; i<1; i++) {
3213
3214////            itens << "Cargar archivo PDF para verificar la firma " + QString::number(i);
3215////        }
3216//    m_detailsSignatureView->addItems(itens);
3217
3218//    m_detailsSignatureDock->setWidget(m_detailsSignatureView);
3219
3220
3221   connect(m_detailsSignatureView->horizontalHeader(), SIGNAL(sectionCountChanged(int,int)), SLOT(on_detailsSignatureView_sectionCountChanged()));
3222   //connect(m_detailsSignatureView, SIGNAL(valueChanged(int)), SLOT(on_detailsSignatureView_sectionCountChanged()));
3223
3224    m_detailsSignatureDock->setWidget(m_detailsSignatureView);
3225    //______________________________________________________________
3226
3227    // thumbnails
3228
3229    m_thumbnailsDock = createDock(tr("Thumb&nails"), QLatin1String("thumbnailsDock"), QKeySequence(Qt::Key_F8));
3230
3231    connect(m_thumbnailsDock, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)), SLOT(on_thumbnails_dockLocationChanged(Qt::DockWidgetArea)));
3232
3233    m_thumbnailsView = new QGraphicsView(this);
3234
3235    m_thumbnailsView->installEventFilter(this);
3236
3237    connect(m_thumbnailsView->verticalScrollBar(), SIGNAL(valueChanged(int)), SLOT(on_thumbnails_verticalScrollBar_valueChanged(int)));
3238
3239    m_thumbnailsDock->setWidget(m_thumbnailsView);
3240
3241    // bookmarks
3242
3243    m_bookmarksDock = createDock(tr("Book&marks"), QLatin1String("bookmarksDock"), QKeySequence(Qt::Key_F9));
3244
3245    m_bookmarksView = new QTableView(this);
3246    m_bookmarksView->setShowGrid(false);
3247    m_bookmarksView->setAlternatingRowColors(true);
3248    m_bookmarksView->setEditTriggers(QAbstractItemView::NoEditTriggers);
3249    m_bookmarksView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
3250    m_bookmarksView->setSelectionMode(QAbstractItemView::SingleSelection);
3251    m_bookmarksView->setSelectionBehavior(QAbstractItemView::SelectRows);
3252    m_bookmarksView->setContextMenuPolicy(Qt::CustomContextMenu);
3253
3254    connect(m_bookmarksView->horizontalHeader(), SIGNAL(sectionCountChanged(int,int)), SLOT(on_bookmarks_sectionCountChanged()));
3255    connect(m_bookmarksView, SIGNAL(clicked(QModelIndex)), SLOT(on_bookmarks_clicked(QModelIndex)));
3256    connect(m_bookmarksView, SIGNAL(activated(QModelIndex)), SLOT(on_bookmarks_clicked(QModelIndex)));
3257    connect(m_bookmarksView, SIGNAL(customContextMenuRequested(QPoint)), SLOT(on_bookmarks_contextMenuRequested(QPoint)));
3258
3259    m_bookmarksDock->setWidget(m_bookmarksView);
3260
3261    // search
3262
3263    createSearchDock();
3264}
3265
3266void MainWindow::createMenus()
3267{
3268    // file
3269
3270    m_fileMenu = menuBar()->addMenu(tr("&File"));
3271    m_fileMenu->addActions(QList< QAction* >() << m_openAction << m_openInNewTabAction);
3272
3273    m_recentlyUsedMenu = new RecentlyUsedMenu(s_settings->mainWindow().recentlyUsed(), s_settings->mainWindow().recentlyUsedCount(), this);
3274
3275    connect(m_recentlyUsedMenu, SIGNAL(openTriggered(QString)), SLOT(on_recentlyUsed_openTriggered(QString)));
3276
3277    if(s_settings->mainWindow().trackRecentlyUsed())
3278    {
3279        m_fileMenu->addMenu(m_recentlyUsedMenu);
3280
3281        setToolButtonMenu(m_fileToolBar, m_openAction, m_recentlyUsedMenu);
3282        setToolButtonMenu(m_fileToolBar, m_openInNewTabAction, m_recentlyUsedMenu);
3283    }
3284
3285    //m_fileMenu->addActions(QList< QAction* >() << m_refreshAction << m_saveCopyAction << m_saveAsAction << m_printAction << m_verify_signature);
3286    m_fileMenu->addActions(QList< QAction* >() << m_refreshAction << m_saveCopyAction << m_saveAsAction << m_printAction);
3287    m_fileMenu->addSeparator();
3288    m_fileMenu->addAction(m_exitAction);
3289
3290    // edit
3291
3292    m_editMenu = menuBar()->addMenu(tr("&Edit"));
3293    m_editMenu->addActions(QList< QAction* >() << m_previousPageAction << m_nextPageAction << m_firstPageAction << m_lastPageAction << m_jumpToPageAction);
3294    m_editMenu->addSeparator();
3295    m_editMenu->addActions(QList< QAction* >() << m_jumpBackwardAction << m_jumpForwardAction);
3296    m_editMenu->addSeparator();
3297    m_editMenu->addActions(QList< QAction* >() << m_searchAction << m_findPreviousAction << m_findNextAction << m_cancelSearchAction);
3298    m_editMenu->addSeparator();
3299    m_editMenu->addActions(QList< QAction* >() << m_copyToClipboardModeAction << m_addAnnotationModeAction);
3300    m_editMenu->addSeparator();
3301    m_editMenu->addAction(m_settingsAction);
3302
3303    // view
3304
3305    m_viewMenu = menuBar()->addMenu(tr("&View"));
3306    m_viewMenu->addActions(QList< QAction* >() << m_continuousModeAction << m_twoPagesModeAction << m_twoPagesWithCoverPageModeAction << m_multiplePagesModeAction);
3307    m_viewMenu->addSeparator();
3308    m_viewMenu->addAction(m_rightToLeftModeAction);
3309    m_viewMenu->addSeparator();
3310    m_viewMenu->addActions(QList< QAction* >() << m_zoomInAction << m_zoomOutAction << m_originalSizeAction << m_fitToPageWidthModeAction << m_fitToPageSizeModeAction);
3311    m_viewMenu->addSeparator();
3312    m_viewMenu->addActions(QList< QAction* >() << m_rotateLeftAction << m_rotateRightAction);
3313    m_viewMenu->addSeparator();
3314    m_viewMenu->addActions(QList< QAction* >() << m_invertColorsAction << m_convertToGrayscaleAction << m_trimMarginsAction);
3315
3316    m_compositionModeMenu = m_viewMenu->addMenu(tr("Composition"));
3317    m_compositionModeMenu->addAction(m_darkenWithPaperColorAction);
3318    m_compositionModeMenu->addAction(m_lightenWithPaperColorAction);
3319
3320    m_viewMenu->addSeparator();
3321
3322    QMenu* toolBarsMenu = m_viewMenu->addMenu(tr("&Tool bars"));
3323    toolBarsMenu->addActions(QList< QAction* >() << m_fileToolBar->toggleViewAction() << m_editToolBar->toggleViewAction() << m_viewToolBar->toggleViewAction());
3324
3325    QMenu* docksMenu = m_viewMenu->addMenu(tr("&Docks"));
3326    //docksMenu->addActions(QList< QAction* >() << m_outlineDock->toggleViewAction() << m_propertiesDock->toggleViewAction() << m_thumbnailsDock->toggleViewAction() << m_bookmarksDock->toggleViewAction() << m_detailsSignatureDock->toggleViewAction());
3327    docksMenu->addActions(QList< QAction* >() << m_outlineDock->toggleViewAction() << m_propertiesDock->toggleViewAction() << m_thumbnailsDock->toggleViewAction() << m_bookmarksDock->toggleViewAction());
3328
3329    if(s_settings->mainWindow().extendedSearchDock())
3330    {
3331        docksMenu->addAction(m_searchDock->toggleViewAction());
3332    }
3333
3334    m_viewMenu->addAction(m_fontsAction);
3335    m_viewMenu->addSeparator();
3336    m_viewMenu->addActions(QList< QAction* >() << m_fullscreenAction << m_presentationAction);
3337
3338    // tabs
3339
3340    m_tabsMenu = new SearchableMenu(tr("&Tabs"), this);
3341    menuBar()->addMenu(m_tabsMenu);
3342
3343    m_tabsMenu->setSearchable(s_settings->mainWindow().searchableMenus());
3344
3345    m_tabsMenu->addActions(QList< QAction* >() << m_previousTabAction << m_nextTabAction);
3346    m_tabsMenu->addSeparator();
3347    m_tabsMenu->addActions(QList< QAction* >() << m_closeTabAction << m_closeAllTabsAction << m_closeAllTabsButCurrentTabAction);
3348
3349    m_recentlyClosedMenu = new RecentlyClosedMenu(s_settings->mainWindow().recentlyClosedCount(), this);
3350
3351    connect(m_recentlyClosedMenu, SIGNAL(tabActionTriggered(QAction*)), SLOT(on_recentlyClosed_tabActionTriggered(QAction*)));
3352
3353    if(s_settings->mainWindow().keepRecentlyClosed())
3354    {
3355        m_tabsMenu->addMenu(m_recentlyClosedMenu);
3356        m_tabsMenu->addAction(m_restoreMostRecentlyClosedTabAction);
3357    }
3358
3359    m_tabsMenu->addSeparator();
3360
3361    // bookmarks
3362
3363    m_bookmarksMenu = new SearchableMenu(tr("&Bookmarks"), this);
3364    menuBar()->addMenu(m_bookmarksMenu);
3365
3366    m_bookmarksMenu->setSearchable(s_settings->mainWindow().searchableMenus());
3367
3368    connect(m_bookmarksMenu, SIGNAL(aboutToShow()), this, SLOT(on_bookmarksMenu_aboutToShow()));
3369
3370    m_bookmarksMenuIsDirty = true;
3371
3372    // help
3373
3374    m_helpMenu = menuBar()->addMenu(tr("&Help"));
3375    m_helpMenu->addActions(QList< QAction* >() << m_contentsAction << m_aboutAction);
3376
3377    //security
3378
3379    m_security = menuBar()->addMenu(tr("&Security"));
3380    m_security->addActions(QList< QAction* >() << m_signature << m_verify_signature << m_detailsSignatureDock->toggleViewAction());
3381
3382}
3383
3384#ifdef WITH_DBUS
3385
3386MainWindowAdaptor::MainWindowAdaptor(MainWindow* mainWindow) : QDBusAbstractAdaptor(mainWindow)
3387{
3388}
3389
3390void MainWindowAdaptor::raiseAndActivate()
3391{
3392    mainWindow()->raise();
3393    mainWindow()->activateWindow();
3394}
3395
3396bool MainWindowAdaptor::open(const QString& absoluteFilePath, int page, const QRectF& highlight, bool quiet)
3397{
3398    return mainWindow()->open(absoluteFilePath, page, highlight, quiet);
3399}
3400
3401bool MainWindowAdaptor::openInNewTab(const QString& absoluteFilePath, int page, const QRectF& highlight, bool quiet)
3402{
3403    return mainWindow()->openInNewTab(absoluteFilePath, page, highlight, quiet);
3404}
3405
3406bool MainWindowAdaptor::jumpToPageOrOpenInNewTab(const QString& absoluteFilePath, int page, bool refreshBeforeJump, const QRectF& highlight, bool quiet)
3407{
3408    return mainWindow()->jumpToPageOrOpenInNewTab(absoluteFilePath, page, refreshBeforeJump, highlight, quiet);
3409}
3410
3411void MainWindowAdaptor::startSearch(const QString& text)
3412{
3413    mainWindow()->startSearch(text);
3414}
3415
3416#define ONLY_IF_CURRENT_TAB if(mainWindow()->m_tabWidget->currentIndex() == -1) { return; }
3417
3418void MainWindowAdaptor::previousPage()
3419{
3420    ONLY_IF_CURRENT_TAB
3421
3422    mainWindow()->on_previousPage_triggered();
3423}
3424
3425void MainWindowAdaptor::nextPage()
3426{
3427    ONLY_IF_CURRENT_TAB
3428
3429    mainWindow()->on_nextPage_triggered();
3430}
3431
3432void MainWindowAdaptor::firstPage()
3433{
3434    ONLY_IF_CURRENT_TAB
3435
3436    mainWindow()->on_firstPage_triggered();
3437}
3438
3439void MainWindowAdaptor::lastPage()
3440{
3441    ONLY_IF_CURRENT_TAB
3442
3443    mainWindow()->on_lastPage_triggered();
3444}
3445
3446void MainWindowAdaptor::previousBookmark()
3447{
3448    ONLY_IF_CURRENT_TAB
3449
3450    mainWindow()->on_previousBookmark_triggered();
3451}
3452
3453void MainWindowAdaptor::nextBookmark()
3454{
3455    ONLY_IF_CURRENT_TAB
3456
3457    mainWindow()->on_nextBookmark_triggered();
3458}
3459
3460bool MainWindowAdaptor::jumpToBookmark(const QString& label)
3461{
3462    if(mainWindow()->m_tabWidget->currentIndex() == -1) { return false; }
3463
3464    const BookmarkModel* model = mainWindow()->bookmarkModelForCurrentTab();
3465
3466    if(model != 0)
3467    {
3468        for(int row = 0, rowCount = model->rowCount(); row < rowCount; ++row)
3469        {
3470            const QModelIndex index = model->index(row);
3471
3472            if(label == index.data(BookmarkModel::LabelRole).toString())
3473            {
3474                mainWindow()->currentTab()->jumpToPage(index.data(BookmarkModel::PageRole).toInt());
3475
3476                return true;
3477            }
3478        }
3479    }
3480
3481    return false;
3482}
3483
3484void MainWindowAdaptor::continuousModeAction(bool checked)
3485{
3486    ONLY_IF_CURRENT_TAB
3487
3488    mainWindow()->on_continuousMode_triggered(checked);
3489}
3490
3491void MainWindowAdaptor::twoPagesModeAction(bool checked)
3492{
3493    ONLY_IF_CURRENT_TAB
3494
3495    mainWindow()->on_twoPagesMode_triggered(checked);
3496}
3497
3498void MainWindowAdaptor::twoPagesWithCoverPageModeAction(bool checked)
3499{
3500    ONLY_IF_CURRENT_TAB
3501
3502    mainWindow()->on_twoPagesWithCoverPageMode_triggered(checked);
3503}
3504
3505void MainWindowAdaptor::multiplePagesModeAction(bool checked)
3506{
3507    ONLY_IF_CURRENT_TAB
3508
3509    mainWindow()->on_multiplePagesMode_triggered(checked);
3510}
3511
3512void MainWindowAdaptor::fitToPageWidthModeAction(bool checked)
3513{
3514    ONLY_IF_CURRENT_TAB
3515
3516    mainWindow()->on_fitToPageWidthMode_triggered(checked);
3517}
3518
3519void MainWindowAdaptor::fitToPageSizeModeAction(bool checked)
3520{
3521    ONLY_IF_CURRENT_TAB
3522
3523    mainWindow()->on_fitToPageSizeMode_triggered(checked);
3524}
3525
3526void MainWindowAdaptor::convertToGrayscaleAction(bool checked)
3527{
3528    ONLY_IF_CURRENT_TAB
3529
3530    mainWindow()->on_convertToGrayscale_triggered(checked);
3531}
3532
3533void MainWindowAdaptor::invertColorsAction(bool checked)
3534{
3535    ONLY_IF_CURRENT_TAB
3536
3537    mainWindow()->on_invertColors_triggered(checked);
3538}
3539
3540void MainWindowAdaptor::fullscreenAction(bool checked)
3541{
3542    if(mainWindow()->m_fullscreenAction->isChecked() != checked)
3543    {
3544        mainWindow()->m_fullscreenAction->trigger();
3545    }
3546}
3547
3548void MainWindowAdaptor::presentationAction()
3549{
3550    ONLY_IF_CURRENT_TAB
3551
3552    mainWindow()->on_presentation_triggered();
3553}
3554
3555void MainWindowAdaptor::closeTab()
3556{
3557    ONLY_IF_CURRENT_TAB
3558
3559    mainWindow()->on_closeTab_triggered();
3560}
3561
3562void MainWindowAdaptor::closeAllTabs()
3563{
3564    mainWindow()->on_closeAllTabs_triggered();
3565}
3566
3567void MainWindowAdaptor::closeAllTabsButCurrentTab()
3568{
3569    mainWindow()->on_closeAllTabsButCurrentTab_triggered();
3570}
3571
3572// agregando funciones para la verificación de la firma electrónica
3573
3574const char * getReadableSigState(SignatureValidationStatus sig_vs)
3575{
3576  switch(sig_vs) {
3577    case SIGNATURE_VALID:
3578      //return "Signature is Valid.";
3579      return "Firma válida.";
3580
3581    case SIGNATURE_INVALID:
3582      //return "Signature is Invalid.";
3583      return "Firma inválida.";
3584
3585    case SIGNATURE_DIGEST_MISMATCH:
3586      //return "Digest Mismatch.";
3587      return "Digest Mismatch.";
3588
3589    case SIGNATURE_DECODING_ERROR:
3590      //return "Document isn't signed or corrupted data.";
3591      return "El documento no está firmado o datos dañados.";
3592
3593    case SIGNATURE_NOT_VERIFIED:
3594      //return "Signature has not yet been verified.";
3595      return "Firma todavía no se ha verificado.";
3596
3597    default:
3598      //return "Unknown Validation Failure.";
3599      return "Desconocido fallo de validación.";
3600  }
3601}
3602
3603const char * getReadableCertState(CertificateValidationStatus cert_vs)
3604{
3605  switch(cert_vs) {
3606    case CERTIFICATE_TRUSTED:
3607      //return "Certificate is Trusted.";
3608      return "Certificado es de confianza";
3609
3610    case CERTIFICATE_UNTRUSTED_ISSUER:
3611      //return "Certificate issuer isn't Trusted.";
3612      return "Emisor del certificado no es de confianza";
3613
3614    case CERTIFICATE_UNKNOWN_ISSUER:
3615      //return "Certificate issuer is unknown.";
3616      return "Emisor de certificado es desconocido";
3617
3618    case CERTIFICATE_REVOKED:
3619      //return "Certificate has been Revoked.";
3620      return "Certificado ha sido revocado.";
3621
3622    case CERTIFICATE_EXPIRED:
3623      //return "Certificate has Expired";
3624      return "Certificado ha caducado";
3625
3626    case CERTIFICATE_NOT_VERIFIED:
3627      //return "Certificate has not yet been verified.";
3628      return "Certificado aún no ha sido verificado.";
3629
3630    default:
3631      //return "Unknown issue with Certificate or corrupted data.";
3632      return "Problema desconocido con el certificado o datos dañados.";
3633  }
3634}
3635
3636char *getReadableTime(time_t unix_time)
3637{
3638  char * time_str = (char *) gmalloc(64);
3639  strftime(time_str, 64, "%b %d %Y %H:%M:%S", localtime(&unix_time));
3640  return time_str;
3641}
3642
3643static GBool printVersion = gFalse;
3644static GBool printHelp = gFalse;
3645static GBool dontVerifyCert = gFalse;
3646
3647//static const ArgDesc argDesc[] = {
3648//  {"-nocert", argFlag,     &dontVerifyCert,     0,
3649//   "don't perform certificate validation"},
3650
3651//  {"-v",      argFlag,     &printVersion,  0,
3652//   "print copyright and version info"},
3653//  {"-h",      argFlag,     &printHelp,     0,
3654//   "print usage information"},
3655//  {"-help",   argFlag,     &printHelp,     0,
3656//   "print usage information"},
3657//  {"-?",      argFlag,     &printHelp,     0,
3658//   "print usage information"},
3659//  {NULL}
3660//};
3661
3662//fin de agregar funciones para la verificación de firma electrónica
3663
3664//QString MainWindow::verify_signature() {
3665//QStringList MainWindow::verify_signature() {
3666
3667QStandardItemModel *MainWindow::view_table_verify_signature() {
3668
3669    qDebug("view_table_verify_signature");
3670    //m_tableVerifySign = new QTableView();
3671
3672    char *time_str = NULL;
3673    PDFDoc *doc = NULL;
3674    unsigned int sigCount;
3675    GooString * fileName = NULL;
3676    SignatureInfo *sig_info = NULL;
3677    std::vector<FormWidgetSignature*> sig_widgets;
3678    globalParams = new GlobalParams();
3679
3680    int exitCode = 99;
3681    // GBool ok;
3682
3683    QString newfile = currentTab()->fileInfo().absoluteFilePath();
3684
3685    qDebug("***fileName signatures: |%s|",newfile.toUtf8().data());
3686    fileName = new GooString(newfile.toUtf8().data());  // le paso el path del documento PDF para abrirlo
3687
3688    // open PDF file
3689    doc = PDFDocFactory().createPDFDoc(*fileName, NULL, NULL); //abre el documento
3690    if (!doc->isOk()) {
3691        exitCode = 1;
3692        qDebug(".......error");
3693     }
3694
3695     sig_widgets = doc->getSignatureWidgets();
3696     sigCount = sig_widgets.size();
3697
3698     if( sigCount >= 1 ) { //El documento tiene firma electronica
3699         int numColumns = 2;
3700         int numRows = sigCount*5;
3701         QStringList horzHeaders;
3702         horzHeaders << "Atributo" << "Valor";
3703         QStandardItemModel* model = new QStandardItemModel(numRows, numColumns);
3704         model->setHorizontalHeaderLabels(horzHeaders);
3705         QString rowtype, rowvalue;
3706         int countRow = 0;
3707
3708         for (unsigned int i = 0; i < sigCount; i++) {
3709              sig_info = sig_widgets.at(i)->validateSignature(!dontVerifyCert, false);
3710
3711              //**Sección para llenar la tabla
3712              //qDebug() << countRow;
3713              rowtype = trUtf8("Firma número %1").arg(i+1);
3714              QStandardItem* item = new QStandardItem(rowtype);
3715              model->setItem(countRow, 0, item);
3716              countRow ++;
3717              rowtype = trUtf8("   - Nombre común ");
3718              item = new QStandardItem(rowtype);
3719              model->setItem(countRow, 0, item);
3720              rowvalue = sig_info->getSignerName();
3721              item = new QStandardItem(rowvalue);
3722              model->setItem(countRow, 1, item);
3723              countRow ++;
3724              rowtype = trUtf8("   - Hora de la firma ");
3725              item = item = new QStandardItem(rowtype);
3726              model->setItem(countRow, 0, item);
3727              rowvalue = getReadableTime(sig_info->getSigningTime());
3728              item = new QStandardItem(rowvalue);
3729              model->setItem(countRow, 1, item);
3730              countRow ++;
3731              rowtype = trUtf8("   - Validación de la firma ");
3732              item = item = new QStandardItem(rowtype);
3733              model->setItem(countRow, 0, item);
3734              rowvalue = trUtf8(getReadableSigState(sig_info->getSignatureValStatus()));
3735              item = new QStandardItem(rowvalue);
3736              model->setItem(countRow, 1, item);
3737              countRow ++;
3738              rowtype = trUtf8("   - Validación del certificado ");
3739              item = item = new QStandardItem(rowtype);
3740              model->setItem(countRow, 0, item);
3741              rowvalue = getReadableCertState(sig_info->getCertificateValStatus());
3742              item = new QStandardItem(rowvalue);
3743              model->setItem(countRow, 1, item);
3744              countRow ++;
3745              model->takeVerticalHeaderItem(countRow);
3746          }
3747         return model;
3748      }
3749
3750     else { //El documento no tiene firma
3751         QStandardItemModel* model = new QStandardItemModel(1,1);
3752         QString rowtype = trUtf8("El documento no posee firma electrónica");
3753         QStandardItem* item = new QStandardItem(rowtype);
3754         model->setItem(0, 0, item);
3755         return model;
3756     }
3757}
3758
3759QStandardItemModel *MainWindow::verify_signature() {
3760    qDebug("verify_signature");
3761    m_tableVerifySign = new QTableView();
3762
3763
3764    char *time_str = NULL;
3765    PDFDoc *doc = NULL;
3766    unsigned int sigCount;
3767    GooString * fileName = NULL;
3768    SignatureInfo *sig_info = NULL;
3769    std::vector<FormWidgetSignature*> sig_widgets;
3770    globalParams = new GlobalParams();
3771
3772    int exitCode = 99;
3773    // GBool ok;
3774
3775    QString newfile = currentTab()->fileInfo().absoluteFilePath();
3776
3777    qDebug("***fileName signatures: |%s|",newfile.toUtf8().data());
3778    fileName = new GooString(newfile.toUtf8().data());  // le paso el path del documento PDF para abrirlo
3779
3780    // open PDF file
3781    doc = PDFDocFactory().createPDFDoc(*fileName, NULL, NULL); //abre el documento
3782    //qDebug(".......1");
3783    if (!doc->isOk()) {
3784        exitCode = 1;
3785        qDebug(".......error");
3786        //return "Error";
3787        //goto end;
3788     }
3789
3790     //qDebug(".......3");
3791     sig_widgets = doc->getSignatureWidgets();
3792     sigCount = sig_widgets.size();
3793     int numColumns = 2;
3794     int numRows = sigCount*5;
3795     QStringList horzHeaders;
3796     horzHeaders << "Atributo" << "Valor";
3797
3798     QStandardItemModel* model = new QStandardItemModel(numRows, numColumns);
3799     model->setHorizontalHeaderLabels(horzHeaders);
3800     qDebug()<<horzHeaders[0];
3801     qDebug()<<horzHeaders[1];
3802    // model->setHorizontalHeaderLabels(horzheaders);
3803      QStringList itens;
3804      //QStandardItem* item;
3805      QString rowtype, rowvalue;
3806      int countRow = 0;
3807      QString newmessage = trUtf8("Número de firmas: %1 ").arg(sigCount);
3808      newmessage += "\n \n";
3809      for (unsigned int i = 0; i < sigCount; i++) {
3810          sig_info = sig_widgets.at(i)->validateSignature(!dontVerifyCert, false);
3811          //qDebug("Firma %d ", i+1);
3812          newmessage += trUtf8("Firma número %1").arg(i+1);
3813          newmessage += "\n";
3814          //qDebug(sig_info->getSignerName());
3815          newmessage += trUtf8("  - Nombre común: %1  \n").arg(sig_info->getSignerName());
3816          newmessage += trUtf8("  - Hora de la firma: %1f \n").arg(time_str = getReadableTime(sig_info->getSigningTime()));
3817          newmessage += trUtf8("  - Validación de la firma: %1  \n").arg(getReadableSigState(sig_info->getSignatureValStatus()));
3818          newmessage += trUtf8("  - Validación del certificado: %1").arg(getReadableCertState(sig_info->getCertificateValStatus()));
3819          newmessage += "  \n";
3820          itens << trUtf8("Firma número %1").arg(i+1) + trUtf8("  - Nombre común: %1  \n").arg(sig_info->getSignerName()) + trUtf8("  - Hora de la firma: %1f \n").arg(time_str = getReadableTime(sig_info->getSigningTime())) + trUtf8("  - Validación de la firma: %1  \n").arg(getReadableSigState(sig_info->getSignatureValStatus())) + trUtf8("  - Validación del certificado: %1").arg(getReadableCertState(sig_info->getCertificateValStatus()));
3821
3822          //**Sección para llenar la tabla
3823
3824          rowtype = "Firma " + QString::number(i + 1);
3825          QStandardItem* item = new QStandardItem(rowtype);
3826          model->setItem(countRow, 0, item);
3827          countRow ++;
3828          rowtype = trUtf8("  - Nombre común ");
3829          item = new QStandardItem(rowtype);
3830          model->setItem(countRow, 0, item);
3831          rowvalue = sig_info->getSignerName();
3832          item = new QStandardItem(rowvalue);
3833          model->setItem(countRow, 1, item);
3834          countRow ++;
3835          rowtype = trUtf8("  - Hora de la firma ");
3836          item = item = new QStandardItem(rowtype);
3837          model->setItem(countRow, 0, item);
3838          rowvalue = getReadableTime(sig_info->getSigningTime());
3839          item = new QStandardItem(rowvalue);
3840          model->setItem(countRow, 1, item);
3841          countRow ++;
3842          rowtype = trUtf8("  - Validación de la firma ");
3843          item = item = new QStandardItem(rowtype);
3844          model->setItem(countRow, 0, item);
3845          rowvalue = trUtf8(getReadableSigState(sig_info->getSignatureValStatus()));
3846          item = new QStandardItem(rowvalue);
3847          model->setItem(countRow, 1, item);
3848          countRow ++;
3849          rowtype = trUtf8("  - Validación del certificado ");
3850          item = item = new QStandardItem(rowtype);
3851          model->setItem(countRow, 0, item);
3852          rowvalue = getReadableCertState(sig_info->getCertificateValStatus());
3853          item = new QStandardItem(rowvalue);
3854          model->setItem(countRow, 1, item);
3855          countRow ++;
3856      }
3857      //return newmessage;
3858      qDebug()<<itens;
3859      qDebug("Saliendo**************************************************************************************************************");
3860      //m_tableVerifySign->setModel(model);
3861      //return itens;
3862      return model;
3863 }
3864
3865void MainWindow::on_verify_signature() {
3866
3867    qDebug("Entro en callMurachi()");
3868    callMurachi();
3869    qDebug("Salio en callMurachi()");
3870
3871    qDebug("Entro a on_verify_signature()");
3872    verify_signature();
3873    char *time_str = NULL;
3874    PDFDoc *doc = NULL;
3875    unsigned int sigCount;
3876    GooString * fileName = NULL;
3877    SignatureInfo *sig_info = NULL;
3878    std::vector<FormWidgetSignature*> sig_widgets;
3879    globalParams = new GlobalParams();
3880
3881    int exitCode = 99;
3882    // GBool ok;
3883
3884    QString newfile = currentTab()->fileInfo().absoluteFilePath();
3885
3886    qDebug("***fileName signatures: |%s|",newfile.toUtf8().data());
3887    fileName = new GooString(newfile.toUtf8().data());  // le paso el path del documento PDF para abrirlo
3888
3889    // open PDF file
3890    doc = PDFDocFactory().createPDFDoc(*fileName, NULL, NULL); //abre el documento
3891    //qDebug(".......1");
3892    if (!doc->isOk()) {
3893        exitCode = 1;
3894        qDebug(".......error");
3895        return;
3896        //goto end;
3897     }
3898
3899     qDebug(".......3");
3900     sig_widgets = doc->getSignatureWidgets();
3901     sigCount = sig_widgets.size();
3902
3903
3904      QString newmessage = trUtf8("Número de firmas: %1 ").arg(sigCount);
3905      newmessage += "\n \n";
3906      //qDebug("fileName number of signatures: %d", sigCount);
3907      //qDebug("****************************");
3908      //qDebug(fileName->getCString());
3909
3910      //***********************
3911//      if (sigCount >= 1) {
3912//          //newmessage =+ trUtf8("Digital Signature Info of: %s\n").arg(fileName->getCString());
3913//          //qDebug(fileName->getCString()); //path del archivo que se abrio
3914//          qDebug("El archivo contiene firma electrónica");
3915//          //printf("Digital Signature Info of: %s\n", fileName->getCString());
3916//        } else {
3917//          //newmessage =+ trUtf8("File '%s' does not contain any signatures\n").arg(fileName->getCString());
3918//          qDebug("El archivo no contiene firma electrónica");
3919//          //printf("File '%s' does not contain any signatures\n", fileName->getCString());
3920//          exitCode = 2;
3921//          return;
3922//          //goto end;
3923//        }
3924
3925        for (unsigned int i = 0; i < sigCount; i++) {
3926          sig_info = sig_widgets.at(i)->validateSignature(!dontVerifyCert, false);
3927          qDebug("Firma %d ", i+1);
3928          //printf("Signature #%u:\n", i+1);
3929          newmessage += trUtf8("Firma número %1").arg(i+1);
3930          newmessage += "\n";
3931          //qDebug("entro al for: %d", i);
3932          //qDebug(i+1);
3933          //printf("  - Signer Certificate Common Name: %s\n", sig_info->getSignerName());
3934          //qDebug(sig_info->getSignerName());
3935          newmessage += trUtf8("  - Nombre común: %1  \n").arg(sig_info->getSignerName());
3936          //newmessage += "  \n";
3937          //printf("  - Signing Time: %s\n", time_str = getReadableTime(sig_info->getSigningTime()));
3938          newmessage += trUtf8("  - Hora de la firma: %1f \n").arg(time_str = getReadableTime(sig_info->getSigningTime()));
3939          //newmessage += "  \n";
3940          //newmessage =+ trUtf8("  - Signing Time: %s\n").arg(getReadableTime(sig_info->getSigningTime()));
3941          //printf("  - Signature Validation: %s\n", getReadableSigState(sig_info->getSignatureValStatus()));
3942          newmessage += trUtf8("  - Validación de la firma: %1  \n").arg(trUtf8(getReadableSigState(sig_info->getSignatureValStatus())));
3943
3944          //newmessage =+ trUtf8("  - Signature Validation: %s\n").arg(getReadableSigState(sig_info->getSignatureValStatus()));
3945          //gfree(time_str);
3946          //if (sig_info->getSignatureValStatus() != SIGNATURE_VALID || dontVerifyCert) {
3947            //continue;
3948          //}
3949          //printf("  - Certificate Validation: %s\n", getReadableCertState(sig_info->getCertificateValStatus()));
3950          newmessage += trUtf8("  - Validación del certificado: %1").arg(getReadableCertState(sig_info->getCertificateValStatus()));
3951          newmessage += "  \n";
3952        }
3953
3954    //***********************
3955
3956
3957    QString my_msg;
3958    my_msg = " Signature #1: \n - Signer Certificate Common Name: Murachi \n - Signing Time: Apr 10 2015 08:26:08  \n - Signature Validation: Signature is Valid. \n - Certificate Validation: Certificate issuer is unknown. \n Signature #2: \n - Signer Certificate Common Name: Juan Hilario \n  - Signing Time: Apr 10 2015 08:27:42 \n - Signature Validation: Signature is Valid. \n  - Certificate Validation: Certificate has Expired \n  Signature #3: \n - Signer Certificate Common Name: Murachi \n - Signing Time: Apr 10 2015 08:48:18 \n - Signature Validation: Signature is Valid. \n - Certificate Validation: Certificate issuer is unknown";
3959
3960    QMessageBox my_msg_Box;
3961    int cont = 1;
3962    if(sigCount == 0) {
3963        my_msg_Box.setWindowTitle("Terepaima");
3964        my_msg_Box.setText("El documento no esta firmado");
3965        my_msg_Box.exec();
3966    }
3967    else {
3968        my_msg_Box.setWindowTitle("Terepaima");
3969        my_msg_Box.setText("El documento esta firmado electronicamente");
3970        my_msg_Box.setDetailedText(newmessage);
3971        my_msg_Box.exec();
3972    }
3973}
3974
3975void MainWindow::callMurachi() {
3976
3977
3978   // QString version = executeRest("https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/version","admin","admin");
3979    //QString fileid = "c73efabb-d771-4328-be4f-36b11c4add57";
3980    QString fileid = "8dd41d79-c3c8-4490-944b-3a246422ab6c";
3981   QUrlQuery postData;
3982    //postData.addQueryItem("fileId", fileid);
3983    //postData.addQueryItem("certificate", certInHex);
3984    //postData.addQueryItem("reason", "Certificado");
3985    //postData.addQueryItem("location", "CENDITEL");
3986    //postData.addQueryItem("contact", "582746574336");
3987    //postData.addQueryItem("signatureVisible","true" );
3988    //postData.addQueryItem("signaturePage","1" );
3989    //postData.addQueryItem("xPos","10" );
3990    //postData.addQueryItem("yPos","10" );
3991    //postData.addQueryItem("lastSignature","false" );
3992
3993    QString parameters = QString("{\"fileId\":\"%1\",\"certificate\":\"%2\",\"reason\":\"Certificado\", \"location\":\"CENDITEL\", "
3994                                 "\"contact\":\"582746574336\",\"signatureVisible\":\"true\","
3995                                  "\"signaturePage\":\"1\",\"xPos\":\"10\",\"yPos\":\"10\",\"lastSignature\":\"false\" }")
3996            .arg(fileid).arg(certInHex);
3997
3998    //postData.addQueryItem("", parameters);
3999
4000/*    QByteArray postData;
4001    postData.append(QString("fileId=%1&").arg(fileid));
4002    postData.append(QString("certificate=%1&").arg(certInHex));
4003    postData.append(QString("reason=%1&").arg("Certificado"));
4004    postData.append(QString("location=%1&").arg("CENDITEL"));
4005    postData.append(QString("contact=%1&").arg("582746574336"));
4006    postData.append(QString("signatureVisible=%1&").arg("true"));
4007    postData.append(QString("signaturePage=%1&").arg("1"));
4008    postData.append(QString("xPos=%1&").arg("10"));
4009    postData.append(QString("yPos=%1&").arg("10"));
4010    postData.append(QString("lastSignature=%1").arg("false"));
4011
4012*/
4013
4014    //parameters = "{}";
4015
4016    qDebug("Parameters: |%s|", qPrintable(parameters));
4017
4018   // qDebug("Verifying...... SIGNED...fileid |%s|", qPrintable(fileid));
4019    //qDebug("certInHex: |%s|", qPrintable(certInHex));
4020
4021//    QString newverify  = privateExecuteRest("https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/pdfs",
4022//                                         "admin","admin", "post",postData);
4023
4024 //   QString newverify  = privateExecuteRest("https://192.168.12.154:8443/Murachi/0.1/archivos/pdfs",
4025//                                         "admin","admin", "post",postData);
4026
4027    //qDebug("Verifying...... SIGNED...hash |%s|", qPrintable(newverify));
4028
4029
4030    //QUrlQuery postData1;
4031
4032    QString newhash =  executeRest("https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/pdfs","admin","admin"
4033                                     ,parameters);
4034
4035    qDebug(".....................*Verify: newhash %s", qPrintable(newhash));
4036
4037    QJsonDocument d = QJsonDocument::fromJson(newhash.toUtf8());
4038          QJsonObject sett2 = d.object();
4039          QJsonValue value = sett2.value(QString("hash"));
4040
4041    currentHash = value.toString();
4042    qDebug(".....................****currentHash: |%s|", qPrintable(currentHash));
4043
4044
4045    on_signature();
4046    //QString verify  = privateExecuteRest("https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/aee1a794-5fc7-4008-ac6d-de2e79583074.pdf",
4047    //                                     "admin","admin",method="post",postData);
4048
4049
4050 //   qDebug("Version: %s", qPrintable(version));
4051
4052}
4053
4054void MainWindow::on_signature() {
4055    qDebug("** on_signature **");
4056
4057    on_windowCertificate();
4058}
4059
4060
4061void MainWindow::on_windowPIN(int x) {
4062
4063    qDebug("** on_windowPIN **");
4064
4065    qDebug("**CALLING TEST on_windowPIN **");
4066    m_pin = new QDialog;
4067    close_PIN = "falso";
4068
4069    m_layoutContrasenia = new QHBoxLayout;
4070    m_layoutBotones = new QHBoxLayout;
4071    m_layoutPrincipal = new QVBoxLayout(m_pin);
4072    m_layoutmesage = new QVBoxLayout;
4073    if(x == 0) {
4074        m_mesage = new QLabel("Error, PIN incorrecto");
4075    }
4076    else m_mesage = new QLabel("");
4077    m_etiquetaContrasenia = new QLabel("Para firmar introduzca el PIN");
4078
4079    m_campoContrasenia = new QLineEdit;
4080    m_campoContrasenia->setEchoMode(QLineEdit::Password);
4081
4082    m_botonAceptar = new QPushButton("Aceptar");
4083    m_botonCancelar = new QPushButton("Cancelar");
4084
4085
4086    m_layoutContrasenia->addWidget(m_etiquetaContrasenia);
4087    m_layoutContrasenia->addWidget(m_campoContrasenia);
4088
4089    m_layoutBotones->addStretch();
4090    m_layoutmesage->addWidget(m_mesage);
4091    m_layoutBotones->addWidget(m_botonAceptar);
4092    m_layoutBotones->addWidget(m_botonCancelar);
4093
4094    m_layoutPrincipal->addLayout(m_layoutContrasenia);
4095    m_layoutPrincipal->addLayout(m_layoutmesage);
4096    m_layoutPrincipal->addLayout(m_layoutBotones);
4097
4098    m_pin->setWindowTitle(QObject::trUtf8("PIN:"));
4099
4100    connect(m_botonCancelar, SIGNAL(clicked()),this, SLOT(on_close_windowPIN()));
4101    connect(m_botonAceptar, SIGNAL(clicked()),this, SLOT(on_managePIN()));
4102    m_pin->exec();
4103}
4104
4105void MainWindow::on_close_windowPIN() {
4106    qDebug("** on_close_windowPIN() **");
4107    m_pin->close();
4108    qDebug("** Accion cancelada por el usuario **");
4109    close_PIN = "verdadero";
4110}
4111
4112void MainWindow::on_managePIN() {
4113    qDebug("on_gestionar_PIN");
4114    QString pin = m_campoContrasenia->text();
4115    qDebug("PIN: %s", qPrintable(pin));
4116    m_pin->accept();
4117    m_nct = new CryptoToken();
4118    //QString hash("e4b820914010e65a578435fd6839f8dfe1037915d39130902970355a272ce3b3");
4119    //currentHash = hash;
4120
4121    try {
4122        qDebug("Resultado Firma hash: |%s|", qPrintable(currentHash));
4123        if (currentHash.isEmpty()) {
4124            QMessageBox msgBox;
4125            msgBox.setText("Hash esta vacio!");
4126            msgBox.exec();
4127            return;
4128        }
4129        QString pass = m_campoContrasenia->text();
4130        qDebug("Resultado Firma pass: |%s|", qPrintable(pass));
4131        std::vector<unsigned char> result = m_nct->signHash(currentHash, pass, certSelect);
4132        qDebug("** signature: ");
4133        QString newsignature = QString(m_nct->toHex(result));
4134        qDebug("Resultado Firma en HEX: |%s|", qPrintable(newsignature));
4135        open("/home/pbuitrago/Cenditel/Seguridad/POA-2015/Portal_verificacion_firma/reconocimientoMurachi-signed.pdf"); // para refrescar el archivo al firmado
4136        m_detailsSignatureView->setModel(view_table_verify_signature()); // refresca la table de verificación de firma electrónica
4137        QString resenas = QString("{\"signature\":\"%1\"}").arg(newsignature);
4138
4139        qDebug("..............(1).......resenas: |%s|", qPrintable(resenas));
4140
4141        QString newcompleted =  executeRest("https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/pdfs/resenas","admin","admin",resenas);
4142
4143        qDebug("..............(2).......resenas: |%s|", qPrintable(newcompleted));
4144        QMessageBox msgBox;
4145        msgBox.setText("El archivo se firmo con exitos..!");
4146        msgBox.exec();
4147    }catch(std::runtime_error e) {
4148        qDebug("exception");
4149        qDebug("%s", e.what());
4150        on_windowPIN(0);
4151     }
4152}
4153
4154
4155
4156void MainWindow::handleNetworkData(QNetworkReply *networkReply)
4157{
4158    qDebug("MainWindow::handleNetworkData....*1");
4159
4160    QUrl url = networkReply->url();
4161
4162    qDebug("MainWindow::handleNetworkData....*2");
4163
4164    if (!networkReply->error()) {
4165
4166        QString response(networkReply->readAll());
4167        _currentrest = response;
4168        qDebug("CALLING_REST_SERVICE....response: |%s|",qPrintable(response));
4169
4170
4171     } else {
4172     qDebug("handleNetworkData  OCURRED ERROR network error: |%s|",qPrintable(networkReply->errorString()));
4173    }
4174
4175
4176    networkReply->deleteLater();
4177}
4178
4179
4180void MainWindow::slotError(QNetworkReply::NetworkError e) {
4181
4182    QString currenterror = QString("Error ocurred: |%1|").arg(e);
4183
4184    qDebug("Error network.............1");
4185    //SYD << currenterror;
4186
4187    _currentrest = currenterror;
4188
4189}
4190
4191
4192
4193QString MainWindow::privateExecuteRest(const QString &url, const QString &name,
4194                                       const QString &pass,
4195                                       QString method, const QUrlQuery& postData )
4196{
4197    _currentrest = "";
4198
4199    qDebug("Private Executing Rest...1");
4200
4201    QNetworkAccessManager *manager = new QNetworkAccessManager(this);
4202
4203  //  int nargs;
4204  //  char** argv =NULL;
4205  //  QCoreApplication myapp(nargs,argv);
4206
4207
4208
4209        QNetworkRequest request;
4210        QSslConfiguration conf = request.sslConfiguration();
4211        conf.setPeerVerifyMode(QSslSocket::VerifyNone);
4212     //   conf.setProtocol(QSsl::TlsV1SslV3);
4213        request.setSslConfiguration(conf);
4214
4215
4216        qDebug("Executing Rest...4");
4217
4218     QUrl myurl(url);
4219
4220     //   myurl.setUserName(name);
4221     //   myurl.setPassword(pass);
4222        request.setUrl(myurl);
4223        qDebug("Private Executing Rest...URL CALLING:|%s|", qPrintable(url));
4224
4225      qDebug("Private Executing Rest...4");
4226
4227      connect(manager, SIGNAL(finished(QNetworkReply*)),
4228              this, SLOT(handleNetworkData(QNetworkReply*)));
4229
4230
4231      qDebug("Private Executing Rest...5");
4232      QNetworkReply *reply = NULL;
4233      if (method == "post") {
4234          qDebug("Private Executing Rest...**6");
4235          qDebug("CALLING_REST_SERVICE... method IS POST");
4236
4237           request.setHeader(QNetworkRequest::ContentTypeHeader,
4238              "application/json");
4239           QString headerData = QString("Basic YWRtaW46YWRtaW4=");
4240           request.setRawHeader("Authorization", headerData.toLocal8Bit());
4241
4242           //QNetworkReply *reply = manager->post(request, postData.encodedQuery());
4243           qDebug("Private Executing Rest...7");
4244
4245           reply = manager->post(request,  postData.toString(QUrl::FullyEncoded).toUtf8());
4246          // reply = manager->post(request,  postData);
4247
4248
4249           connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
4250                     this, SLOT(slotError(QNetworkReply::NetworkError)));
4251
4252           qDebug("Private Executing Rest...8");
4253
4254
4255      } else {
4256            qDebug("CALLING_REST_SERVICE... method IS GET");
4257            reply = manager->get(request);
4258
4259      }
4260
4261
4262      qDebug("Private Executing Rest...9");
4263      QEventLoop loop;
4264      connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
4265      loop.exec();
4266
4267
4268      qDebug("Private Executing Rest...10");
4269      QString result = _currentrest;
4270      //QString result = "....test1";
4271      return result;
4272
4273}
4274
4275
4276
4277QString MainWindow::executeRest(const QString &url, const QString &name, const QString &pass, const QString& postData) {
4278    _currentrest = "";
4279
4280    qDebug("Executing Executing...Rest...1");
4281
4282    if (manager == NULL) {
4283            qDebug("Executing Executing..MANAGER new");
4284            manager = new QNetworkAccessManager(this);
4285            cookiesJar = new QNetworkCookieJar(this);
4286            manager->setCookieJar(cookiesJar);
4287    }
4288
4289
4290
4291
4292    qDebug("Executing Executing...Rest...2");
4293
4294    //int nargs;
4295    //char** argv =NULL;
4296    //QCoreApplication myapp(nargs,argv);
4297
4298    qDebug("Executing Rest...3");
4299
4300      QNetworkRequest request;
4301    QSslConfiguration conf = request.sslConfiguration();
4302    conf.setPeerVerifyMode(QSslSocket::VerifyNone);
4303    //conf.setPeerVerifyMode(QSslSocket::AutoVerifyPeer);
4304    //conf.setProtocol(QSsl::AnyProtocol);
4305    request.setSslConfiguration(conf);
4306
4307   // if (url.endsWith("pdfs") ) {
4308        qDebug("Credentials is TRUE, maybe");
4309        //request.setAttribute(QNetworkRequest::CookieLoadControlAttribute, QVariant(QNetworkRequest::Manual));
4310       // request.setAttribute(QNetworkRequest::CookieSaveControlAttribute, QVariant(QNetworkRequest::Manual));
4311       // request.setAttribute(QNetworkRequest::AuthenticationReuseAttribute, QVariant(QNetworkRequest::Manual));
4312   // }
4313    qDebug("Executing Rest...4");
4314
4315       QUrl myurl(url);
4316
4317      //myurl.setUserName(name);
4318      //myurl.setPassword(pass);
4319      request.setUrl(myurl);
4320
4321      qDebug("Executing Rest...5");
4322
4323      connect(manager, SIGNAL(finished(QNetworkReply*)),
4324              this, SLOT(handleNetworkData(QNetworkReply*)));
4325
4326
4327      qDebug("Executing Rest...6");
4328
4329      request.setRawHeader("User-Agent", "MyOwnBrowser 1.0");
4330      //QNetworkReply *reply = manager->get(QNetworkRequest(QUrl("http://127.0.0.1:8000")));
4331      request.setHeader(QNetworkRequest::ContentTypeHeader,
4332      "application/json");
4333
4334      //request.setAttribute(QNetworkRequest::ConnectionEncryptedAttribute,QVariant(true));
4335
4336      QString headerData = QString("Basic YWRtaW46YWRtaW4=");
4337      request.setRawHeader("Authorization", headerData.toUtf8());
4338
4339      request.setRawHeader("xhrFields", "{ withCredentials:true }");
4340
4341      //QNetworkReply *reply = manager->post(request, postData.encodedQuery());
4342      //QNetworkReply *reply = manager->get(request);
4343
4344      QNetworkReply *reply = manager->post(request, postData.toUtf8());
4345      //QNetworkReply *reply = manager->post(request,postData.toString(QUrl::FullyEncoded).toUtf8());
4346      qDebug("Executing Rest..............*7");
4347
4348      connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
4349                this, SLOT(slotError(QNetworkReply::NetworkError)));
4350
4351      QEventLoop loop;
4352      connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
4353      loop.exec();
4354
4355      connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
4356                this, SLOT(slotError(QNetworkReply::NetworkError)));
4357
4358      qDebug("Executing Rest...8");
4359
4360      QString result = _currentrest;
4361      //QString result = "....test1";
4362      return result;
4363
4364}
4365
4366void MainWindow::on_windowCertificate() {
4367
4368    qDebug("** on_windowSelecctionCertificate(). **");
4369
4370    m_certificate = new QDialog;
4371    m_layoutmensaje = new QHBoxLayout;
4372    m_ClayoutBotones = new QHBoxLayout;
4373    m_layoutTableView = new QHBoxLayout;
4374    m_ClayoutPrincipal = new QVBoxLayout(m_certificate);
4375
4376    m_mensaje = new QLabel("Al seleccionar el certificado acepto que mi nombre y certificado serán enviado al proveedor de servicio");
4377
4378    m_listCertificate = new QTableView;
4379    QString ok = "verdadero";
4380    close_windowCertificate = "falso";
4381
4382    //Conectar con el dispositivo
4383    m_nct = new CryptoToken();
4384
4385
4386
4387
4388    //Sección para verificar si hay dispositivo cryptografico conectado
4389    try {
4390        certificateInformationListN = m_nct->getDeviceCertificates(); //obtener los certificados disponible en el dispositivo
4391
4392        qDebug("******************* Certification Info **********************");
4393        for(int i= 0; i < certificateInformationListN.size(); i++) {
4394            for(int j= 0; j < certificateInformationListN[i].size(); j++) {
4395                QString data = certificateInformationListN[i].at(j);
4396                if (j == 3)  {
4397                    certInHex = data;
4398                }
4399                qDebug(",,,,addngCERTIFICATION INFO %d %d: |%s|",i,j, qPrintable(data));
4400
4401            }
4402            qDebug(".................");
4403        }
4404    }catch(std::runtime_error e){
4405        ok = "falso";
4406        qDebug("exception");
4407        qDebug("%s", e.what());
4408        QString msj = e.what();
4409        QMessageBox msgBox;
4410        msgBox.setText(msj);
4411        msgBox.exec();
4412     }
4413
4414
4415   
4416    //Si hay dispositivo conectado creo la ventana para mostrar los certificados si hay disponibles
4417    if(ok == "verdadero") {
4418        m_model = new QStandardItemModel(certificateInformationListN.size(),3,this); //contruye un model en función al número de certificado disponible en el dispositivo
4419        m_model->setHeaderData(0, Qt::Horizontal, QObject::tr("Certificado"));
4420        m_model->setHeaderData(1, Qt::Horizontal, QObject::tr("Tipo"));
4421        m_model->setHeaderData(2, Qt::Horizontal, QObject::tr("Valido hasta"));
4422        m_listCertificate->setModel(m_model);
4423        m_listCertificate->setShowGrid(false);
4424        m_listCertificate->verticalHeader()->setVisible(false);
4425        m_listCertificate->setSelectionBehavior(QAbstractItemView::SelectRows); //para seleccionar la fila
4426        m_listCertificate->setSelectionMode(QAbstractItemView::SingleSelection); //para seleccionar solo una fila
4427        m_listCertificate->setEditTriggers(QAbstractItemView::NoEditTriggers); //para no modificar los campos de la tabla
4428        QStandardItem *item;
4429        // recorre los certificados que estan en el dispositivo cryptografico y llena la lista de certificadoz
4430        for (int row = 0; row < certificateInformationListN.size(); ++row) {
4431            for (int column = 0; column < 3; ++column) {
4432                item = new QStandardItem(certificateInformationListN[row][column]);
4433                //QStandardItem *item = new QStandardItem(certificateInformationListN[row][column]);
4434                m_model->setItem(row,column,item);
4435            }
4436        }
4437
4438        m_listCertificate->setFocusPolicy(Qt::NoFocus);
4439        m_listCertificate->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
4440
4441        m_CbotonAceptar = new QPushButton("Aceptar");
4442        m_CbotonAceptar->setDisabled(true);
4443        m_CbotonCancelar = new QPushButton("Cancelar");
4444
4445        m_ClayoutBotones->addStretch();
4446        m_ClayoutBotones->addWidget(m_CbotonAceptar);
4447        m_ClayoutBotones->addWidget(m_CbotonCancelar);
4448
4449        m_layoutmensaje->addWidget(m_mensaje);
4450        m_layoutTableView->addWidget(m_listCertificate);
4451
4452        m_ClayoutPrincipal->addLayout(m_layoutmensaje);
4453        m_ClayoutPrincipal->addLayout(m_layoutTableView);
4454        m_ClayoutPrincipal->addLayout(m_ClayoutBotones);
4455
4456
4457        m_certificate->setWindowTitle(QObject::trUtf8("Seleccionar el certificado del firmante:"));
4458
4459        connect(m_CbotonCancelar, SIGNAL(clicked()),this,SLOT(on_close_windowCertificate()));
4460        connect(m_CbotonAceptar, SIGNAL(clicked()),this,SLOT(on_selectCertificate()));
4461        connect(m_listCertificate, SIGNAL(clicked(QModelIndex)),this,SLOT(on_activateButtonCertificate()));
4462        m_certificate->exec();
4463
4464        /**if(close_windowCertificate == "falso" || close_PIN == "falso") {
4465            //Conectar con el dispositivo
4466            QString hash("cdbc23b0c23e164225acd0dbf8afecc420ca61ded483a0a43d88d4a76916cc04");
4467            std::vector<unsigned char> result = m_nct->signHash(hash, m_campoContrasenia->text(), certSelect);
4468            qDebug("** signature: ");
4469            qDebug("Resultado %s", m_nct->toHex(result));
4470            open("/home/pbuitrago/Cenditel/Seguridad/POA-2015/Portal_verificacion_firma/reconocimientoMurachi-signed.pdf"); // para refrescar el archivo al firmado
4471            m_detailsSignatureView->setModel(view_table_verify_signature()); // refresca la table de verificación de firma electrónica
4472            QMessageBox msgBox;
4473            msgBox.setText("El archivo se firmo con exitos..!");
4474            msgBox.exec();
4475        }
4476        if(close_windowCertificate == "verdadero") {
4477            qDebug("El usuario cancelo en la selección del certificado");
4478        }
4479        if(close_PIN == "verdadero") {
4480            qDebug("El usuario cancelo en la introduccion del PIN");
4481        } **/
4482    }
4483}
4484
4485void MainWindow::on_activateButtonCertificate() {
4486    qDebug("*** on_activateButtonCertificate ***");
4487    m_CbotonAceptar->setDisabled(false);
4488}
4489
4490void MainWindow::on_close_windowCertificate() {
4491    qDebug("** on_close_windowCertificate() **");
4492    m_certificate->close();
4493    qDebug("** Accion cancelada por el usuario **");
4494    close_windowCertificate = "verdadero";
4495}
4496
4497void MainWindow::on_selectCertificate() {
4498
4499    qDebug("** on_selectCertificate() **");
4500    QModelIndex select = m_listCertificate->selectionModel()->currentIndex();
4501    QString selectText = select.data(Qt::DisplayRole).toString();
4502    QString label = QString("%1").arg(select.row());
4503    certSelect = select.row();
4504    qDebug("seleccion: %s", qPrintable(label));
4505    qDebug("columna: %s", qPrintable(selectText));
4506    m_certificate->accept();
4507    on_windowPIN(1);
4508
4509}
4510
4511bool MainWindowAdaptor::closeTab(const QString& absoluteFilePath)
4512{
4513    qDebug("** closeTab **");
4514    if(mainWindow()->m_tabWidget->currentIndex() == -1) { return false; }
4515
4516    const QFileInfo fileInfo(absoluteFilePath);
4517
4518    foreach(DocumentView* tab, mainWindow()->tabs())
4519    {
4520        if(tab->fileInfo() == fileInfo)
4521        {
4522            if(mainWindow()->saveModifications(tab))
4523            {
4524                mainWindow()->closeTab(tab);
4525            }
4526
4527            return true;
4528        }
4529    }
4530
4531    return false;
4532}
4533
4534void MainWindow::on_currentChanged_selection() {
4535    qDebug("** on_currentChanged_selection() **");
4536     m_CbotonAceptar->setDisabled(false);
4537}
4538
4539
4540
4541#undef ONLY_IF_CURRENT_TAB
4542
4543inline MainWindow* MainWindowAdaptor::mainWindow() const
4544{
4545    return qobject_cast< MainWindow* >(parent());
4546}
4547
4548# endif // WITH_DBUS
4549
4550} // qpdfview
Note: See TracBrowser for help on using the repository browser.