XpdfViewer.cc (xpdf-4.03) | : | XpdfViewer.cc (xpdf-4.04) | ||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// Copyright 2015 Glyph & Cog, LLC | // Copyright 2015 Glyph & Cog, LLC | |||
// | // | |||
//======================================================================== | //======================================================================== | |||
#include <aconf.h> | #include <aconf.h> | |||
#include <math.h> | #include <math.h> | |||
#include <QAbstractItemModel> | #include <QAbstractItemModel> | |||
#include <QAction> | #include <QAction> | |||
#include <QActionGroup> | ||||
#include <QButtonGroup> | #include <QButtonGroup> | |||
#include <QClipboard> | #include <QClipboard> | |||
#include <QComboBox> | #include <QComboBox> | |||
#include <QDesktopServices> | #include <QDesktopServices> | |||
#include <QDesktopWidget> | ||||
#include <QFileDialog> | #include <QFileDialog> | |||
#include <QFrame> | #include <QFrame> | |||
#include <QGridLayout> | #include <QGridLayout> | |||
#include <QHBoxLayout> | #include <QHBoxLayout> | |||
#include <QHeaderView> | #include <QHeaderView> | |||
#include <QKeyEvent> | #include <QKeyEvent> | |||
#include <QLabel> | #include <QLabel> | |||
#include <QLineEdit> | #include <QLineEdit> | |||
#include <QListWidget> | #include <QListWidget> | |||
#include <QLocalSocket> | #include <QLocalSocket> | |||
#include <QMenu> | #include <QMenu> | |||
#include <QMenuBar> | #include <QMenuBar> | |||
#include <QMessageBox> | #include <QMessageBox> | |||
#include <QMimeData> | #include <QMimeData> | |||
#include <QMouseEvent> | #include <QMouseEvent> | |||
#include <QProcess> | #include <QProcess> | |||
#include <QProgressDialog> | #include <QProgressDialog> | |||
#include <QPropertyAnimation> | #include <QPropertyAnimation> | |||
#include <QPushButton> | #include <QPushButton> | |||
#include <QRadioButton> | #include <QRadioButton> | |||
#include <QScreen> | ||||
#include <QScrollBar> | #include <QScrollBar> | |||
#include <QSignalMapper> | #include <QSignalMapper> | |||
#include <QSplitter> | #include <QSplitter> | |||
#include <QStackedLayout> | #include <QStackedLayout> | |||
#include <QStackedWidget> | #include <QStackedWidget> | |||
#include <QTabWidget> | ||||
#include <QTableWidget> | #include <QTableWidget> | |||
#include <QTextBrowser> | #include <QTextBrowser> | |||
#include <QTimer> | #include <QTimer> | |||
#include <QToolBar> | #include <QToolBar> | |||
#include <QTreeView> | #include <QTreeView> | |||
#include <QVBoxLayout> | #include <QVBoxLayout> | |||
#include "GString.h" | #include "GString.h" | |||
#include "GList.h" | #include "GList.h" | |||
#include "GlobalParams.h" | #include "GlobalParams.h" | |||
#include "QtPDFCore.h" | #include "QtPDFCore.h" | |||
#include "PDFDoc.h" | #include "PDFDoc.h" | |||
#include "AcroForm.h" | ||||
#include "Annot.h" | ||||
#include "TextString.h" | #include "TextString.h" | |||
#include "Zoox.h" | ||||
#include "XpdfApp.h" | #include "XpdfApp.h" | |||
#include "XpdfViewer.h" | #include "XpdfViewer.h" | |||
#include "gmempp.h" | #include "gmempp.h" | |||
//------------------------------------------------------------------------ | //------------------------------------------------------------------------ | |||
static const char *aboutHTML = | static const char *aboutHTML = | |||
"<h3><img align=\"middle\" src=\"qrc:/xpdf-icon\"> " | "<h3><img align=\"middle\" src=\"qrc:/xpdf-icon\"> " | |||
"Xpdf" | "Xpdf" | |||
"</h3>" | "</h3>" | |||
skipping to change at line 149 | skipping to change at line 154 | |||
{ "followLinkNoSel", 0, gTrue, gTrue, &XpdfViewer::cmdFollowLinkNoSe l }, | { "followLinkNoSel", 0, gTrue, gTrue, &XpdfViewer::cmdFollowLinkNoSe l }, | |||
{ "fullScreenMode", 0, gFalse, gFalse, &XpdfViewer::cmdFullScreenMode }, | { "fullScreenMode", 0, gFalse, gFalse, &XpdfViewer::cmdFullScreenMode }, | |||
{ "goBackward", 0, gFalse, gFalse, &XpdfViewer::cmdGoBackward }, | { "goBackward", 0, gFalse, gFalse, &XpdfViewer::cmdGoBackward }, | |||
{ "goForward", 0, gFalse, gFalse, &XpdfViewer::cmdGoForward }, | { "goForward", 0, gFalse, gFalse, &XpdfViewer::cmdGoForward }, | |||
{ "gotoDest", 1, gTrue, gFalse, &XpdfViewer::cmdGotoDest }, | { "gotoDest", 1, gTrue, gFalse, &XpdfViewer::cmdGotoDest }, | |||
{ "gotoLastPage", 0, gTrue, gFalse, &XpdfViewer::cmdGotoLastPage } , | { "gotoLastPage", 0, gTrue, gFalse, &XpdfViewer::cmdGotoLastPage } , | |||
//~ { "gotoLastPageNoScroll", 0, gTrue, gFalse, &XpdfViewer::cmdGotoLastPa geNoScroll }, | //~ { "gotoLastPageNoScroll", 0, gTrue, gFalse, &XpdfViewer::cmdGotoLastPa geNoScroll }, | |||
{ "gotoPage", 1, gTrue, gFalse, &XpdfViewer::cmdGotoPage }, | { "gotoPage", 1, gTrue, gFalse, &XpdfViewer::cmdGotoPage }, | |||
//~ { "gotoPageNoScroll", 1, gTrue, gFalse, &XpdfViewer::cmdGotoPageNo Scroll }, | //~ { "gotoPageNoScroll", 1, gTrue, gFalse, &XpdfViewer::cmdGotoPageNo Scroll }, | |||
{ "help", 0, gFalse, gFalse, &XpdfViewer::cmdHelp }, | { "help", 0, gFalse, gFalse, &XpdfViewer::cmdHelp }, | |||
{ "hideMenuBar", 0, gFalse, gFalse, &XpdfViewer::cmdHideMenuBar }, | ||||
{ "hideToolbar", 0, gFalse, gFalse, &XpdfViewer::cmdHideToolbar }, | { "hideToolbar", 0, gFalse, gFalse, &XpdfViewer::cmdHideToolbar }, | |||
{ "horizontalContinuousMode",0, gFalse, gFalse, &XpdfViewer::cmdHorizontalCont inuousMode }, | { "horizontalContinuousMode",0, gFalse, gFalse, &XpdfViewer::cmdHorizontalCont inuousMode }, | |||
{ "linearSelectMode", 0, gFalse, gFalse, &XpdfViewer::cmdLinearSelectMo de }, | { "linearSelectMode", 0, gFalse, gFalse, &XpdfViewer::cmdLinearSelectMo de }, | |||
{ "loadTabState", 0, gFalse, gFalse, &XpdfViewer::cmdLoadTabState } , | { "loadTabState", 0, gFalse, gFalse, &XpdfViewer::cmdLoadTabState } , | |||
{ "newTab", 0, gFalse, gFalse, &XpdfViewer::cmdNewTab }, | { "newTab", 0, gFalse, gFalse, &XpdfViewer::cmdNewTab }, | |||
{ "newWindow", 0, gFalse, gFalse, &XpdfViewer::cmdNewWindow }, | { "newWindow", 0, gFalse, gFalse, &XpdfViewer::cmdNewWindow }, | |||
{ "nextPage", 0, gTrue, gFalse, &XpdfViewer::cmdNextPage }, | { "nextPage", 0, gTrue, gFalse, &XpdfViewer::cmdNextPage }, | |||
{ "nextPageNoScroll", 0, gTrue, gFalse, &XpdfViewer::cmdNextPageNoScro ll }, | { "nextPageNoScroll", 0, gTrue, gFalse, &XpdfViewer::cmdNextPageNoScro ll }, | |||
{ "nextTab", 0, gTrue, gFalse, &XpdfViewer::cmdNextTab }, | { "nextTab", 0, gFalse, gFalse, &XpdfViewer::cmdNextTab }, | |||
{ "open", 0, gFalse, gFalse, &XpdfViewer::cmdOpen }, | { "open", 0, gFalse, gFalse, &XpdfViewer::cmdOpen }, | |||
{ "openErrorWindow", 0, gFalse, gFalse, &XpdfViewer::cmdOpenErrorWindo w }, | { "openErrorWindow", 0, gFalse, gFalse, &XpdfViewer::cmdOpenErrorWindo w }, | |||
{ "openFile", 1, gFalse, gFalse, &XpdfViewer::cmdOpenFile }, | { "openFile", 1, gFalse, gFalse, &XpdfViewer::cmdOpenFile }, | |||
{ "openFile2", 5, gFalse, gFalse, &XpdfViewer::cmdOpenFile2 }, | ||||
{ "openFileAtDest", 2, gFalse, gFalse, &XpdfViewer::cmdOpenFileAtDest }, | { "openFileAtDest", 2, gFalse, gFalse, &XpdfViewer::cmdOpenFileAtDest }, | |||
{ "openFileAtDestIn", 3, gFalse, gFalse, &XpdfViewer::cmdOpenFileAtDest In }, | { "openFileAtDestIn", 3, gFalse, gFalse, &XpdfViewer::cmdOpenFileAtDest In }, | |||
{ "openFileAtPage", 2, gFalse, gFalse, &XpdfViewer::cmdOpenFileAtPage }, | { "openFileAtPage", 2, gFalse, gFalse, &XpdfViewer::cmdOpenFileAtPage }, | |||
{ "openFileAtPageIn", 3, gFalse, gFalse, &XpdfViewer::cmdOpenFileAtPage In }, | { "openFileAtPageIn", 3, gFalse, gFalse, &XpdfViewer::cmdOpenFileAtPage In }, | |||
{ "openFileIn", 2, gFalse, gFalse, &XpdfViewer::cmdOpenFileIn }, | { "openFileIn", 2, gFalse, gFalse, &XpdfViewer::cmdOpenFileIn }, | |||
{ "openIn", 1, gFalse, gFalse, &XpdfViewer::cmdOpenIn }, | { "openIn", 1, gFalse, gFalse, &XpdfViewer::cmdOpenIn }, | |||
{ "openSidebar", 0, gFalse, gFalse, &XpdfViewer::cmdOpenSidebar }, | { "openSidebar", 0, gFalse, gFalse, &XpdfViewer::cmdOpenSidebar }, | |||
{ "openSidebarMoveResizeWin", 0, gFalse, gFalse, &XpdfViewer::cmdOpenSideba rMoveResizeWin }, | { "openSidebarMoveResizeWin", 0, gFalse, gFalse, &XpdfViewer::cmdOpenSideba rMoveResizeWin }, | |||
{ "openSidebarResizeWin", 0, gFalse, gFalse, &XpdfViewer::cmdOpenSidebarRes izeWin }, | { "openSidebarResizeWin", 0, gFalse, gFalse, &XpdfViewer::cmdOpenSidebarRes izeWin }, | |||
{ "pageDown", 0, gTrue, gFalse, &XpdfViewer::cmdPageDown }, | { "pageDown", 0, gTrue, gFalse, &XpdfViewer::cmdPageDown }, | |||
{ "pageUp", 0, gTrue, gFalse, &XpdfViewer::cmdPageUp }, | { "pageUp", 0, gTrue, gFalse, &XpdfViewer::cmdPageUp }, | |||
{ "postPopupMenu", 0, gFalse, gTrue, &XpdfViewer::cmdPostPopupMenu }, | { "postPopupMenu", 0, gFalse, gTrue, &XpdfViewer::cmdPostPopupMenu }, | |||
{ "prevPage", 0, gTrue, gFalse, &XpdfViewer::cmdPrevPage }, | { "prevPage", 0, gTrue, gFalse, &XpdfViewer::cmdPrevPage }, | |||
{ "prevPageNoScroll", 0, gTrue, gFalse, &XpdfViewer::cmdPrevPageNoScro ll }, | { "prevPageNoScroll", 0, gTrue, gFalse, &XpdfViewer::cmdPrevPageNoScro ll }, | |||
{ "prevTab", 0, gTrue, gFalse, &XpdfViewer::cmdPrevTab }, | { "prevTab", 0, gFalse, gFalse, &XpdfViewer::cmdPrevTab }, | |||
#if XPDFWIDGET_PRINTING | #if XPDFWIDGET_PRINTING | |||
{ "print", 0, gTrue, gFalse, &XpdfViewer::cmdPrint }, | { "print", 0, gTrue, gFalse, &XpdfViewer::cmdPrint }, | |||
#endif | #endif | |||
{ "quit", 0, gFalse, gFalse, &XpdfViewer::cmdQuit }, | { "quit", 0, gFalse, gFalse, &XpdfViewer::cmdQuit }, | |||
{ "raise", 0, gFalse, gFalse, &XpdfViewer::cmdRaise }, | { "raise", 0, gFalse, gFalse, &XpdfViewer::cmdRaise }, | |||
//~ { "redraw", 0, gTrue, gFalse, &XpdfViewer::cmdRedraw }, | //~ { "redraw", 0, gTrue, gFalse, &XpdfViewer::cmdRedraw }, | |||
{ "reload", 0, gTrue, gFalse, &XpdfViewer::cmdReload }, | { "reload", 0, gTrue, gFalse, &XpdfViewer::cmdReload }, | |||
{ "rotateCCW", 0, gTrue, gFalse, &XpdfViewer::cmdRotateCCW }, | { "rotateCCW", 0, gTrue, gFalse, &XpdfViewer::cmdRotateCCW }, | |||
{ "rotateCW", 0, gTrue, gFalse, &XpdfViewer::cmdRotateCW }, | { "rotateCW", 0, gTrue, gFalse, &XpdfViewer::cmdRotateCW }, | |||
{ "run", 1, gFalse, gFalse, &XpdfViewer::cmdRun }, | { "run", 1, gFalse, gFalse, &XpdfViewer::cmdRun }, | |||
skipping to change at line 206 | skipping to change at line 213 | |||
{ "scrollToBottomRight", 0, gTrue, gFalse, &XpdfViewer::cmdScrollToBottom Right }, | { "scrollToBottomRight", 0, gTrue, gFalse, &XpdfViewer::cmdScrollToBottom Right }, | |||
{ "scrollToLeftEdge", 0, gTrue, gFalse, &XpdfViewer::cmdScrollToLeftEd ge }, | { "scrollToLeftEdge", 0, gTrue, gFalse, &XpdfViewer::cmdScrollToLeftEd ge }, | |||
{ "scrollToRightEdge", 0, gTrue, gFalse, &XpdfViewer::cmdScrollToRightE dge }, | { "scrollToRightEdge", 0, gTrue, gFalse, &XpdfViewer::cmdScrollToRightE dge }, | |||
{ "scrollToTopEdge", 0, gTrue, gFalse, &XpdfViewer::cmdScrollToTopEdg e }, | { "scrollToTopEdge", 0, gTrue, gFalse, &XpdfViewer::cmdScrollToTopEdg e }, | |||
{ "scrollToTopLeft", 0, gTrue, gFalse, &XpdfViewer::cmdScrollToTopLef t }, | { "scrollToTopLeft", 0, gTrue, gFalse, &XpdfViewer::cmdScrollToTopLef t }, | |||
{ "scrollUp", 1, gTrue, gFalse, &XpdfViewer::cmdScrollUp }, | { "scrollUp", 1, gTrue, gFalse, &XpdfViewer::cmdScrollUp }, | |||
{ "scrollUpPrevPage", 1, gTrue, gFalse, &XpdfViewer::cmdScrollUpPrevPa ge }, | { "scrollUpPrevPage", 1, gTrue, gFalse, &XpdfViewer::cmdScrollUpPrevPa ge }, | |||
{ "selectLine", 0, gTrue, gTrue, &XpdfViewer::cmdSelectLine }, | { "selectLine", 0, gTrue, gTrue, &XpdfViewer::cmdSelectLine }, | |||
{ "selectWord", 0, gTrue, gTrue, &XpdfViewer::cmdSelectWord }, | { "selectWord", 0, gTrue, gTrue, &XpdfViewer::cmdSelectWord }, | |||
{ "setSelection", 5, gTrue, gFalse, &XpdfViewer::cmdSetSelection } , | { "setSelection", 5, gTrue, gFalse, &XpdfViewer::cmdSetSelection } , | |||
{ "showAttachmentsPane", 0, gFalse, gFalse, &XpdfViewer::cmdShowAttachment | ||||
sPane }, | ||||
{ "showDocumentInfo", 0, gTrue, gFalse, &XpdfViewer::cmdShowDocumentIn | ||||
fo }, | ||||
{ "showKeyBindings", 0, gFalse, gFalse, &XpdfViewer::cmdShowKeyBinding s }, | { "showKeyBindings", 0, gFalse, gFalse, &XpdfViewer::cmdShowKeyBinding s }, | |||
{ "showLayersPane", 0, gFalse, gFalse, &XpdfViewer::cmdShowLayersPane | ||||
}, | ||||
{ "showMenuBar", 0, gFalse, gFalse, &XpdfViewer::cmdShowMenuBar }, | ||||
{ "showOutlinePane", 0, gFalse, gFalse, &XpdfViewer::cmdShowOutlinePan | ||||
e }, | ||||
{ "showToolbar", 0, gFalse, gFalse, &XpdfViewer::cmdShowToolbar }, | { "showToolbar", 0, gFalse, gFalse, &XpdfViewer::cmdShowToolbar }, | |||
{ "shrinkSidebar", 1, gFalse, gFalse, &XpdfViewer::cmdShrinkSidebar }, | { "shrinkSidebar", 1, gFalse, gFalse, &XpdfViewer::cmdShrinkSidebar }, | |||
{ "sideBySideContinuousMode",0, gFalse, gFalse, &XpdfViewer::cmdSideBySideCont inuousMode }, | { "sideBySideContinuousMode",0, gFalse, gFalse, &XpdfViewer::cmdSideBySideCont inuousMode }, | |||
{ "sideBySideSingleMode", 0, gFalse, gFalse, &XpdfViewer::cmdSideBySideSing leMode }, | { "sideBySideSingleMode", 0, gFalse, gFalse, &XpdfViewer::cmdSideBySideSing leMode }, | |||
{ "singlePageMode", 0, gFalse, gFalse, &XpdfViewer::cmdSinglePageMode }, | { "singlePageMode", 0, gFalse, gFalse, &XpdfViewer::cmdSinglePageMode }, | |||
{ "startExtendedSelection", 0, gTrue, gTrue, &XpdfViewer::cmdStartExtendedS election }, | { "startExtendedSelection", 0, gTrue, gTrue, &XpdfViewer::cmdStartExtendedS election }, | |||
{ "startPan", 0, gTrue, gTrue, &XpdfViewer::cmdStartPan }, | { "startPan", 0, gTrue, gTrue, &XpdfViewer::cmdStartPan }, | |||
{ "startSelection", 0, gTrue, gTrue, &XpdfViewer::cmdStartSelection }, | { "startSelection", 0, gTrue, gTrue, &XpdfViewer::cmdStartSelection }, | |||
{ "toggleContinuousMode", 0, gFalse, gFalse, &XpdfViewer::cmdToggleContinuo usMode }, | { "toggleContinuousMode", 0, gFalse, gFalse, &XpdfViewer::cmdToggleContinuo usMode }, | |||
{ "toggleFullScreenMode", 0, gFalse, gFalse, &XpdfViewer::cmdToggleFullScre enMode }, | { "toggleFullScreenMode", 0, gFalse, gFalse, &XpdfViewer::cmdToggleFullScre enMode }, | |||
{ "toggleMenuBar", 0, gFalse, gFalse, &XpdfViewer::cmdToggleMenuBar }, | ||||
{ "toggleSelectMode", 0, gFalse, gFalse, &XpdfViewer::cmdToggleSelectMo de }, | { "toggleSelectMode", 0, gFalse, gFalse, &XpdfViewer::cmdToggleSelectMo de }, | |||
{ "toggleSidebar", 0, gFalse, gFalse, &XpdfViewer::cmdToggleSidebar }, | { "toggleSidebar", 0, gFalse, gFalse, &XpdfViewer::cmdToggleSidebar }, | |||
{ "toggleSidebarMoveResizeWin", 0, gFalse, gFalse, &XpdfViewer::cmdToggleSide barMoveResizeWin }, | { "toggleSidebarMoveResizeWin", 0, gFalse, gFalse, &XpdfViewer::cmdToggleSide barMoveResizeWin }, | |||
{ "toggleSidebarResizeWin", 0, gFalse, gFalse, &XpdfViewer::cmdToggleSidebarR esizeWin }, | { "toggleSidebarResizeWin", 0, gFalse, gFalse, &XpdfViewer::cmdToggleSidebarR esizeWin }, | |||
{ "toggleToolbar", 0, gFalse, gFalse, &XpdfViewer::cmdShowToolbar }, | { "toggleToolbar", 0, gFalse, gFalse, &XpdfViewer::cmdToggleToolbar }, | |||
{ "viewPageLabels", 0, gFalse, gFalse, &XpdfViewer::cmdViewPageLabels }, | { "viewPageLabels", 0, gFalse, gFalse, &XpdfViewer::cmdViewPageLabels }, | |||
{ "viewPageNumbers", 0, gFalse, gFalse, &XpdfViewer::cmdViewPageNumber s }, | { "viewPageNumbers", 0, gFalse, gFalse, &XpdfViewer::cmdViewPageNumber s }, | |||
{ "windowMode", 0, gFalse, gFalse, &XpdfViewer::cmdWindowMode }, | { "windowMode", 0, gFalse, gFalse, &XpdfViewer::cmdWindowMode }, | |||
{ "zoomFitPage", 0, gFalse, gFalse, &XpdfViewer::cmdZoomFitPage }, | { "zoomFitPage", 0, gFalse, gFalse, &XpdfViewer::cmdZoomFitPage }, | |||
{ "zoomFitWidth", 0, gFalse, gFalse, &XpdfViewer::cmdZoomFitWidth } , | { "zoomFitWidth", 0, gFalse, gFalse, &XpdfViewer::cmdZoomFitWidth } , | |||
{ "zoomIn", 0, gFalse, gFalse, &XpdfViewer::cmdZoomIn }, | { "zoomIn", 0, gFalse, gFalse, &XpdfViewer::cmdZoomIn }, | |||
{ "zoomOut", 0, gFalse, gFalse, &XpdfViewer::cmdZoomOut }, | { "zoomOut", 0, gFalse, gFalse, &XpdfViewer::cmdZoomOut }, | |||
{ "zoomPercent", 1, gFalse, gFalse, &XpdfViewer::cmdZoomPercent }, | { "zoomPercent", 1, gFalse, gFalse, &XpdfViewer::cmdZoomPercent }, | |||
{ "zoomToSelection", 0, gTrue, gFalse, &XpdfViewer::cmdZoomToSelectio n } | { "zoomToSelection", 0, gTrue, gFalse, &XpdfViewer::cmdZoomToSelectio n } | |||
}; | }; | |||
skipping to change at line 289 | skipping to change at line 302 | |||
connect(clearBtn, SIGNAL(clicked()), this, SLOT(clearBtnPressed())); | connect(clearBtn, SIGNAL(clicked()), this, SLOT(clearBtnPressed())); | |||
btnLayout->addWidget(clearBtn); | btnLayout->addWidget(clearBtn); | |||
btnLayout->addStretch(1); | btnLayout->addStretch(1); | |||
list = new QListWidget(); | list = new QListWidget(); | |||
topLayout->addWidget(list); | topLayout->addWidget(list); | |||
setLayout(topLayout); | setLayout(topLayout); | |||
#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0) | ||||
lastSize = QSize(list->fontMetrics().horizontalAdvance("m") * 50, | ||||
list->fontMetrics().lineSpacing() * 16); | ||||
#else | ||||
lastSize = QSize(list->fontMetrics().width("m") * 50, | lastSize = QSize(list->fontMetrics().width("m") * 50, | |||
list->fontMetrics().lineSpacing() * 16); | list->fontMetrics().lineSpacing() * 16); | |||
#endif | ||||
setErrorCallback(&errorCbk, this); | setErrorCallback(&errorCbk, this); | |||
} | } | |||
XpdfErrorWindow::~XpdfErrorWindow() { | XpdfErrorWindow::~XpdfErrorWindow() { | |||
// If the user quits while a page is rendering, we want any | // If the user quits while a page is rendering, we want any | |||
// subsequent error messages to vanish -- they shouldn't try to | // subsequent error messages to vanish -- they shouldn't try to | |||
// update the error window (which has been deleted), and they | // update the error window (which has been deleted), and they | |||
// shouldn't get dumped to stderr. | // shouldn't get dumped to stderr. | |||
setErrorCallback(dummyErrorCbk, NULL); | setErrorCallback(dummyErrorCbk, NULL); | |||
skipping to change at line 746 | skipping to change at line 764 | |||
vis = value == Qt::Checked; | vis = value == Qt::Checked; | |||
if (vis != pdf->getLayerVisibility(layer)) { | if (vis != pdf->getLayerVisibility(layer)) { | |||
pdf->setLayerVisibility(layer, vis); | pdf->setLayerVisibility(layer, vis); | |||
} | } | |||
emit dataChanged(idx, idx); | emit dataChanged(idx, idx); | |||
return true; | return true; | |||
} | } | |||
Qt::ItemFlags LayerModel::flags(const QModelIndex &idx) const { | Qt::ItemFlags LayerModel::flags(const QModelIndex &idx) const { | |||
if (!idx.isValid()) { | if (!idx.isValid()) { | |||
return 0; | return Qt::NoItemFlags; | |||
} | } | |||
// NB: this does not include Qt::ItemIsUserCheckable because we use | // NB: this does not include Qt::ItemIsUserCheckable because we use | |||
// the QTreeView::clicked signal to toggle the checkbox -- which | // the QTreeView::clicked signal to toggle the checkbox -- which | |||
// handles clicks anywhere in the item, including in the checkbox | // handles clicks anywhere in the item, including in the checkbox | |||
return Qt::ItemIsEnabled; | return Qt::ItemIsEnabled; | |||
} | } | |||
int LayerModel::getOrderRow(XpdfLayerOrderHandle order) const { | int LayerModel::getOrderRow(XpdfLayerOrderHandle order) const { | |||
XpdfLayerOrderHandle par; | XpdfLayerOrderHandle par; | |||
int nChildren, i; | int nChildren, i; | |||
skipping to change at line 871 | skipping to change at line 889 | |||
// PDF file is loaded and before the window is shown. | // PDF file is loaded and before the window is shown. | |||
void XpdfViewer::tweakSize() { | void XpdfViewer::tweakSize() { | |||
if (initialSidebarWidth > 0) { | if (initialSidebarWidth > 0) { | |||
QList<int> sidebarSplitterSizes = sidebarSplitter->sizes(); | QList<int> sidebarSplitterSizes = sidebarSplitter->sizes(); | |||
sidebarSplitterSizes[0] = initialSidebarWidth; | sidebarSplitterSizes[0] = initialSidebarWidth; | |||
sidebarSplitterSizes[1] = sidebarSplitter->widget(1)->sizeHint().width(); | sidebarSplitterSizes[1] = sidebarSplitter->widget(1)->sizeHint().width(); | |||
sidebarSplitter->setSizes(sidebarSplitterSizes); | sidebarSplitter->setSizes(sidebarSplitterSizes); | |||
} | } | |||
QSize hint = sizeHint(); | QSize hint = sizeHint(); | |||
QRect screen = QApplication::desktop()->availableGeometry(); | QRect screen = QGuiApplication::primaryScreen()->availableGeometry(); | |||
int w = hint.width(); | int w = hint.width(); | |||
int h = hint.height(); | int h = hint.height(); | |||
if (w > screen.width() - 60) { | if (w > screen.width() - 60) { | |||
w = screen.width() - 60; | w = screen.width() - 60; | |||
} | } | |||
if (h > screen.height() - 60) { | if (h > screen.height() - 60) { | |||
h = screen.height() - 60; | h = screen.height() - 60; | |||
} | } | |||
resize(w, h); | resize(w, h); | |||
} | } | |||
bool XpdfViewer::close() { | ||||
if (tabInfo->getLength() > 0) { | ||||
app->startUpdatePagesFile(); | ||||
for (int i = 0; i < tabInfo->getLength(); ++i) { | ||||
XpdfTabInfo *tab = (XpdfTabInfo *)tabInfo->get(i); | ||||
app->updatePagesFile(tab->pdf->getFileName(), tab->pdf->getMidPage()); | ||||
} | ||||
app->finishUpdatePagesFile(); | ||||
} | ||||
return QMainWindow::close(); | ||||
} | ||||
//------------------------------------------------------------------------ | //------------------------------------------------------------------------ | |||
GBool XpdfViewer::open(QString fileName, int page, QString destName, | GBool XpdfViewer::open(QString fileName, int page, QString destName, | |||
int rot, QString password) { | int rot, QString password) { | |||
XpdfWidget::ErrorCode err; | XpdfWidget::ErrorCode err; | |||
if (currentTab->pdf->hasOpenDocument()) { | ||||
app->startUpdatePagesFile(); | ||||
app->updatePagesFile(currentTab->pdf->getFileName(), | ||||
currentTab->pdf->getMidPage()); | ||||
app->finishUpdatePagesFile(); | ||||
} | ||||
err = currentTab->pdf->loadFile(fileName, password); | err = currentTab->pdf->loadFile(fileName, password); | |||
if (err != XpdfWidget::pdfOk) { | if (err != XpdfWidget::pdfOk) { | |||
QMessageBox::warning(NULL, "Xpdf Error", | QMessageBox::warning(NULL, "Xpdf Error", | |||
"Couldn't open file '" + fileName + "'"); | "Couldn't open file '" + fileName + "'"); | |||
return gFalse; | return gFalse; | |||
} | } | |||
if (!destName.isEmpty()) { | if (!destName.isEmpty()) { | |||
currentTab->pdf->gotoNamedDestination(destName); | currentTab->pdf->gotoNamedDestination(destName); | |||
} else { | } else { | |||
if (page < 0) { | ||||
page = app->getSavedPageNumber(fileName); | ||||
} | ||||
currentTab->pdf->gotoPage(page); | currentTab->pdf->gotoPage(page); | |||
} | } | |||
if (rot != 0) { | if (rot != 0) { | |||
currentTab->pdf->setRotate(rot); | currentTab->pdf->setRotate(rot); | |||
} | } | |||
// after opening a document, focus goes to the XpdfWidget | // after opening a document, focus goes to the XpdfWidget | |||
currentTab->pdf->setFocus(Qt::OtherFocusReason); | currentTab->pdf->setFocus(Qt::OtherFocusReason); | |||
lastOpenedTab = currentTab; | ||||
lastFileOpened = fileName; | lastFileOpened = fileName; | |||
return gTrue; | return gTrue; | |||
} | } | |||
GBool XpdfViewer::openInNewTab(QString fileName, int page, QString destName, | GBool XpdfViewer::openInNewTab(QString fileName, int page, QString destName, | |||
int rot, QString password, GBool switchToTab) { | int rot, QString password, GBool switchToTab) { | |||
GBool ok; | GBool ok; | |||
int oldTabIndex; | int oldTabIndex; | |||
oldTabIndex = tabList->currentRow(); | oldTabIndex = tabList->currentRow(); | |||
addTab(); | addTab(); | |||
updateModeInfo(); | updateModeInfo(); | |||
ok = open(fileName, page, destName, rot, password); | ok = open(fileName, page, destName, rot, password); | |||
if (!ok) { | if (!ok) { | |||
if (tabInfo->getLength() > 1) { | if (tabInfo->getLength() > 1) { | |||
closeTab(currentTab); | closeTab(currentTab); | |||
} | } | |||
return gFalse; | return gFalse; | |||
} | } | |||
lastOpenedTab = currentTab; | ||||
if (!switchToTab) { | if (!switchToTab) { | |||
tabList->setCurrentRow(oldTabIndex); | tabList->setCurrentRow(oldTabIndex); | |||
} | } | |||
lastFileOpened = fileName; | lastFileOpened = fileName; | |||
return gTrue; | return gTrue; | |||
} | } | |||
GBool XpdfViewer::checkOpen(QString fileName, int page, QString destName, | GBool XpdfViewer::checkOpen(QString fileName, int page, QString destName, | |||
QString password) { | QString password) { | |||
XpdfWidget::ErrorCode err; | XpdfWidget::ErrorCode err; | |||
if (fileName != currentTab->pdf->getFileName()) { | if (fileName != currentTab->pdf->getFileName()) { | |||
if (currentTab->pdf->hasOpenDocument()) { | ||||
app->startUpdatePagesFile(); | ||||
app->updatePagesFile(currentTab->pdf->getFileName(), | ||||
currentTab->pdf->getMidPage()); | ||||
app->finishUpdatePagesFile(); | ||||
} | ||||
err = currentTab->pdf->loadFile(fileName, password); | err = currentTab->pdf->loadFile(fileName, password); | |||
if (err != XpdfWidget::pdfOk) { | if (err != XpdfWidget::pdfOk) { | |||
QMessageBox::warning(NULL, "Xpdf Error", | QMessageBox::warning(NULL, "Xpdf Error", | |||
"Couldn't open file '" + fileName + "'"); | "Couldn't open file '" + fileName + "'"); | |||
return gFalse; | return gFalse; | |||
} | } | |||
} | } | |||
if (!destName.isEmpty()) { | if (!destName.isEmpty()) { | |||
currentTab->pdf->gotoNamedDestination(destName); | currentTab->pdf->gotoNamedDestination(destName); | |||
} else { | } else { | |||
if (page < 0) { | ||||
page = app->getSavedPageNumber(fileName); | ||||
} | ||||
currentTab->pdf->gotoPage(page); | currentTab->pdf->gotoPage(page); | |||
} | } | |||
// after opening a document, focus goes to the XpdfWidget | // after opening a document, focus goes to the XpdfWidget | |||
currentTab->pdf->setFocus(Qt::OtherFocusReason); | currentTab->pdf->setFocus(Qt::OtherFocusReason); | |||
lastFileOpened = fileName; | lastFileOpened = fileName; | |||
lastOpenedTab = currentTab; | ||||
return gTrue; | return gTrue; | |||
} | } | |||
// Disable the default popup menu (which shows a toggle to hide the | // Disable the default popup menu (which shows a toggle to hide the | |||
// toolbar). | // toolbar). | |||
QMenu *XpdfViewer::createPopupMenu() { | QMenu *XpdfViewer::createPopupMenu() { | |||
return NULL; | return NULL; | |||
} | } | |||
//------------------------------------------------------------------------ | //------------------------------------------------------------------------ | |||
skipping to change at line 1108 | skipping to change at line 1159 | |||
QEvent::Type eventType; | QEvent::Type eventType; | |||
if (!event) { | if (!event) { | |||
return 0; | return 0; | |||
} | } | |||
eventType = event->type(); | eventType = event->type(); | |||
if (eventType == QEvent::MouseButtonPress || | if (eventType == QEvent::MouseButtonPress || | |||
eventType == QEvent::MouseButtonRelease || | eventType == QEvent::MouseButtonRelease || | |||
eventType == QEvent::MouseButtonDblClick || | eventType == QEvent::MouseButtonDblClick || | |||
eventType == QEvent::MouseMove) { | eventType == QEvent::MouseMove) { | |||
return (int)(((QMouseEvent *)event)->x() * scaleFactor); | return (int)(((QMouseEvent *)event)->pos().x() * scaleFactor); | |||
} else if (eventType == QEvent::Wheel) { | } else if (eventType == QEvent::Wheel) { | |||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) | ||||
return (int)(((QWheelEvent *)event)->position().x() * scaleFactor); | ||||
#else | ||||
return (int)(((QWheelEvent *)event)->x() * scaleFactor); | return (int)(((QWheelEvent *)event)->x() * scaleFactor); | |||
#endif | ||||
} else { | } else { | |||
return 0; | return 0; | |||
} | } | |||
} | } | |||
int XpdfViewer::mouseY(QInputEvent *event) { | int XpdfViewer::mouseY(QInputEvent *event) { | |||
QEvent::Type eventType; | QEvent::Type eventType; | |||
if (!event) { | if (!event) { | |||
return 0; | return 0; | |||
} | } | |||
eventType = event->type(); | eventType = event->type(); | |||
if (eventType == QEvent::MouseButtonPress || | if (eventType == QEvent::MouseButtonPress || | |||
eventType == QEvent::MouseButtonRelease || | eventType == QEvent::MouseButtonRelease || | |||
eventType == QEvent::MouseButtonDblClick || | eventType == QEvent::MouseButtonDblClick || | |||
eventType == QEvent::MouseMove) { | eventType == QEvent::MouseMove) { | |||
return (int)(((QMouseEvent *)event)->y() * scaleFactor); | return (int)(((QMouseEvent *)event)->pos().y() * scaleFactor); | |||
} else if (eventType == QEvent::Wheel) { | } else if (eventType == QEvent::Wheel) { | |||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) | ||||
return (int)(((QWheelEvent *)event)->position().y() * scaleFactor); | ||||
#else | ||||
return (int)(((QWheelEvent *)event)->y() * scaleFactor); | return (int)(((QWheelEvent *)event)->y() * scaleFactor); | |||
#endif | ||||
} else { | } else { | |||
return 0; | return 0; | |||
} | } | |||
} | } | |||
void XpdfViewer::cmdAbout(GString *args[], int nArgs, QInputEvent *event) { | void XpdfViewer::cmdAbout(GString *args[], int nArgs, QInputEvent *event) { | |||
if (!aboutDialog) { | if (!aboutDialog) { | |||
createAboutDialog(); | createAboutDialog(); | |||
} | } | |||
aboutDialog->show(); | aboutDialog->show(); | |||
skipping to change at line 1151 | skipping to change at line 1210 | |||
} | } | |||
void XpdfViewer::cmdBlockSelectMode(GString *args[], int nArgs, | void XpdfViewer::cmdBlockSelectMode(GString *args[], int nArgs, | |||
QInputEvent *event) { | QInputEvent *event) { | |||
currentTab->pdf->setBlockSelectMode(); | currentTab->pdf->setBlockSelectMode(); | |||
updateSelectModeInfo(); | updateSelectModeInfo(); | |||
} | } | |||
void XpdfViewer::cmdCheckOpenFile(GString *args[], int nArgs, | void XpdfViewer::cmdCheckOpenFile(GString *args[], int nArgs, | |||
QInputEvent *event) { | QInputEvent *event) { | |||
checkOpen(args[0]->getCString(), 1, "", ""); | checkOpen(args[0]->getCString(), -1, "", ""); | |||
} | } | |||
void XpdfViewer::cmdCheckOpenFileAtDest(GString *args[], int nArgs, | void XpdfViewer::cmdCheckOpenFileAtDest(GString *args[], int nArgs, | |||
QInputEvent *event) { | QInputEvent *event) { | |||
checkOpen(args[0]->getCString(), 1, args[1]->getCString(), ""); | checkOpen(args[0]->getCString(), 1, args[1]->getCString(), ""); | |||
} | } | |||
void XpdfViewer::cmdCheckOpenFileAtPage(GString *args[], int nArgs, | void XpdfViewer::cmdCheckOpenFileAtPage(GString *args[], int nArgs, | |||
QInputEvent *event) { | QInputEvent *event) { | |||
checkOpen(args[0]->getCString(), atoi(args[1]->getCString()), "", ""); | checkOpen(args[0]->getCString(), atoi(args[1]->getCString()), "", ""); | |||
skipping to change at line 1404 | skipping to change at line 1463 | |||
if (pg < 1 || pg > currentTab->pdf->getNumPages()) { | if (pg < 1 || pg > currentTab->pdf->getNumPages()) { | |||
return; | return; | |||
} | } | |||
currentTab->pdf->gotoPage(pg); | currentTab->pdf->gotoPage(pg); | |||
} | } | |||
void XpdfViewer::cmdHelp(GString *args[], int nArgs, QInputEvent *event) { | void XpdfViewer::cmdHelp(GString *args[], int nArgs, QInputEvent *event) { | |||
QDesktopServices::openUrl(QUrl(helpURL, QUrl::TolerantMode)); | QDesktopServices::openUrl(QUrl(helpURL, QUrl::TolerantMode)); | |||
} | } | |||
void XpdfViewer::cmdHideMenuBar(GString *args[], int nArgs, | ||||
QInputEvent *event) { | ||||
mainMenu->hide(); | ||||
} | ||||
void XpdfViewer::cmdHideToolbar(GString *args[], int nArgs, | void XpdfViewer::cmdHideToolbar(GString *args[], int nArgs, | |||
QInputEvent *event) { | QInputEvent *event) { | |||
toolBar->hide(); | toolBar->hide(); | |||
toggleToolbarMenuItem->setChecked(false); | toggleToolbarMenuItem->setChecked(false); | |||
} | } | |||
void XpdfViewer::cmdHorizontalContinuousMode(GString *args[], int nArgs, | void XpdfViewer::cmdHorizontalContinuousMode(GString *args[], int nArgs, | |||
QInputEvent *event) { | QInputEvent *event) { | |||
currentTab->pdf->setDisplayMode(XpdfWidget::pdfDisplayHorizontalContinuous); | currentTab->pdf->setDisplayMode(XpdfWidget::pdfDisplayHorizontalContinuous); | |||
} | } | |||
void XpdfViewer::cmdLinearSelectMode(GString *args[], int nArgs, | void XpdfViewer::cmdLinearSelectMode(GString *args[], int nArgs, | |||
QInputEvent *event) { | QInputEvent *event) { | |||
currentTab->pdf->setLinearSelectMode(); | currentTab->pdf->setLinearSelectMode(); | |||
updateSelectModeInfo(); | updateSelectModeInfo(); | |||
} | } | |||
void XpdfViewer::cmdLoadTabState(GString *args[], int nArgs, | void XpdfViewer::cmdLoadTabState(GString *args[], int nArgs, | |||
QInputEvent *event) { | QInputEvent *event) { | |||
FILE *f; | GString *path = globalParams->getTabStateFile(); | |||
GString *path, *msg; | FILE *f = openFile(path->getCString(), "rb"); | |||
char line1[1024], line2[100]; | if (!f) { | |||
GBool first; | GString *msg = GString::format("Couldn't read the tab file '{0:t}'", path); | |||
int n; | ||||
path = globalParams->getTabStateFile(); | ||||
if (!(f = openFile(path->getCString(), "rb"))) { | ||||
msg = GString::format("Couldn't read the tab file '{0:t}'", path); | ||||
QMessageBox::warning(NULL, "Xpdf Error", msg->getCString()); | QMessageBox::warning(NULL, "Xpdf Error", msg->getCString()); | |||
delete msg; | delete msg; | |||
delete path; | delete path; | |||
return; | return; | |||
} | } | |||
delete path; | delete path; | |||
first = gTrue; | char line1[1024], line2[1024]; | |||
while (fgets(line1, sizeof(line1), f) && | if (!fgets(line1, sizeof(line1), f)) { | |||
fclose(f); | ||||
return; | ||||
} | ||||
size_t n = strlen(line1); | ||||
if (n > 0 && line1[n-1] == '\n') { | ||||
line1[--n] = '\0'; | ||||
} | ||||
if (n > 0 && line1[n-1] == '\r') { | ||||
line1[--n] = '\0'; | ||||
} | ||||
int format = 1; | ||||
if (!strcmp(line1, "xpdf-tabstate-2")) { | ||||
format = 2; | ||||
} | ||||
GBool first = gTrue; | ||||
while (((first && format == 1) || fgets(line1, sizeof(line1), f)) && | ||||
fgets(line2, sizeof(line2), f)) { | fgets(line2, sizeof(line2), f)) { | |||
n = (int)strlen(line1); | n = strlen(line1); | |||
if (n > 0 && line1[n-1] == '\n') { | if (n > 0 && line1[n-1] == '\n') { | |||
line1[--n] = '\0'; | line1[--n] = '\0'; | |||
} | } | |||
if (n > 0 && line1[n-1] == '\r') { | if (n > 0 && line1[n-1] == '\r') { | |||
line1[--n] = '\0'; | line1[--n] = '\0'; | |||
} | } | |||
n = (int)strlen(line2); | n = strlen(line2); | |||
if (n > 0 && line2[n-1] == '\n') { | if (n > 0 && line2[n-1] == '\n') { | |||
line2[--n] = '\0'; | line2[--n] = '\0'; | |||
} | } | |||
if (n > 0 && line2[n-1] == '\r') { | if (n > 0 && line2[n-1] == '\r') { | |||
line2[--n] = '\0'; | line2[--n] = '\0'; | |||
} | } | |||
char displayModeChar; | ||||
int page, rotate, scrollX, scrollY; | ||||
double zoom; | ||||
if (format == 2) { | ||||
sscanf(line2, "%c %d %lf %d %d %d", | ||||
&displayModeChar, &page, &zoom, &rotate, &scrollX, &scrollY); | ||||
} else { | ||||
page = atoi(line2); | ||||
rotate = 0; | ||||
// the rest are unused, but set to make gcc happy | ||||
displayModeChar = 'c'; | ||||
zoom = zoomWidth; | ||||
scrollX = scrollY = 0; | ||||
} | ||||
GBool ok; | ||||
if (first && !currentTab->pdf->hasOpenDocument()) { | if (first && !currentTab->pdf->hasOpenDocument()) { | |||
open(line1, atoi(line2), "", 0, ""); | ok = open(line1, page, "", rotate, ""); | |||
} else { | } else { | |||
openInNewTab(line1, atoi(line2), "", 0, "", gFalse); | ok = openInNewTab(line1, page, "", rotate, "", gFalse); | |||
} | ||||
if (ok && format == 2) { | ||||
XpdfWidget *pdf = lastOpenedTab->pdf; | ||||
switch (displayModeChar) { | ||||
case 's': | ||||
pdf->setDisplayMode(XpdfWidget::pdfDisplaySingle); | ||||
break; | ||||
case 'c': | ||||
pdf->setDisplayMode(XpdfWidget::pdfDisplayContinuous); | ||||
break; | ||||
case 'b': | ||||
pdf->setDisplayMode(XpdfWidget::pdfDisplaySideBySideSingle); | ||||
break; | ||||
case 'B': | ||||
pdf->setDisplayMode(XpdfWidget::pdfDisplaySideBySideContinuous); | ||||
break; | ||||
case 'h': | ||||
pdf->setDisplayMode(XpdfWidget::pdfDisplayHorizontalContinuous); | ||||
break; | ||||
default: break; | ||||
} | ||||
pdf->setRotate(rotate); | ||||
pdf->setZoom(zoom); | ||||
pdf->scrollTo(scrollX, scrollY); | ||||
} | } | |||
first = gFalse; | first = gFalse; | |||
} | } | |||
fclose(f); | fclose(f); | |||
} | } | |||
void XpdfViewer::cmdNewTab(GString *args[], int nArgs, QInputEvent *event) { | void XpdfViewer::cmdNewTab(GString *args[], int nArgs, QInputEvent *event) { | |||
addTab(); | addTab(); | |||
updateModeInfo(); | updateModeInfo(); | |||
skipping to change at line 1524 | skipping to change at line 1639 | |||
startDir.cdUp(); | startDir.cdUp(); | |||
} else { | } else { | |||
startDir = QDir("."); | startDir = QDir("."); | |||
} | } | |||
fileName = QFileDialog::getOpenFileName(this, "Open PDF File", | fileName = QFileDialog::getOpenFileName(this, "Open PDF File", | |||
startDir.canonicalPath(), | startDir.canonicalPath(), | |||
"PDF files (*.pdf)"); | "PDF files (*.pdf)"); | |||
if (fileName.isEmpty()) { | if (fileName.isEmpty()) { | |||
return; | return; | |||
} | } | |||
open(fileName, 1, "", 0, ""); | open(fileName, -1, "", 0, ""); | |||
} | } | |||
void XpdfViewer::cmdOpenErrorWindow(GString *args[], int nArgs, | void XpdfViewer::cmdOpenErrorWindow(GString *args[], int nArgs, | |||
QInputEvent *event) { | QInputEvent *event) { | |||
errorWindow->show(); | errorWindow->show(); | |||
errorWindow->raise(); | errorWindow->raise(); | |||
} | } | |||
void XpdfViewer::cmdOpenFile(GString *args[], int nArgs, QInputEvent *event) { | void XpdfViewer::cmdOpenFile(GString *args[], int nArgs, QInputEvent *event) { | |||
open(args[0]->getCString(), 1, "", 0, ""); | open(args[0]->getCString(), -1, "", 0, ""); | |||
} | ||||
void XpdfViewer::cmdOpenFile2(GString *args[], int nArgs, QInputEvent *event) { | ||||
char *file = args[0]->getCString(); | ||||
int page; | ||||
if (args[1]->getLength() == 0) { | ||||
page = -1; | ||||
} else { | ||||
page = atoi(args[1]->getCString()); | ||||
} | ||||
char *dest = args[2]->getCString(); | ||||
char *password = args[3]->getCString(); | ||||
GString *location = args[4]; | ||||
if (location->cmp("win") == 0) { | ||||
app->openInNewWindow(file, page, dest, 0, password); | ||||
} else if (location->cmp("tab") == 0) { | ||||
openInNewTab(file, page, dest, 0, password, gTrue); | ||||
} else if (location->cmp("check") == 0) { | ||||
checkOpen(file, page, dest, password); | ||||
} else { | ||||
open(file, page, dest, 0, password); | ||||
} | ||||
} | } | |||
void XpdfViewer::cmdOpenFileAtDest(GString *args[], int nArgs, | void XpdfViewer::cmdOpenFileAtDest(GString *args[], int nArgs, | |||
QInputEvent *event) { | QInputEvent *event) { | |||
open(args[0]->getCString(), 1, args[1]->getCString(), 0, ""); | open(args[0]->getCString(), 1, args[1]->getCString(), 0, ""); | |||
} | } | |||
void XpdfViewer::cmdOpenFileAtDestIn(GString *args[], int nArgs, | void XpdfViewer::cmdOpenFileAtDestIn(GString *args[], int nArgs, | |||
QInputEvent *event) { | QInputEvent *event) { | |||
if (!args[2]->cmp("win")) { | if (!args[2]->cmp("win")) { | |||
skipping to change at line 1573 | skipping to change at line 1710 | |||
openInNewTab(args[0]->getCString(), atoi(args[1]->getCString()), | openInNewTab(args[0]->getCString(), atoi(args[1]->getCString()), | |||
"", 0, "", gTrue); | "", 0, "", gTrue); | |||
} else { | } else { | |||
open(args[0]->getCString(), atoi(args[1]->getCString()), "", 0, ""); | open(args[0]->getCString(), atoi(args[1]->getCString()), "", 0, ""); | |||
} | } | |||
} | } | |||
void XpdfViewer::cmdOpenFileIn(GString *args[], int nArgs, | void XpdfViewer::cmdOpenFileIn(GString *args[], int nArgs, | |||
QInputEvent *event) { | QInputEvent *event) { | |||
if (!args[1]->cmp("win")) { | if (!args[1]->cmp("win")) { | |||
app->openInNewWindow(args[0]->getCString(), 1); | app->openInNewWindow(args[0]->getCString(), -1); | |||
} else if (!args[1]->cmp("tab")) { | } else if (!args[1]->cmp("tab")) { | |||
openInNewTab(args[0]->getCString(), 1, "", 0, "", gTrue); | openInNewTab(args[0]->getCString(), -1, "", 0, "", gTrue); | |||
} else { | } else { | |||
open(args[0]->getCString(), 1, "", 0, ""); | open(args[0]->getCString(), -1, "", 0, ""); | |||
} | } | |||
} | } | |||
void XpdfViewer::cmdOpenIn(GString *args[], int nArgs, QInputEvent *event) { | void XpdfViewer::cmdOpenIn(GString *args[], int nArgs, QInputEvent *event) { | |||
QString startFile, fileName; | QString startFile, fileName; | |||
QDir startDir; | QDir startDir; | |||
if (!(startFile = currentTab->pdf->getFileName()).isEmpty()) { | if (!(startFile = currentTab->pdf->getFileName()).isEmpty()) { | |||
startDir = QDir(startFile); | startDir = QDir(startFile); | |||
startDir.cdUp(); | startDir.cdUp(); | |||
skipping to change at line 1601 | skipping to change at line 1738 | |||
} else { | } else { | |||
startDir = QDir("."); | startDir = QDir("."); | |||
} | } | |||
fileName = QFileDialog::getOpenFileName(this, "Open PDF File", | fileName = QFileDialog::getOpenFileName(this, "Open PDF File", | |||
startDir.canonicalPath(), | startDir.canonicalPath(), | |||
"PDF files (*.pdf)"); | "PDF files (*.pdf)"); | |||
if (fileName.isEmpty()) { | if (fileName.isEmpty()) { | |||
return; | return; | |||
} | } | |||
if (!args[0]->cmp("win")) { | if (!args[0]->cmp("win")) { | |||
app->openInNewWindow(fileName, 1); | app->openInNewWindow(fileName, -1); | |||
} else if (!args[0]->cmp("tab")) { | } else if (!args[0]->cmp("tab")) { | |||
openInNewTab(fileName, 1, "", 0, "", gTrue); | openInNewTab(fileName, -1, "", 0, "", gTrue); | |||
} else { | } else { | |||
open(fileName, 1, "", 0, ""); | open(fileName, -1, "", 0, ""); | |||
} | } | |||
} | } | |||
void XpdfViewer::cmdOpenSidebar(GString *args[], int nArgs, | void XpdfViewer::cmdOpenSidebar(GString *args[], int nArgs, | |||
QInputEvent *event) { | QInputEvent *event) { | |||
QList<int> sizes = sidebarSplitter->sizes(); | QList<int> sizes = sidebarSplitter->sizes(); | |||
if (sizes[0] > 0) { | if (sizes[0] > 0) { | |||
return; | return; | |||
} | } | |||
sizes[0] = sidebarWidth; | sizes[0] = sidebarWidth; | |||
skipping to change at line 1839 | skipping to change at line 1976 | |||
cmd->append(c1); | cmd->append(c1); | |||
break; | break; | |||
} | } | |||
i += 2; | i += 2; | |||
} else { | } else { | |||
cmd->append(c0); | cmd->append(c0); | |||
++i; | ++i; | |||
} | } | |||
} | } | |||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) | ||||
QString cmdStr(cmd->getCString()); | ||||
QStringList tokens = QProcess::splitCommand(cmdStr); | ||||
if (!tokens.isEmpty()) { | ||||
QString program = tokens[0]; | ||||
tokens.removeFirst(); | ||||
QProcess::startDetached(program, tokens); | ||||
} | ||||
#else | ||||
QProcess::startDetached(cmd->getCString()); | QProcess::startDetached(cmd->getCString()); | |||
#endif | ||||
delete cmd; | delete cmd; | |||
} | } | |||
void XpdfViewer::cmdSaveAs(GString *args[], int nArgs, QInputEvent *event) { | void XpdfViewer::cmdSaveAs(GString *args[], int nArgs, QInputEvent *event) { | |||
QString startFile, fileName; | QString startFile, fileName; | |||
QDir startDir; | QDir startDir; | |||
if (!(startFile = currentTab->pdf->getFileName()).isEmpty()) { | if (!(startFile = currentTab->pdf->getFileName()).isEmpty()) { | |||
startDir = QDir(startFile); | startDir = QDir(startFile); | |||
} else { | } else { | |||
skipping to change at line 1867 | skipping to change at line 2014 | |||
} | } | |||
currentTab->pdf->saveAs(fileName); | currentTab->pdf->saveAs(fileName); | |||
} | } | |||
void XpdfViewer::cmdSaveImage(GString *args[], int nArgs, QInputEvent *event) { | void XpdfViewer::cmdSaveImage(GString *args[], int nArgs, QInputEvent *event) { | |||
execSaveImageDialog(); | execSaveImageDialog(); | |||
} | } | |||
void XpdfViewer::cmdSaveTabState(GString *args[], int nArgs, | void XpdfViewer::cmdSaveTabState(GString *args[], int nArgs, | |||
QInputEvent *event) { | QInputEvent *event) { | |||
FILE *f; | GString *path = globalParams->getTabStateFile(); | |||
XpdfWidget *pdf; | FILE *f = openFile(path->getCString(), "wb"); | |||
QString fileName; | if (!f) { | |||
GString *path, *msg; | GString *msg = GString::format("Couldn't write the tab file '{0:t}'", | |||
int i; | path); | |||
path = globalParams->getTabStateFile(); | ||||
if (!(f = openFile(path->getCString(), "wb"))) { | ||||
msg = GString::format("Couldn't write the tab file '{0:t}'", path); | ||||
QMessageBox::warning(NULL, "Xpdf Error", msg->getCString()); | QMessageBox::warning(NULL, "Xpdf Error", msg->getCString()); | |||
delete msg; | delete msg; | |||
delete path; | delete path; | |||
return; | return; | |||
} | } | |||
delete path; | delete path; | |||
for (i = 0; i < tabInfo->getLength(); ++i) { | fprintf(f, "xpdf-tabstate-2\n"); | |||
pdf = ((XpdfTabInfo *)tabInfo->get(i))->pdf; | ||||
fileName = pdf->getFileName(); | for (int i = 0; i < tabInfo->getLength(); ++i) { | |||
XpdfWidget *pdf = ((XpdfTabInfo *)tabInfo->get(i))->pdf; | ||||
QString fileName = pdf->getFileName(); | ||||
if (!fileName.isEmpty()) { | if (!fileName.isEmpty()) { | |||
fprintf(f, "%s\n%d\n", fileName.toUtf8().constData(), pdf->getMidPage()); | fprintf(f, "%s\n", fileName.toUtf8().constData()); | |||
char displayModeChar; | ||||
switch (pdf->getDisplayMode()) { | ||||
case XpdfWidget::pdfDisplaySingle: | ||||
displayModeChar = 's'; | ||||
break; | ||||
case XpdfWidget::pdfDisplayContinuous: | ||||
displayModeChar = 'c'; | ||||
break; | ||||
case XpdfWidget::pdfDisplaySideBySideSingle: | ||||
displayModeChar = 'b'; | ||||
break; | ||||
case XpdfWidget::pdfDisplaySideBySideContinuous: | ||||
displayModeChar = 'B'; | ||||
break; | ||||
case XpdfWidget::pdfDisplayHorizontalContinuous: | ||||
displayModeChar = 'h'; | ||||
break; | ||||
default: | ||||
displayModeChar = 'c'; | ||||
break; | ||||
} | ||||
fprintf(f, "%c %d %g %d %d %d\n", | ||||
displayModeChar, pdf->getMidPage(), pdf->getZoom(), | ||||
pdf->getRotate(), pdf->getScrollX(), pdf->getScrollY()); | ||||
} | } | |||
} | } | |||
fclose(f); | fclose(f); | |||
} | } | |||
void XpdfViewer::cmdScrollDown(GString *args[], int nArgs, | void XpdfViewer::cmdScrollDown(GString *args[], int nArgs, | |||
QInputEvent *event) { | QInputEvent *event) { | |||
int dy = scaleScroll(atoi(args[0]->getCString())); | int dy = scaleScroll(atoi(args[0]->getCString())); | |||
currentTab->pdf->scrollBy(0, dy); | currentTab->pdf->scrollBy(0, dy); | |||
skipping to change at line 1989 | skipping to change at line 2158 | |||
void XpdfViewer::cmdSetSelection(GString *args[], int nArgs, | void XpdfViewer::cmdSetSelection(GString *args[], int nArgs, | |||
QInputEvent *event) { | QInputEvent *event) { | |||
currentTab->pdf->setCurrentSelection(atoi(args[0]->getCString()), | currentTab->pdf->setCurrentSelection(atoi(args[0]->getCString()), | |||
atof(args[1]->getCString()), | atof(args[1]->getCString()), | |||
atof(args[2]->getCString()), | atof(args[2]->getCString()), | |||
atof(args[3]->getCString()), | atof(args[3]->getCString()), | |||
atof(args[4]->getCString())); | atof(args[4]->getCString())); | |||
} | } | |||
void XpdfViewer::cmdShowAttachmentsPane(GString *args[], int nArgs, | ||||
QInputEvent *event) { | ||||
infoComboBox->setCurrentIndex(2); | ||||
} | ||||
void XpdfViewer::cmdShowDocumentInfo(GString *args[], int nArgs, | ||||
QInputEvent *event) { | ||||
if (!currentTab->pdf->hasOpenDocument()) { | ||||
return; | ||||
} | ||||
updateDocumentInfoDialog(currentTab->pdf); | ||||
documentInfoDialog->show(); | ||||
documentInfoDialog->raise(); | ||||
} | ||||
void XpdfViewer::cmdShowKeyBindings(GString *args[], int nArgs, | void XpdfViewer::cmdShowKeyBindings(GString *args[], int nArgs, | |||
QInputEvent *event) { | QInputEvent *event) { | |||
if (!keyBindingsDialog) { | if (!keyBindingsDialog) { | |||
createKeyBindingsDialog(); | createKeyBindingsDialog(); | |||
} | } | |||
keyBindingsDialog->show(); | keyBindingsDialog->show(); | |||
keyBindingsDialog->raise(); | keyBindingsDialog->raise(); | |||
} | } | |||
void XpdfViewer::cmdShowLayersPane(GString *args[], int nArgs, | ||||
QInputEvent *event) { | ||||
infoComboBox->setCurrentIndex(1); | ||||
} | ||||
void XpdfViewer::cmdShowMenuBar(GString *args[], int nArgs, | ||||
QInputEvent *event) { | ||||
mainMenu->show(); | ||||
} | ||||
void XpdfViewer::cmdShowOutlinePane(GString *args[], int nArgs, | ||||
QInputEvent *event) { | ||||
infoComboBox->setCurrentIndex(0); | ||||
} | ||||
void XpdfViewer::cmdShowToolbar(GString *args[], int nArgs, | void XpdfViewer::cmdShowToolbar(GString *args[], int nArgs, | |||
QInputEvent *event) { | QInputEvent *event) { | |||
toolBar->show(); | toolBar->show(); | |||
toggleToolbarMenuItem->setChecked(true); | toggleToolbarMenuItem->setChecked(true); | |||
} | } | |||
void XpdfViewer::cmdShrinkSidebar(GString *args[], int nArgs, | void XpdfViewer::cmdShrinkSidebar(GString *args[], int nArgs, | |||
QInputEvent *event) { | QInputEvent *event) { | |||
QList<int> sizes = sidebarSplitter->sizes(); | QList<int> sizes = sidebarSplitter->sizes(); | |||
if (sizes[0] == 0) { | if (sizes[0] == 0) { | |||
skipping to change at line 2073 | skipping to change at line 2272 | |||
void XpdfViewer::cmdToggleFullScreenMode(GString *args[], int nArgs, | void XpdfViewer::cmdToggleFullScreenMode(GString *args[], int nArgs, | |||
QInputEvent *event) { | QInputEvent *event) { | |||
if (windowState() & Qt::WindowFullScreen) { | if (windowState() & Qt::WindowFullScreen) { | |||
exitFullScreenMode(); | exitFullScreenMode(); | |||
} else { | } else { | |||
enterFullScreenMode(); | enterFullScreenMode(); | |||
} | } | |||
} | } | |||
void XpdfViewer::cmdToggleMenuBar(GString *args[], int nArgs, | ||||
QInputEvent *event) { | ||||
if (mainMenu->isVisible()) { | ||||
cmdHideMenuBar(args, nArgs, event); | ||||
} else { | ||||
cmdShowMenuBar(args, nArgs, event); | ||||
} | ||||
} | ||||
void XpdfViewer::cmdToggleSelectMode(GString *args[], int nArgs, | void XpdfViewer::cmdToggleSelectMode(GString *args[], int nArgs, | |||
QInputEvent *event) { | QInputEvent *event) { | |||
if (currentTab->pdf->isBlockSelectMode()) { | if (currentTab->pdf->isBlockSelectMode()) { | |||
currentTab->pdf->setLinearSelectMode(); | currentTab->pdf->setLinearSelectMode(); | |||
} else { | } else { | |||
currentTab->pdf->setBlockSelectMode(); | currentTab->pdf->setBlockSelectMode(); | |||
} | } | |||
updateSelectModeInfo(); | updateSelectModeInfo(); | |||
} | } | |||
skipping to change at line 2456 | skipping to change at line 2664 | |||
deleteGList(cmds, GString); | deleteGList(cmds, GString); | |||
} | } | |||
} | } | |||
void XpdfViewer::mouseWheel(QWheelEvent *e) { | void XpdfViewer::mouseWheel(QWheelEvent *e) { | |||
GList *cmds; | GList *cmds; | |||
int keyCode, i; | int keyCode, i; | |||
// for historical reasons xpdf uses X11 button numbering for mouse | // for historical reasons xpdf uses X11 button numbering for mouse | |||
// wheel events | // wheel events | |||
if (e->orientation() == Qt::Vertical) { | QPoint delta = e->angleDelta(); | |||
if (e->delta() > 0) { | if (delta.y() > 0) { | |||
keyCode = xpdfKeyCodeMousePress4; | keyCode = xpdfKeyCodeMousePress4; | |||
} else { | } else if (delta.y() < 0) { | |||
keyCode = xpdfKeyCodeMousePress5; | keyCode = xpdfKeyCodeMousePress5; | |||
} | } else if (delta.x() > 0) { | |||
} else { | keyCode = xpdfKeyCodeMousePress6; | |||
if (e->delta() > 0) { | } else if (delta.x() < 0) { | |||
keyCode = xpdfKeyCodeMousePress6; | keyCode = xpdfKeyCodeMousePress7; | |||
} else { | ||||
keyCode = xpdfKeyCodeMousePress7; | ||||
} | ||||
} | } | |||
if ((cmds = globalParams->getKeyBinding(keyCode, | if ((cmds = globalParams->getKeyBinding(keyCode, | |||
getModifiers(e->modifiers()), | getModifiers(e->modifiers()), | |||
getContext(e->modifiers())))) { | getContext(e->modifiers())))) { | |||
for (i = 0; i < cmds->getLength(); ++i) { | for (i = 0; i < cmds->getLength(); ++i) { | |||
execCmd(((GString *)cmds->get(i))->getCString(), e); | execCmd(((GString *)cmds->get(i))->getCString(), e); | |||
} | } | |||
deleteGList(cmds, GString); | deleteGList(cmds, GString); | |||
} | } | |||
} | } | |||
skipping to change at line 2579 | skipping to change at line 2784 | |||
if (e->mimeData()->hasUrls() && | if (e->mimeData()->hasUrls() && | |||
e->mimeData()->urls().front().isLocalFile()) { | e->mimeData()->urls().front().isLocalFile()) { | |||
e->acceptProposedAction(); | e->acceptProposedAction(); | |||
} | } | |||
} | } | |||
void XpdfViewer::dropEvent(QDropEvent *e) { | void XpdfViewer::dropEvent(QDropEvent *e) { | |||
if (e->mimeData()->hasUrls()) { | if (e->mimeData()->hasUrls()) { | |||
QUrl url = e->mimeData()->urls().front(); | QUrl url = e->mimeData()->urls().front(); | |||
if (url.isLocalFile()) { | if (url.isLocalFile()) { | |||
openInNewTab(url.toLocalFile(), 1, "", 0, "", gTrue); | openInNewTab(url.toLocalFile(), -1, "", 0, "", gTrue); | |||
} | } | |||
} | } | |||
} | } | |||
bool XpdfViewer::eventFilter(QObject *watched, QEvent *event) { | bool XpdfViewer::eventFilter(QObject *watched, QEvent *event) { | |||
// if the user clicks in the find edit box, clear the find error | // if the user clicks in the find edit box, clear the find error | |||
// indicator (if any) | // indicator (if any) | |||
if (watched == findEdit && event->type() == QEvent::MouseButtonPress) { | if (watched == findEdit && event->type() == QEvent::MouseButtonPress) { | |||
clearFindError(); | clearFindError(); | |||
} | } | |||
skipping to change at line 2718 | skipping to change at line 2923 | |||
} | } | |||
void XpdfViewer::toggleSidebarMenuAction(bool checked) { | void XpdfViewer::toggleSidebarMenuAction(bool checked) { | |||
execCmd(checked ? "openSidebar" : "closeSidebar", NULL); | execCmd(checked ? "openSidebar" : "closeSidebar", NULL); | |||
} | } | |||
void XpdfViewer::viewPageLabelsMenuAction(bool checked) { | void XpdfViewer::viewPageLabelsMenuAction(bool checked) { | |||
execCmd(checked ? "viewPageLabels" : "viewPageNumbers", NULL); | execCmd(checked ? "viewPageLabels" : "viewPageNumbers", NULL); | |||
} | } | |||
void XpdfViewer::documentInfoMenuAction() { | ||||
execCmd("showDocumentInfo", NULL); | ||||
} | ||||
void XpdfViewer::newTabMenuAction() { | void XpdfViewer::newTabMenuAction() { | |||
execCmd("newTab", NULL); | execCmd("newTab", NULL); | |||
} | } | |||
void XpdfViewer::newWindowMenuAction() { | void XpdfViewer::newWindowMenuAction() { | |||
execCmd("newWindow", NULL); | execCmd("newWindow", NULL); | |||
} | } | |||
void XpdfViewer::closeTabMenuAction() { | void XpdfViewer::closeTabMenuAction() { | |||
execCmd("closeTabOrQuit", NULL); | execCmd("closeTabOrQuit", NULL); | |||
skipping to change at line 2800 | skipping to change at line 3009 | |||
} | } | |||
void XpdfViewer::zoomOutButtonPressed() { | void XpdfViewer::zoomOutButtonPressed() { | |||
execCmd("zoomOut", NULL); | execCmd("zoomOut", NULL); | |||
} | } | |||
void XpdfViewer::zoomInButtonPressed() { | void XpdfViewer::zoomInButtonPressed() { | |||
execCmd("zoomIn", NULL); | execCmd("zoomIn", NULL); | |||
} | } | |||
void XpdfViewer::zoomIndexChanged(const QString &zoomText) { | void XpdfViewer::zoomIndexChanged(int idx) { | |||
QString zoomText = zoomComboBox->itemText(idx); | ||||
QString z; | QString z; | |||
GString *cmd; | ||||
if (zoomText.endsWith("%")) { | if (zoomText.endsWith("%")) { | |||
z = zoomText.left(zoomText.size() - 1); | z = zoomText.left(zoomText.size() - 1); | |||
} else { | } else { | |||
z = zoomText; | z = zoomText; | |||
} | } | |||
cmd = GString::format("zoomPercent({0:s})", z.toLatin1().constData()); | GString *cmd = GString::format("zoomPercent({0:s})", | |||
z.toLatin1().constData()); | ||||
execCmd(cmd->getCString(), NULL); | execCmd(cmd->getCString(), NULL); | |||
delete cmd; | delete cmd; | |||
} | } | |||
void XpdfViewer::zoomEditingFinished() { | void XpdfViewer::zoomEditingFinished() { | |||
QString z; | QString z; | |||
GString *cmd; | GString *cmd; | |||
z = zoomComboBox->currentText(); | z = zoomComboBox->currentText(); | |||
if (z.endsWith("%")) { | if (z.endsWith("%")) { | |||
skipping to change at line 2873 | skipping to change at line 3082 | |||
for (i = 0; i < tabInfo->getLength(); ++i) { | for (i = 0; i < tabInfo->getLength(); ++i) { | |||
tab = (XpdfTabInfo *)tabInfo->get(i); | tab = (XpdfTabInfo *)tabInfo->get(i); | |||
if (tab->listItem == current) { | if (tab->listItem == current) { | |||
gotoTab(i); | gotoTab(i); | |||
return; | return; | |||
} | } | |||
} | } | |||
} | } | |||
void XpdfViewer::tabsReordered(const QModelIndex &srcParent, | ||||
int srcStart, int srcEnd, | ||||
const QModelIndex &destParent, | ||||
int destRow) { | ||||
// these conditions should always be true, but check just in case | ||||
if (srcStart == srcEnd && | ||||
srcStart >= 0 && srcStart < tabInfo->getLength() && | ||||
destRow >= 0 && destRow <= tabInfo->getLength()) { | ||||
XpdfTabInfo *tab = (XpdfTabInfo *)tabInfo->del(srcStart); | ||||
int i = destRow; | ||||
if (i >= srcStart) { | ||||
--i; | ||||
} | ||||
tabInfo->insert(i, tab); | ||||
} | ||||
} | ||||
void XpdfViewer::infoComboBoxChanged(int idx) { | void XpdfViewer::infoComboBoxChanged(int idx) { | |||
updateInfoPane(); | updateInfoPane(); | |||
} | } | |||
void XpdfViewer::outlineItemClicked(const QModelIndex& idx) { | void XpdfViewer::outlineItemClicked(const QModelIndex& idx) { | |||
currentTab->pdf->gotoOutlineTarget((XpdfOutlineHandle)idx.internalPointer()); | currentTab->pdf->gotoOutlineTarget((XpdfOutlineHandle)idx.internalPointer()); | |||
updateModeInfo(); | updateModeInfo(); | |||
} | } | |||
void XpdfViewer::layerItemClicked(const QModelIndex& idx) { | void XpdfViewer::layerItemClicked(const QModelIndex& idx) { | |||
skipping to change at line 2972 | skipping to change at line 3198 | |||
sidebarWidth = 200; | sidebarWidth = 200; | |||
linkTargetBar = new QLabel(this); | linkTargetBar = new QLabel(this); | |||
linkTargetBar->setStyleSheet("padding:2px; background:#00ffff;"); | linkTargetBar->setStyleSheet("padding:2px; background:#00ffff;"); | |||
linkTargetBar->setAttribute(Qt::WA_TransparentForMouseEvents, true); | linkTargetBar->setAttribute(Qt::WA_TransparentForMouseEvents, true); | |||
findErrorTimer = new QTimer(this); | findErrorTimer = new QTimer(this); | |||
findErrorTimer->setSingleShot(true); | findErrorTimer->setSingleShot(true); | |||
connect(findErrorTimer, SIGNAL(timeout()), this, SLOT(clearFindError())); | connect(findErrorTimer, SIGNAL(timeout()), this, SLOT(clearFindError())); | |||
documentInfoDialog = NULL; | ||||
keyBindingsDialog = NULL; | keyBindingsDialog = NULL; | |||
aboutDialog = NULL; | aboutDialog = NULL; | |||
#if XPDFWIDGET_PRINTING | #if XPDFWIDGET_PRINTING | |||
printStatusDialog = NULL; | printStatusDialog = NULL; | |||
#endif | #endif | |||
scaleFactor = 1; | scaleFactor = 1; | |||
tabInfo = new GList(); | tabInfo = new GList(); | |||
addTab(); | addTab(); | |||
skipping to change at line 3044 | skipping to change at line 3271 | |||
//--- selection mode toggle | //--- selection mode toggle | |||
selectModeBtn = addToolBarButton(QIcon(":/selectModeLinear-button"), | selectModeBtn = addToolBarButton(QIcon(":/selectModeLinear-button"), | |||
SLOT(selectModeButtonPressed()), | SLOT(selectModeButtonPressed()), | |||
"toggle selection mode"); | "toggle selection mode"); | |||
addToolBarSeparator(); | addToolBarSeparator(); | |||
//--- page number and page count | //--- page number and page count | |||
// note: the pageNumber widget was created earlier because we need | // note: the pageNumber widget was created earlier because we need | |||
// to look at its font size | // to look at its font size | |||
#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0) | ||||
pageNumber->setFixedWidth( | ||||
pageNumber->fontMetrics().horizontalAdvance("00000") + 6); | ||||
#else | ||||
pageNumber->setFixedWidth(pageNumber->fontMetrics().width("00000") + 6); | pageNumber->setFixedWidth(pageNumber->fontMetrics().width("00000") + 6); | |||
#endif | ||||
pageNumber->setToolTip("current page number"); | pageNumber->setToolTip("current page number"); | |||
toolBar->addWidget(pageNumber); | toolBar->addWidget(pageNumber); | |||
addToolBarSpacing(2); | addToolBarSpacing(2); | |||
toolBar->addWidget(new QLabel("/")); | toolBar->addWidget(new QLabel("/")); | |||
addToolBarSpacing(2); | addToolBarSpacing(2); | |||
connect(pageNumber, SIGNAL(returnPressed()), this, SLOT(pageNumberChanged())); | connect(pageNumber, SIGNAL(returnPressed()), this, SLOT(pageNumberChanged())); | |||
pageCount = new QLabel(""); | pageCount = new QLabel(""); | |||
pageCount->setToolTip("page count"); | pageCount->setToolTip("page count"); | |||
toolBar->addWidget(pageCount); | toolBar->addWidget(pageCount); | |||
addToolBarSpacing(4); | addToolBarSpacing(4); | |||
skipping to change at line 3080 | skipping to change at line 3312 | |||
zoomComboBox = new QComboBox(); | zoomComboBox = new QComboBox(); | |||
zoomComboBox->setToolTip("change zoom level"); | zoomComboBox->setToolTip("change zoom level"); | |||
for (i = 0; i < nZoomComboBoxVals; ++i) { | for (i = 0; i < nZoomComboBoxVals; ++i) { | |||
zoomVal.setNum(zoomComboBoxVals[i]); | zoomVal.setNum(zoomComboBoxVals[i]); | |||
zoomVal.append('%'); | zoomVal.append('%'); | |||
zoomComboBox->addItem(zoomVal); | zoomComboBox->addItem(zoomVal); | |||
} | } | |||
zoomComboBox->setEditable(true); | zoomComboBox->setEditable(true); | |||
zoomComboBox->setInsertPolicy(QComboBox::NoInsert); | zoomComboBox->setInsertPolicy(QComboBox::NoInsert); | |||
zoomComboBox->setValidator(new ZoomValidator(this)); | zoomComboBox->setValidator(new ZoomValidator(this)); | |||
connect(zoomComboBox, SIGNAL(currentIndexChanged(const QString&)), | connect(zoomComboBox, SIGNAL(currentIndexChanged(int)), | |||
this, SLOT(zoomIndexChanged(const QString&))); | this, SLOT(zoomIndexChanged(int))); | |||
// this could use the editingFinished signal, but that's emitted | // this could use the editingFinished signal, but that's emitted | |||
// every time the popup is opened and closed, which causes the zoom | // every time the popup is opened and closed, which causes the zoom | |||
// level to be reset | // level to be reset | |||
connect(zoomComboBox->lineEdit(), SIGNAL(returnPressed()), | connect(zoomComboBox->lineEdit(), SIGNAL(returnPressed()), | |||
this, SLOT(zoomEditingFinished())); | this, SLOT(zoomEditingFinished())); | |||
toolBar->addWidget(zoomComboBox); | toolBar->addWidget(zoomComboBox); | |||
addToolBarSpacing(4); | addToolBarSpacing(4); | |||
fitWidthBtn = addToolBarButton(QIcon(":/fitWidth-button"), | fitWidthBtn = addToolBarButton(QIcon(":/fitWidth-button"), | |||
SLOT(fitWidthButtonPressed()), | SLOT(fitWidthButtonPressed()), | |||
"fit page width to window"); | "fit page width to window"); | |||
fitPageBtn = addToolBarButton(QIcon(":/fitPage-button"), | fitPageBtn = addToolBarButton(QIcon(":/fitPage-button"), | |||
SLOT(fitPageButtonPressed()), | SLOT(fitPageButtonPressed()), | |||
"fit page to window"); | "fit page to window"); | |||
addToolBarSeparator(); | addToolBarSeparator(); | |||
//--- find controls | //--- find controls | |||
addToolBarStretch(); | addToolBarStretch(); | |||
findEdit = new QLineEdit(); | findEdit = new QLineEdit(); | |||
findEdit->setPlaceholderText("find"); | findEdit->setPlaceholderText("find"); | |||
#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0) | ||||
findEdit->setFixedWidth(20 * findEdit->fontMetrics().horizontalAdvance("0")); | ||||
#else | ||||
findEdit->setFixedWidth(20 * findEdit->fontMetrics().width("0")); | findEdit->setFixedWidth(20 * findEdit->fontMetrics().width("0")); | |||
#endif | ||||
findEdit->installEventFilter(this); | findEdit->installEventFilter(this); | |||
toolBar->addWidget(findEdit); | toolBar->addWidget(findEdit); | |||
connect(findEdit, SIGNAL(returnPressed()), this, SLOT(findTextChanged())); | connect(findEdit, SIGNAL(returnPressed()), this, SLOT(findTextChanged())); | |||
connect(findEdit, SIGNAL(cursorPositionChanged(int, int)), | connect(findEdit, SIGNAL(cursorPositionChanged(int, int)), | |||
this, SLOT(clearFindError())); | this, SLOT(clearFindError())); | |||
connect(findEdit, SIGNAL(selectionChanged()), this, SLOT(clearFindError())); | connect(findEdit, SIGNAL(selectionChanged()), this, SLOT(clearFindError())); | |||
connect(findEdit, SIGNAL(textChanged(const QString&)), | connect(findEdit, SIGNAL(textChanged(const QString&)), | |||
this, SLOT(clearFindError())); | this, SLOT(clearFindError())); | |||
addToolBarButton(QIcon(":/findNext-button"), | addToolBarButton(QIcon(":/findNext-button"), | |||
SLOT(findNextButtonPressed()), "find next occurrence"); | SLOT(findNextButtonPressed()), "find next occurrence"); | |||
skipping to change at line 3247 | skipping to change at line 3483 | |||
fullScreenMenuItem->setCheckable(true); | fullScreenMenuItem->setCheckable(true); | |||
viewSubmenu->addSeparator(); | viewSubmenu->addSeparator(); | |||
viewSubmenu->addAction("Rotate clockwise", | viewSubmenu->addAction("Rotate clockwise", | |||
this, SLOT(rotateClockwiseMenuAction())); | this, SLOT(rotateClockwiseMenuAction())); | |||
viewSubmenu->addAction("Rotate counterclockwise", | viewSubmenu->addAction("Rotate counterclockwise", | |||
this, SLOT(rotateCounterclockwiseMenuAction())); | this, SLOT(rotateCounterclockwiseMenuAction())); | |||
viewSubmenu->addSeparator(); | viewSubmenu->addSeparator(); | |||
viewSubmenu->addAction("Zoom to selection", | viewSubmenu->addAction("Zoom to selection", | |||
this, SLOT(zoomToSelectionMenuAction())); | this, SLOT(zoomToSelectionMenuAction())); | |||
QMenu *toolsSubmenu = mainMenu->addMenu("&Tools"); | ||||
toolsSubmenu->addAction("Document info", | ||||
this, SLOT(documentInfoMenuAction())); | ||||
QMenu *windowSubmenu = mainMenu->addMenu("&Window"); | QMenu *windowSubmenu = mainMenu->addMenu("&Window"); | |||
windowSubmenu->addAction("New tab", this, SLOT(newTabMenuAction())); | windowSubmenu->addAction("New tab", this, SLOT(newTabMenuAction())); | |||
windowSubmenu->addAction("New window", this, SLOT(newWindowMenuAction())); | windowSubmenu->addAction("New window", this, SLOT(newWindowMenuAction())); | |||
windowSubmenu->addSeparator(); | windowSubmenu->addSeparator(); | |||
windowSubmenu->addAction("Close tab", this, SLOT(closeTabMenuAction())); | windowSubmenu->addAction("Close tab", this, SLOT(closeTabMenuAction())); | |||
windowSubmenu->addAction("Close window", this, SLOT(closeWindowMenuAction())); | windowSubmenu->addAction("Close window", this, SLOT(closeWindowMenuAction())); | |||
windowSubmenu->addSeparator(); | windowSubmenu->addSeparator(); | |||
windowSubmenu->addAction("Open error window...", | windowSubmenu->addAction("Open error window...", | |||
this, SLOT(openErrorWindowMenuAction())); | this, SLOT(openErrorWindowMenuAction())); | |||
skipping to change at line 3273 | skipping to change at line 3513 | |||
// This can't be named createPopupMenu because there's a QMainWindow | // This can't be named createPopupMenu because there's a QMainWindow | |||
// function of that name. | // function of that name. | |||
void XpdfViewer::createXpdfPopupMenu() { | void XpdfViewer::createXpdfPopupMenu() { | |||
PopupMenuCmd *cmd; | PopupMenuCmd *cmd; | |||
QAction *action; | QAction *action; | |||
int n, i; | int n, i; | |||
popupMenu = new QMenu(this); | popupMenu = new QMenu(this); | |||
popupMenuSignalMapper = new QSignalMapper(this); | popupMenuSignalMapper = new QSignalMapper(this); | |||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) | ||||
connect(popupMenuSignalMapper, SIGNAL(mappedInt(int)), | ||||
this, SLOT(popupMenuAction(int))); | ||||
#else | ||||
connect(popupMenuSignalMapper, SIGNAL(mapped(int)), | connect(popupMenuSignalMapper, SIGNAL(mapped(int)), | |||
this, SLOT(popupMenuAction(int))); | this, SLOT(popupMenuAction(int))); | |||
#endif | ||||
n = globalParams->getNumPopupMenuCmds(); | n = globalParams->getNumPopupMenuCmds(); | |||
if (n == 0) { | if (n == 0) { | |||
popupMenu->addAction("use 'popupMenuCmd' to add items to this menu"); | popupMenu->addAction("use 'popupMenuCmd' to add items to this menu"); | |||
popupMenu->addAction("see the xpdfrc(5) documentation"); | popupMenu->addAction("see the xpdfrc(5) documentation"); | |||
} else { | } else { | |||
for (i = 0; i < n; ++i) { | for (i = 0; i < n; ++i) { | |||
cmd = globalParams->getPopupMenuCmd(i); | cmd = globalParams->getPopupMenuCmd(i); | |||
action = popupMenu->addAction(cmd->label->getCString(), | action = popupMenu->addAction(cmd->label->getCString(), | |||
popupMenuSignalMapper, SLOT(map())); | popupMenuSignalMapper, SLOT(map())); | |||
skipping to change at line 3300 | skipping to change at line 3545 | |||
QWidget *XpdfViewer::createTabPane() { | QWidget *XpdfViewer::createTabPane() { | |||
QWidget *tabPane = new QWidget(); | QWidget *tabPane = new QWidget(); | |||
QVBoxLayout *tabPaneLayout = new QVBoxLayout(); | QVBoxLayout *tabPaneLayout = new QVBoxLayout(); | |||
tabPaneLayout->setContentsMargins(0, 0, 0, 0); | tabPaneLayout->setContentsMargins(0, 0, 0, 0); | |||
tabPaneLayout->setSpacing(0); | tabPaneLayout->setSpacing(0); | |||
tabPane->setLayout(tabPaneLayout); | tabPane->setLayout(tabPaneLayout); | |||
tabList = new QListWidget(); | tabList = new QListWidget(); | |||
tabList->setSelectionMode(QAbstractItemView::SingleSelection); | tabList->setSelectionMode(QAbstractItemView::SingleSelection); | |||
tabList->setDragEnabled(true); | ||||
tabList->setDragDropMode(QAbstractItemView::InternalMove); | ||||
tabList->viewport()->setAcceptDrops(true); | ||||
tabList->setDropIndicatorShown(true); | ||||
connect(tabList, SIGNAL(currentItemChanged(QListWidgetItem*, | connect(tabList, SIGNAL(currentItemChanged(QListWidgetItem*, | |||
QListWidgetItem*)), | QListWidgetItem*)), | |||
this, SLOT(switchTab(QListWidgetItem*, QListWidgetItem*))); | this, SLOT(switchTab(QListWidgetItem*, QListWidgetItem*))); | |||
connect(tabList->model(), SIGNAL(rowsMoved(const QModelIndex&, int, int, | ||||
const QModelIndex, int)), | ||||
this, SLOT(tabsReordered(const QModelIndex&, int, int, | ||||
const QModelIndex&, int))); | ||||
tabPaneLayout->addWidget(tabList); | tabPaneLayout->addWidget(tabList); | |||
QPushButton *newTabBtn = new QPushButton("+ tab"); | QPushButton *newTabBtn = new QPushButton("+ tab"); | |||
connect(newTabBtn, SIGNAL(clicked()), this, SLOT(newTabButtonPressed())); | connect(newTabBtn, SIGNAL(clicked()), this, SLOT(newTabButtonPressed())); | |||
tabPaneLayout->addWidget(newTabBtn); | tabPaneLayout->addWidget(newTabBtn); | |||
return tabPane; | return tabPane; | |||
} | } | |||
QWidget *XpdfViewer::createInfoPane() { | QWidget *XpdfViewer::createInfoPane() { | |||
skipping to change at line 3327 | skipping to change at line 3580 | |||
infoLayout->setSpacing(0); | infoLayout->setSpacing(0); | |||
infoPane->setLayout(infoLayout); | infoPane->setLayout(infoLayout); | |||
// NB: order here must match order in updateInfoPane(). | // NB: order here must match order in updateInfoPane(). | |||
infoComboBox = new QComboBox(); | infoComboBox = new QComboBox(); | |||
infoComboBox->setEditable(false); | infoComboBox->setEditable(false); | |||
infoComboBox->addItem("outline"); | infoComboBox->addItem("outline"); | |||
infoComboBox->addItem("layers"); | infoComboBox->addItem("layers"); | |||
infoComboBox->addItem("attachments"); | infoComboBox->addItem("attachments"); | |||
infoLayout->addWidget(infoComboBox); | infoLayout->addWidget(infoComboBox); | |||
connect(infoComboBox, SIGNAL(activated(int)), | connect(infoComboBox, SIGNAL(currentIndexChanged(int)), | |||
this, SLOT(infoComboBoxChanged(int))); | this, SLOT(infoComboBoxChanged(int))); | |||
infoStack = new QStackedLayout(); | infoStack = new QStackedLayout(); | |||
infoLayout->addLayout(infoStack); | infoLayout->addLayout(infoStack); | |||
return infoPane; | return infoPane; | |||
} | } | |||
void XpdfViewer::updateInfoPane() { | void XpdfViewer::updateInfoPane() { | |||
// NB: order here must match order in createInfoPane(). | // NB: order here must match order in createInfoPane(). | |||
skipping to change at line 3504 | skipping to change at line 3757 | |||
tabInfo->append(currentTab); | tabInfo->append(currentTab); | |||
updateInfoPane(); | updateInfoPane(); | |||
scaleFactor = pdf->getCore()->getScaleFactor(); | scaleFactor = pdf->getCore()->getScaleFactor(); | |||
} | } | |||
void XpdfViewer::closeTab(XpdfTabInfo *tab) { | void XpdfViewer::closeTab(XpdfTabInfo *tab) { | |||
int i; | int i; | |||
app->startUpdatePagesFile(); | ||||
app->updatePagesFile(tab->pdf->getFileName(), tab->pdf->getMidPage()); | ||||
app->finishUpdatePagesFile(); | ||||
for (i = 0; i < tabInfo->getLength(); ++i) { | for (i = 0; i < tabInfo->getLength(); ++i) { | |||
if ((XpdfTabInfo *)tabInfo->get(i) == tab) { | if ((XpdfTabInfo *)tabInfo->get(i) == tab) { | |||
break; | break; | |||
} | } | |||
} | } | |||
if (i == tabInfo->getLength()) { | if (i == tabInfo->getLength()) { | |||
// this shouldn't happen | // this shouldn't happen | |||
return; | return; | |||
} | } | |||
tabInfo->del(i); | tabInfo->del(i); | |||
skipping to change at line 3622 | skipping to change at line 3879 | |||
} | } | |||
} | } | |||
// This is called when: | // This is called when: | |||
// - when the GUI is initially created | // - when the GUI is initially created | |||
// - a document is opened or closed | // - a document is opened or closed | |||
// - a tab switch happens | // - a tab switch happens | |||
// It updates all visible info related to the document. | // It updates all visible info related to the document. | |||
void XpdfViewer::updateDocInfo() { | void XpdfViewer::updateDocInfo() { | |||
//--- window title | //--- window title | |||
QString windowTitle("XpdfReader"); | QString windowTitle; | |||
if (currentTab->pdf->hasOpenDocument()) { | if (currentTab->pdf->hasOpenDocument()) { | |||
windowTitle += ": "; | windowTitle = currentTab->pdf->getFileName(); | |||
windowTitle += currentTab->pdf->getFileName(); | windowTitle += " - XpdfReader"; | |||
} else { | ||||
windowTitle = "XpdfReader"; | ||||
} | } | |||
setWindowTitle(windowTitle); | setWindowTitle(windowTitle); | |||
//--- tab title | //--- tab title | |||
QString tabTitle; | QString tabTitle; | |||
if (currentTab->pdf->hasOpenDocument()) { | if (currentTab->pdf->hasOpenDocument()) { | |||
tabTitle = currentTab->pdf->getFileName(); | tabTitle = currentTab->pdf->getFileName(); | |||
int i = tabTitle.lastIndexOf('/'); | ||||
#ifdef _WIN32 | ||||
int j = tabTitle.lastIndexOf('\\'); | ||||
if (j > i) { | ||||
i = j; | ||||
} | ||||
#endif | ||||
if (i >= 0) { | ||||
tabTitle = tabTitle.mid(i + 1) + " [" + tabTitle.left(i + 1) + "]"; | ||||
} | ||||
} else { | } else { | |||
tabTitle = "empty"; | tabTitle = "(empty)"; | |||
} | } | |||
currentTab->listItem->setText(tabTitle); | currentTab->listItem->setText(tabTitle); | |||
currentTab->listItem->setToolTip(tabTitle); | currentTab->listItem->setToolTip(tabTitle); | |||
//--- page number | //--- page number | |||
updatePageNumberOrLabel(currentTab->pdf->getMidPage()); | updatePageNumberOrLabel(currentTab->pdf->getMidPage()); | |||
//--- page count | //--- page count | |||
QString nPages; | QString nPages; | |||
if (currentTab->pdf->hasOpenDocument()) { | if (currentTab->pdf->hasOpenDocument()) { | |||
skipping to change at line 3719 | skipping to change at line 3988 | |||
int n, i; | int n, i; | |||
n = currentTab->pdf->getNumEmbeddedFiles(); | n = currentTab->pdf->getNumEmbeddedFiles(); | |||
currentTab->attachmentList->setRowCount(n); | currentTab->attachmentList->setRowCount(n); | |||
currentTab->attachmentList->setColumnCount(2); | currentTab->attachmentList->setColumnCount(2); | |||
btnGroup = new QButtonGroup(currentTab->attachmentList); | btnGroup = new QButtonGroup(currentTab->attachmentList); | |||
for (i = 0; i < n; ++i) { | for (i = 0; i < n; ++i) { | |||
saveBtn = new QPushButton("save"); | saveBtn = new QPushButton("save"); | |||
saveBtn->setStyleSheet("padding-left:4px; padding-right:4px;"); | saveBtn->setStyleSheet("padding-left:4px; padding-right:4px;"); | |||
btnGroup->addButton(saveBtn, i); | btnGroup->addButton(saveBtn, i); | |||
btnGroup->setId(saveBtn, i); | ||||
currentTab->attachmentList->setCellWidget(i, 0, saveBtn); | currentTab->attachmentList->setCellWidget(i, 0, saveBtn); | |||
item = new QTableWidgetItem(currentTab->pdf->getEmbeddedFileName(i)); | item = new QTableWidgetItem(currentTab->pdf->getEmbeddedFileName(i)); | |||
currentTab->attachmentList->setItem(i, 1, item); | currentTab->attachmentList->setItem(i, 1, item); | |||
} | } | |||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) | ||||
connect(btnGroup, SIGNAL(idClicked(int)), | ||||
this, SLOT(attachmentSaveClicked(int))); | ||||
#else | ||||
connect(btnGroup, SIGNAL(buttonClicked(int)), | connect(btnGroup, SIGNAL(buttonClicked(int)), | |||
this, SLOT(attachmentSaveClicked(int))); | this, SLOT(attachmentSaveClicked(int))); | |||
#endif | ||||
currentTab->attachmentList->resizeRowsToContents(); | currentTab->attachmentList->resizeRowsToContents(); | |||
currentTab->attachmentList->resizeColumnsToContents(); | currentTab->attachmentList->resizeColumnsToContents(); | |||
} | } | |||
void XpdfViewer::statusIndicatorStart() { | void XpdfViewer::statusIndicatorStart() { | |||
if (indicatorAnimation->state() == QAbstractAnimation::Paused) { | if (indicatorAnimation->state() == QAbstractAnimation::Paused) { | |||
indicatorAnimation->resume(); | indicatorAnimation->resume(); | |||
} | } | |||
} | } | |||
skipping to change at line 3764 | skipping to change at line 4039 | |||
void XpdfViewer::showFindError() { | void XpdfViewer::showFindError() { | |||
findEdit->setStyleSheet("background: #ff8080;"); | findEdit->setStyleSheet("background: #ff8080;"); | |||
findErrorTimer->start(1000); | findErrorTimer->start(1000); | |||
} | } | |||
void XpdfViewer::clearFindError() { | void XpdfViewer::clearFindError() { | |||
findErrorTimer->stop(); | findErrorTimer->stop(); | |||
findEdit->setStyleSheet(""); | findEdit->setStyleSheet(""); | |||
} | } | |||
void XpdfViewer::createDocumentInfoDialog() { | ||||
documentInfoDialog = new QDialog(this); | ||||
documentInfoDialog->setWindowTitle("XpdfReader Document Info"); | ||||
QVBoxLayout *vbox = new QVBoxLayout(); | ||||
documentInfoDialog->setLayout(vbox); | ||||
QTabWidget *tabs = new QTabWidget(); | ||||
vbox->addWidget(tabs); | ||||
documentInfoMetadataTab = new QTextBrowser(); | ||||
documentInfoMetadataTab->setLineWrapMode(QTextEdit::NoWrap); | ||||
tabs->addTab(documentInfoMetadataTab, "Metadata"); | ||||
documentInfoFontsTab = new QTextBrowser(); | ||||
documentInfoFontsTab->setLineWrapMode(QTextEdit::NoWrap); | ||||
tabs->addTab(documentInfoFontsTab, "Fonts"); | ||||
} | ||||
void XpdfViewer::updateDocumentInfoDialog(XpdfWidget *view) { | ||||
if (!view->hasOpenDocument()) { | ||||
return; | ||||
} | ||||
if (!documentInfoDialog) { | ||||
createDocumentInfoDialog(); | ||||
} | ||||
documentInfoDialog->setWindowTitle(view->getFileName() + | ||||
" - XpdfReader Document Info"); | ||||
documentInfoMetadataTab->setHtml(createDocumentInfoMetadataHTML(view)); | ||||
documentInfoFontsTab->setHtml(createDocumentInfoFontsHTML(view)); | ||||
//--- tweak the dialog size | ||||
int w = documentInfoMetadataTab->contentsMargins().left() + | ||||
(int)documentInfoMetadataTab->document()->idealWidth() + | ||||
documentInfoMetadataTab->contentsMargins().right() + | ||||
50; | ||||
int w1 = documentInfoFontsTab->contentsMargins().left() + | ||||
(int)documentInfoFontsTab->document()->idealWidth() + | ||||
documentInfoFontsTab->contentsMargins().right() + | ||||
50; | ||||
if (w1 > w) { | ||||
w = w1; | ||||
} | ||||
int h = 20 * documentInfoMetadataTab->fontMetrics().lineSpacing() + 75; | ||||
documentInfoDialog->resize(w, h); | ||||
} | ||||
static QString parseInfoDate(GString *s) { | ||||
char *p = s->getCString(); | ||||
if (p[0] == 'D' && p[1] == ':') { | ||||
p += 2; | ||||
} | ||||
int year, mon, day, hour, min, sec, n; | ||||
if ((n = sscanf(p, "%4d%2d%2d%2d%2d%2d", | ||||
&year, &mon, &day, &hour, &min, &sec)) < 1) { | ||||
return QString(); | ||||
} | ||||
switch (n) { | ||||
case 1: mon = 1; | ||||
case 2: day = 1; | ||||
case 3: hour = 0; | ||||
case 4: min = 0; | ||||
case 5: sec = 0; | ||||
} | ||||
struct tm tmStruct; | ||||
tmStruct.tm_year = year - 1900; | ||||
tmStruct.tm_mon = mon - 1; | ||||
tmStruct.tm_mday = day; | ||||
tmStruct.tm_hour = hour; | ||||
tmStruct.tm_min = min; | ||||
tmStruct.tm_sec = sec; | ||||
tmStruct.tm_wday = -1; | ||||
tmStruct.tm_yday = -1; | ||||
tmStruct.tm_isdst = -1; | ||||
// compute the tm_wday and tm_yday fields | ||||
char buf[256]; | ||||
if (!(mktime(&tmStruct) != (time_t)-1 && | ||||
strftime(buf, sizeof(buf), "%c", &tmStruct))) { | ||||
return QString(); | ||||
} | ||||
return QString(buf); | ||||
} | ||||
static QString parseXMPDate(GString *s) { | ||||
int year, mon, day, hour, min, sec, tz; | ||||
char buf[256]; | ||||
char *p = s->getCString(); | ||||
if (isdigit(p[0]) && isdigit(p[1]) && isdigit(p[2]) && isdigit(p[3])) { | ||||
buf[0] = p[0]; | ||||
buf[1] = p[1]; | ||||
buf[2] = p[2]; | ||||
buf[3] = p[3]; | ||||
buf[4] = '\0'; | ||||
year = atoi(buf); | ||||
p += 4; | ||||
} else { | ||||
return QString(); | ||||
} | ||||
mon = day = 1; | ||||
hour = min = sec = 0; | ||||
tz = 2000; | ||||
if (p[0] == '-' && isdigit(p[1]) && isdigit(p[2])) { | ||||
buf[0] = p[1]; | ||||
buf[1] = p[2]; | ||||
buf[2] = '\0'; | ||||
mon = atoi(buf); | ||||
p += 3; | ||||
if (p[0] == '-' && isdigit(p[1]) && isdigit(p[2])) { | ||||
buf[0] = p[1]; | ||||
buf[1] = p[2]; | ||||
buf[2] = '\0'; | ||||
day = atoi(buf); | ||||
p += 3; | ||||
if (p[0] == 'T' && isdigit(p[1]) && isdigit(p[2]) && | ||||
p[3] == ':' && isdigit(p[4]) && isdigit(p[5])) { | ||||
buf[0] = p[1]; | ||||
buf[1] = p[2]; | ||||
buf[2] = '\0'; | ||||
hour = atoi(buf); | ||||
buf[0] = p[4]; | ||||
buf[1] = p[5]; | ||||
buf[2] = '\0'; | ||||
min = atoi(buf); | ||||
p += 6; | ||||
if (p[0] == ':' && isdigit(p[1]) && isdigit(p[2])) { | ||||
buf[0] = p[1]; | ||||
buf[1] = p[2]; | ||||
buf[2] = '\0'; | ||||
sec = atoi(buf); | ||||
if (p[0] == '.' && isdigit(p[1])) { | ||||
p += 2; | ||||
} | ||||
} | ||||
if ((p[0] == '+' || p[0] == '-') && | ||||
isdigit(p[1]) && isdigit(p[2]) && p[3] == ':' && | ||||
isdigit(p[4]) && isdigit(p[5])) { | ||||
buf[0] = p[1]; | ||||
buf[1] = p[2]; | ||||
buf[2] = '\0'; | ||||
tz = atoi(buf); | ||||
buf[0] = p[4]; | ||||
buf[1] = p[5]; | ||||
buf[2] = '\0'; | ||||
tz = tz * 60 + atoi(buf); | ||||
tz = tz * 60; | ||||
if (p[0] == '-') { | ||||
tz = -tz; | ||||
} | ||||
} | ||||
} | ||||
} | ||||
} | ||||
struct tm tmStruct; | ||||
tmStruct.tm_year = year - 1900; | ||||
tmStruct.tm_mon = mon - 1; | ||||
tmStruct.tm_mday = day; | ||||
tmStruct.tm_hour = hour; | ||||
tmStruct.tm_min = min; | ||||
tmStruct.tm_sec = sec; | ||||
tmStruct.tm_wday = -1; | ||||
tmStruct.tm_yday = -1; | ||||
tmStruct.tm_isdst = -1; | ||||
// compute the tm_wday and tm_yday fields | ||||
//~ this ignores the timezone | ||||
if (!(mktime(&tmStruct) != (time_t)-1 && | ||||
strftime(buf, sizeof(buf), "%c", &tmStruct))) { | ||||
return QString(); | ||||
} | ||||
return QString(buf); | ||||
} | ||||
static QString createInfoString(Object *infoDict, const char *infoKey, | ||||
ZxDoc *xmp, const char *xmpKey1, | ||||
const char *xmpKey2, GBool parseDate) { | ||||
//-- check the XMP metadata | ||||
if (xmp) { | ||||
ZxElement *rdf = xmp->getRoot(); | ||||
if (rdf->isElement("x:xmpmeta")) { | ||||
rdf = rdf->findFirstChildElement("rdf:RDF"); | ||||
} | ||||
if (rdf && rdf->isElement("rdf:RDF")) { | ||||
for (ZxNode *node = rdf->getFirstChild(); | ||||
node; | ||||
node = node->getNextChild()) { | ||||
if (node->isElement("rdf:Description")) { | ||||
ZxElement *elem; | ||||
if ((elem = node->findFirstChildElement(xmpKey1)) || | ||||
(xmpKey2 && (elem = node->findFirstChildElement(xmpKey2)))) { | ||||
ZxElement *child; | ||||
ZxNode *node2; | ||||
if ((child = elem->findFirstChildElement("rdf:Alt")) || | ||||
(child = elem->findFirstChildElement("rdf:Seq"))) { | ||||
if ((node2 = child->findFirstChildElement("rdf:li"))) { | ||||
node2 = node2->getFirstChild(); | ||||
} | ||||
} else { | ||||
node2 = elem->getFirstChild(); | ||||
} | ||||
if (node2 && node2->isCharData()) { | ||||
QString value; | ||||
if (parseDate) { | ||||
value = parseXMPDate(((ZxCharData *)node2)->getData()); | ||||
} | ||||
if (value.isEmpty()) { | ||||
value = QString::fromUtf8( | ||||
((ZxCharData *)node2)->getData()->getCString()); | ||||
} | ||||
return QString("<tr><td>") + infoKey + ": </td><td>" | ||||
+ value + "</td></tr>\n"; | ||||
} | ||||
} | ||||
} | ||||
} | ||||
} | ||||
} | ||||
//-- check the info dictionary | ||||
if (infoDict->isDict()) { | ||||
Object obj; | ||||
if (infoDict->dictLookup(infoKey, &obj)->isString()) { | ||||
QString value; | ||||
if (parseDate) { | ||||
value = parseInfoDate(obj.getString()); | ||||
} | ||||
if (value.isEmpty()) { | ||||
TextString *ts = new TextString(obj.getString()); | ||||
GString *utf8 = ts->toUTF8(); | ||||
value = QString::fromUtf8(utf8->getCString()); | ||||
delete utf8; | ||||
delete ts; | ||||
} | ||||
obj.free(); | ||||
return QString("<tr><td>") + infoKey + ": </td><td>" | ||||
+ value + "</td></tr>\n"; | ||||
} | ||||
obj.free(); | ||||
} | ||||
return QString(); | ||||
} | ||||
QString XpdfViewer::createDocumentInfoMetadataHTML(XpdfWidget *view) { | ||||
PDFDoc *doc = view->getCore()->getDoc(); | ||||
QString html("<table>\n"); | ||||
// doc info | ||||
Object info; | ||||
doc->getDocInfo(&info); | ||||
GString *metadata; | ||||
ZxDoc *xmp; | ||||
if ((metadata = doc->readMetadata())) { | ||||
xmp = ZxDoc::loadMem(metadata->getCString(), metadata->getLength()); | ||||
} else { | ||||
xmp = NULL; | ||||
} | ||||
html += createInfoString(&info, "Title", xmp, "dc:title", NULL, | ||||
gFalse); | ||||
html += createInfoString(&info, "Subject", xmp, "dc:description", NULL, | ||||
gFalse); | ||||
html += createInfoString(&info, "Keywords", xmp, "pdf:Keywords", NULL, | ||||
gFalse); | ||||
html += createInfoString(&info, "Author", xmp, "dc:creator", NULL, | ||||
gFalse); | ||||
html += createInfoString(&info, "Creator", xmp, "xmp:CreatorTool", NULL, | ||||
gFalse); | ||||
html += createInfoString(&info, "Producer", xmp, "pdf:Producer", NULL, | ||||
gFalse); | ||||
html += createInfoString(&info, "CreationDate", xmp, "xap:CreateDate", "xmp:C | ||||
reateDate", gTrue); | ||||
html += createInfoString(&info, "ModDate", xmp, "xap:ModifyDate", "xmp:M | ||||
odifyDate", gTrue); | ||||
if (xmp) { | ||||
delete xmp; | ||||
} | ||||
if (metadata) { | ||||
delete metadata; | ||||
} | ||||
info.free(); | ||||
// tagging info | ||||
if (doc->getStructTreeRoot()->isDict()) { | ||||
html += "<tr><td>Tagged: </td><td>yes</td></tr>\n"; | ||||
} else { | ||||
html += "<tr><td>Tagged: </td><td>no</td></tr>\n"; | ||||
} | ||||
// form info | ||||
Object *acroForm = doc->getCatalog()->getAcroForm(); | ||||
if (acroForm->isDict()) { | ||||
Object xfa; | ||||
acroForm->dictLookup("XFA", &xfa); | ||||
if (xfa.isStream() || xfa.isArray()) { | ||||
if (doc->getCatalog()->getNeedsRendering()) { | ||||
html += "<tr><td>Form: </td><td>dynamic XFA</td></tr>\n"; | ||||
} else { | ||||
html += "<tr><td>Form: </td><td>static XFA</td></tr>\n"; | ||||
} | ||||
} else { | ||||
html += "<tr><td>Form: </td><td>AcroForm</td></tr>\n"; | ||||
} | ||||
xfa.free(); | ||||
} else { | ||||
html += "<tr><td>Form: </td><td>none</td></tr>\n"; | ||||
} | ||||
// page count | ||||
html += QString("<tr><td>Pages: </td><td>%1</td></tr>\n") | ||||
.arg(doc->getNumPages()); | ||||
// encryption info | ||||
if (doc->isEncrypted()) { | ||||
int permFlags, keyLength, encVersion; | ||||
GBool ownerPasswordOk; | ||||
CryptAlgorithm encAlgorithm; | ||||
doc->getXRef()->getEncryption(&permFlags, &ownerPasswordOk, &keyLength, | ||||
&encVersion, &encAlgorithm); | ||||
html += QString("<tr><td>Encrypted: </td><td>%1 %2-bit</td></tr>\n") | ||||
.arg(encAlgorithm == cryptRC4 ? "RC4" : "AES") | ||||
.arg(keyLength * 8); | ||||
html += QString("<tr><td>Permissions: </td><td>print:%1 copy:%2 change: | ||||
%3 addNotes:%4</td></tr>\n") | ||||
.arg(doc->okToPrint(gTrue) ? "yes" : "no") | ||||
.arg(doc->okToCopy(gTrue) ? "yes" : "no") | ||||
.arg(doc->okToChange(gTrue) ? "yes" : "no") | ||||
.arg(doc->okToAddNotes(gTrue) ? "yes" : "no"); | ||||
} else { | ||||
html += QString("<tr><td>Encrypted: </td><td>no</td></tr>\n"); | ||||
} | ||||
// page size | ||||
html += QString("<tr><td>Page size: </td><td>%1 x %2 pts (rotated %3 degr | ||||
ees)</td></tr>\n") | ||||
.arg(doc->getPageCropWidth(1), 0, 'g') | ||||
.arg(doc->getPageCropHeight(1), 0, 'g') | ||||
.arg(doc->getPageRotate(1)); | ||||
// linearization info | ||||
html += QString("<tr><td>Optimized: </td><td>%1</td></tr>\n") | ||||
.arg(doc->isLinearized() ? "yes" : "no"); | ||||
// PDF version | ||||
html += QString("<tr><td>PDF version: </td><td>%1</td></tr>\n") | ||||
.arg(doc->getPDFVersion(), 0, 'f', 1); | ||||
html += "</table>\n"; | ||||
return html; | ||||
} | ||||
static GBool scanFontsCheckObject(Object *in, Object *out, | ||||
PDFDoc *doc, char *seenObjs) { | ||||
if (!in->isRef()) { | ||||
in->copy(out); | ||||
return gTrue; | ||||
} | ||||
int objNum = in->getRefNum(); | ||||
if (objNum < 0 || objNum >= doc->getXRef()->getNumObjects()) { | ||||
out->initNull(); | ||||
return gTrue; | ||||
} | ||||
if (seenObjs[objNum]) { | ||||
out->initNull(); | ||||
return gFalse; | ||||
} | ||||
seenObjs[objNum] = (char)1; | ||||
in->fetch(doc->getXRef(), out); | ||||
return gTrue; | ||||
} | ||||
static QString scanFont(Dict *fontDict, PDFDoc *doc) { | ||||
Ref ref; | ||||
ref.num = ref.gen = 0; | ||||
GfxFont *font = GfxFont::makeFont(doc->getXRef(), "F0", ref, fontDict); | ||||
if (!font) { | ||||
return QString(); | ||||
} | ||||
// font name | ||||
GString *name = font->getName(); | ||||
// font type | ||||
const char *type; | ||||
switch (font->getType()) { | ||||
case fontUnknownType: | ||||
default: type = "unknown"; break; | ||||
case fontType1: type = "Type 1"; break; | ||||
case fontType1C: type = "Type 1C"; break; | ||||
case fontType1COT: type = "Type 1C (OT)"; break; | ||||
case fontType3: type = "Type 3"; break; | ||||
case fontTrueType: type = "TrueType"; break; | ||||
case fontTrueTypeOT: type = "TrueType (OT)"; break; | ||||
case fontCIDType0: type = "CID Type 0"; break; | ||||
case fontCIDType0C: type = "CID Type 0C"; break; | ||||
case fontCIDType0COT: type = "CID Type 0C (OT)"; break; | ||||
case fontCIDType2: type = "CID TrueType"; break; | ||||
case fontCIDType2OT: type = "CID TrueType (OT)"; break; | ||||
} | ||||
// check for an embedded font | ||||
GBool emb; | ||||
if (font->getType() == fontType3) { | ||||
emb = gTrue; | ||||
} else { | ||||
Ref embRef; | ||||
emb = font->getEmbeddedFontID(&embRef); | ||||
} | ||||
// problematic for text extraction | ||||
GBool prob = font->problematicForUnicode(); | ||||
QString html = QString("<tr><td>%1 </td><td>%2 </td><td align=\"cent | ||||
er\">%3</td><td align=\"center\">%4</td></tr>\n") | ||||
.arg(name ? name->getCString() : "[none]") | ||||
.arg(type) | ||||
.arg(emb ? "yes" : "no") | ||||
.arg(prob ? "X" : ""); | ||||
delete font; | ||||
return html; | ||||
} | ||||
static QString scanFonts(Dict *resDict, PDFDoc *doc, char *seenObjs); | ||||
static QString scanFonts(Object *obj, PDFDoc *doc, char *seenObjs) { | ||||
QString html; | ||||
Object obj2; | ||||
if (scanFontsCheckObject(obj, &obj2, doc, seenObjs) && obj2.isDict()) { | ||||
html += scanFonts(obj2.getDict(), doc, seenObjs); | ||||
} | ||||
obj2.free(); | ||||
return html; | ||||
} | ||||
static QString scanFonts(Dict *resDict, PDFDoc *doc, char *seenObjs) { | ||||
QString html; | ||||
// scan the fonts in this resource dictionary | ||||
Object fontDict1, fontDict2; | ||||
resDict->lookupNF("Font", &fontDict1); | ||||
if (scanFontsCheckObject(&fontDict1, &fontDict2, doc, seenObjs) && | ||||
fontDict2.isDict()) { | ||||
for (int i = 0; i < fontDict2.dictGetLength(); ++i) { | ||||
Object font1, font2; | ||||
fontDict2.dictGetValNF(i, &font1); | ||||
if (scanFontsCheckObject(&font1, &font2, doc, seenObjs) && | ||||
font2.isDict()) { | ||||
html += scanFont(font2.getDict(), doc); | ||||
} | ||||
font2.free(); | ||||
font1.free(); | ||||
} | ||||
} | ||||
fontDict2.free(); | ||||
fontDict1.free(); | ||||
// recursively scan any resource dictionaries in XObjects in this | ||||
// resource dictionary | ||||
Object xObjDict1, xObjDict2; | ||||
resDict->lookupNF("XObject", &xObjDict1); | ||||
if (scanFontsCheckObject(&xObjDict1, &xObjDict2, doc, seenObjs) && | ||||
xObjDict2.isDict()) { | ||||
for (int i = 0; i < xObjDict2.dictGetLength(); ++i) { | ||||
Object xObj1, xObj2; | ||||
xObjDict2.dictGetValNF(i, &xObj1); | ||||
if (scanFontsCheckObject(&xObj1, &xObj2, doc, seenObjs) && | ||||
xObj2.isStream()) { | ||||
Object resObj; | ||||
xObj2.streamGetDict()->lookupNF("Resources", &resObj); | ||||
html += scanFonts(&resObj, doc, seenObjs); | ||||
resObj.free(); | ||||
} | ||||
xObj2.free(); | ||||
xObj1.free(); | ||||
} | ||||
} | ||||
xObjDict2.free(); | ||||
xObjDict1.free(); | ||||
// recursively scan any resource dictionaries in Patterns in this | ||||
// resource dictionary | ||||
Object patternDict1, patternDict2; | ||||
resDict->lookupNF("Pattern", &patternDict1); | ||||
if (scanFontsCheckObject(&patternDict1, &patternDict2, doc, seenObjs) && | ||||
patternDict2.isDict()) { | ||||
for (int i = 0; i < patternDict2.dictGetLength(); ++i) { | ||||
Object pattern1, pattern2; | ||||
patternDict2.dictGetValNF(i, &pattern1); | ||||
if (scanFontsCheckObject(&pattern1, &pattern2, doc, seenObjs) && | ||||
pattern2.isStream()) { | ||||
Object resObj; | ||||
pattern2.streamGetDict()->lookupNF("Resources", &resObj); | ||||
html += scanFonts(&resObj, doc, seenObjs); | ||||
resObj.free(); | ||||
} | ||||
pattern2.free(); | ||||
pattern1.free(); | ||||
} | ||||
} | ||||
patternDict2.free(); | ||||
patternDict1.free(); | ||||
// recursively scan any resource dictionaries in ExtGStates in this | ||||
// resource dictionary | ||||
Object gsDict1, gsDict2; | ||||
resDict->lookupNF("ExtGState", &gsDict1); | ||||
if (scanFontsCheckObject(&gsDict1, &gsDict2, doc, seenObjs) && | ||||
gsDict2.isDict()) { | ||||
for (int i = 0; i < gsDict2.dictGetLength(); ++i) { | ||||
Object gs1, gs2; | ||||
gsDict2.dictGetValNF(i, &gs1); | ||||
if (scanFontsCheckObject(&gs1, &gs2, doc, seenObjs) && | ||||
gs2.isDict()) { | ||||
Object smask1, smask2; | ||||
gs2.dictLookupNF("SMask", &smask1); | ||||
if (scanFontsCheckObject(&smask1, &smask2, doc, seenObjs) && | ||||
smask2.isDict()) { | ||||
Object smaskGroup1, smaskGroup2; | ||||
smask2.dictLookupNF("G", &smaskGroup1); | ||||
if (scanFontsCheckObject(&smaskGroup1, &smaskGroup2, doc, seenObjs) && | ||||
smaskGroup2.isStream()) { | ||||
Object resObj; | ||||
smaskGroup2.streamGetDict()->lookupNF("Resources", &resObj); | ||||
html += scanFonts(&resObj, doc, seenObjs); | ||||
resObj.free(); | ||||
} | ||||
smaskGroup2.free(); | ||||
smaskGroup1.free(); | ||||
} | ||||
smask2.free(); | ||||
smask1.free(); | ||||
} | ||||
gs2.free(); | ||||
gs1.free(); | ||||
} | ||||
} | ||||
gsDict2.free(); | ||||
gsDict1.free(); | ||||
return html; | ||||
} | ||||
QString XpdfViewer::createDocumentInfoFontsHTML(XpdfWidget *view) { | ||||
PDFDoc *doc = view->getCore()->getDoc(); | ||||
QString html("<table>\n"); | ||||
html += "<tr bgcolor=\"#aaffaa\"><th> name </th><th> type | ||||
</th><th> embedded </th><th> problematic </th></tr>\n"; | ||||
int numObjects = doc->getXRef()->getNumObjects(); | ||||
char *seenObjs = (char *)gmalloc(numObjects); | ||||
memset(seenObjs, 0, numObjects); | ||||
for (int pg = 1; pg <= doc->getNumPages(); ++pg) { | ||||
Page *page = doc->getCatalog()->getPage(pg); | ||||
Dict *resDict = page->getResourceDict(); | ||||
if (resDict) { | ||||
html += scanFonts(resDict, doc, seenObjs); | ||||
} | ||||
Object obj1, obj2; | ||||
Annots *annots = new Annots(doc, page->getAnnots(&obj1)); | ||||
obj1.free(); | ||||
for (int i = 0; i < annots->getNumAnnots(); ++i) { | ||||
if (annots->getAnnot(i)->getAppearance(&obj1)->isStream()) { | ||||
obj1.streamGetDict()->lookupNF("Resources", &obj2); | ||||
html += scanFonts(&obj2, doc, seenObjs); | ||||
obj2.free(); | ||||
} | ||||
obj1.free(); | ||||
} | ||||
delete annots; | ||||
} | ||||
AcroForm *form = doc->getCatalog()->getForm(); | ||||
if (form) { | ||||
Object obj1, obj2; | ||||
for (int i = 0; i < form->getNumFields(); ++i) { | ||||
form->getField(i)->getResources(&obj1); | ||||
if (obj1.isArray()) { | ||||
for (int j = 0; j < obj1.arrayGetLength(); ++j) { | ||||
obj1.arrayGetNF(j, &obj2); | ||||
html += scanFonts(&obj2, doc, seenObjs); | ||||
obj2.free(); | ||||
} | ||||
} else if (obj1.isDict()) { | ||||
html += scanFonts(obj1.getDict(), doc, seenObjs); | ||||
} | ||||
obj1.free(); | ||||
} | ||||
} | ||||
gfree(seenObjs); | ||||
html += "</table>\n"; | ||||
return html; | ||||
} | ||||
void XpdfViewer::createKeyBindingsDialog() { | void XpdfViewer::createKeyBindingsDialog() { | |||
keyBindingsDialog = new QDialog(this); | keyBindingsDialog = new QDialog(this); | |||
keyBindingsDialog->setWindowTitle("XpdfReader Key Bindings"); | keyBindingsDialog->setWindowTitle("XpdfReader Key Bindings"); | |||
QVBoxLayout *vbox = new QVBoxLayout(); | QVBoxLayout *vbox = new QVBoxLayout(); | |||
keyBindingsDialog->setLayout(vbox); | keyBindingsDialog->setLayout(vbox); | |||
QString html = createKeyBindingsHTML(); | QString html = createKeyBindingsHTML(); | |||
QTextBrowser *text = new QTextBrowser(); | QTextBrowser *text = new QTextBrowser(); | |||
skipping to change at line 3979 | skipping to change at line 4841 | |||
QButtonGroup *regionBtnGroup = new QButtonGroup(dialog); | QButtonGroup *regionBtnGroup = new QButtonGroup(dialog); | |||
QRadioButton *pageBtn = new QRadioButton("Page:"); | QRadioButton *pageBtn = new QRadioButton("Page:"); | |||
regionBtnGroup->addButton(pageBtn); | regionBtnGroup->addButton(pageBtn); | |||
regionBox->addWidget(pageBtn); | regionBox->addWidget(pageBtn); | |||
pageBtn->setChecked(true); | pageBtn->setChecked(true); | |||
QLineEdit *pageEdit = new QLineEdit(); | QLineEdit *pageEdit = new QLineEdit(); | |||
regionBox->addWidget(pageEdit); | regionBox->addWidget(pageEdit); | |||
#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0) | ||||
pageEdit->setFixedWidth(8 * pageEdit->fontMetrics().horizontalAdvance("0")); | ||||
#else | ||||
pageEdit->setFixedWidth(8 * pageEdit->fontMetrics().width("0")); | pageEdit->setFixedWidth(8 * pageEdit->fontMetrics().width("0")); | |||
#endif | ||||
int pg = currentTab->pdf->getMidPage(); | int pg = currentTab->pdf->getMidPage(); | |||
pageEdit->setText(QString().setNum(pg)); | pageEdit->setText(QString().setNum(pg)); | |||
connect(pageEdit, SIGNAL(textChanged(const QString&)), | connect(pageEdit, SIGNAL(textChanged(const QString&)), | |||
pageBtn, SLOT(click())); | pageBtn, SLOT(click())); | |||
connect(pageEdit, SIGNAL(cursorPositionChanged(int, int)), | connect(pageEdit, SIGNAL(cursorPositionChanged(int, int)), | |||
pageBtn, SLOT(click())); | pageBtn, SLOT(click())); | |||
connect(pageEdit, SIGNAL(selectionChanged()), pageBtn, SLOT(click())); | connect(pageEdit, SIGNAL(selectionChanged()), pageBtn, SLOT(click())); | |||
regionBox->addSpacing(20); | regionBox->addSpacing(20); | |||
skipping to change at line 4002 | skipping to change at line 4868 | |||
regionBox->addWidget(selectionBtn); | regionBox->addWidget(selectionBtn); | |||
selectionBtn->setEnabled(currentTab->pdf->hasSelection()); | selectionBtn->setEnabled(currentTab->pdf->hasSelection()); | |||
grid->addWidget(new QLabel("Resolution:"), 2, 0); | grid->addWidget(new QLabel("Resolution:"), 2, 0); | |||
QHBoxLayout *resolutionBox = new QHBoxLayout(); | QHBoxLayout *resolutionBox = new QHBoxLayout(); | |||
grid->addLayout(resolutionBox, 2, 1); | grid->addLayout(resolutionBox, 2, 1); | |||
QLineEdit *resolutionEdit = new QLineEdit(); | QLineEdit *resolutionEdit = new QLineEdit(); | |||
resolutionBox->addWidget(resolutionEdit); | resolutionBox->addWidget(resolutionEdit); | |||
#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0) | ||||
resolutionEdit->setFixedWidth( | ||||
8 * pageEdit->fontMetrics().horizontalAdvance("0")); | ||||
#else | ||||
resolutionEdit->setFixedWidth(8 * pageEdit->fontMetrics().width("0")); | resolutionEdit->setFixedWidth(8 * pageEdit->fontMetrics().width("0")); | |||
#endif | ||||
int r = (int)floor(currentTab->pdf->getZoomPercent(pg) * 0.72 + 0.5); | int r = (int)floor(currentTab->pdf->getZoomPercent(pg) * 0.72 + 0.5); | |||
resolutionEdit->setText(QString().setNum(r)); | resolutionEdit->setText(QString().setNum(r)); | |||
resolutionBox->addWidget(new QLabel("dpi")); | resolutionBox->addWidget(new QLabel("dpi")); | |||
grid->addWidget(new QLabel("Format:"), 3, 0); | grid->addWidget(new QLabel("Format:"), 3, 0); | |||
QHBoxLayout *formatBox = new QHBoxLayout(); | QHBoxLayout *formatBox = new QHBoxLayout(); | |||
grid->addLayout(formatBox, 3, 1); | grid->addLayout(formatBox, 3, 1); | |||
End of changes. 89 change blocks. | ||||
69 lines changed or deleted | 956 lines changed or added |