1 //======================================================================== 2 // 3 // XpdfViewer.h 4 // 5 // Copyright 2015 Glyph & Cog, LLC 6 // 7 //======================================================================== 8 9 #ifndef XPDFVIEWER_H 10 #define XPDFVIEWER_H 11 12 #include <aconf.h> 13 14 #include <QDialog> 15 #include <QIcon> 16 #include <QLocalServer> 17 #include <QMainWindow> 18 #include <QToolButton> 19 #include "gtypes.h" 20 #include "Error.h" 21 #include "XpdfWidget.h" 22 23 class GString; 24 class GList; 25 class PropertyListAnimation; 26 class QComboBox; 27 class QDialog; 28 class QHBoxLayout; 29 class QInputEvent; 30 class QLabel; 31 class QLineEdit; 32 class QListWidget; 33 class QListWidgetItem; 34 class QMenu; 35 class QModelIndex; 36 class QProgressDialog; 37 class QSignalMapper; 38 class QSplitter; 39 class QStackedLayout; 40 class QStackedWidget; 41 class QTimer; 42 class QToolBar; 43 class QToolButton; 44 class XpdfApp; 45 class XpdfMenuButton; 46 class XpdfTabInfo; 47 class XpdfViewer; 48 49 //------------------------------------------------------------------------ 50 51 struct XpdfViewerCmd { 52 const char *name; 53 int nArgs; 54 GBool requiresDoc; 55 GBool requiresEvent; 56 void (XpdfViewer::*func)(GString *args[], int nArgs, QInputEvent *event); 57 }; 58 59 //------------------------------------------------------------------------ 60 // XpdfMenuButton 61 //------------------------------------------------------------------------ 62 63 class XpdfMenuButton: public QToolButton { 64 Q_OBJECT 65 66 public: 67 68 XpdfMenuButton(QMenu *menuA); 69 70 private slots: 71 72 void btnPressed(); 73 74 private: 75 76 QMenu *menu; 77 }; 78 79 //------------------------------------------------------------------------ 80 // XpdfErrorWindow 81 //------------------------------------------------------------------------ 82 83 class XpdfErrorWindow: public QWidget { 84 Q_OBJECT 85 86 public: 87 88 XpdfErrorWindow(XpdfViewer *viewerA, int errorEventTypeA); 89 virtual ~XpdfErrorWindow(); 90 virtual QSize sizeHint() const; 91 virtual void closeEvent(QCloseEvent *event); 92 virtual void keyPressEvent(QKeyEvent *event); 93 virtual void customEvent(QEvent *event); 94 95 private slots: 96 97 void clearBtnPressed(); 98 99 private: 100 101 static void errorCbk(void *data, ErrorCategory category, 102 int pos, char *msg); 103 static void dummyErrorCbk(void *data, ErrorCategory category, 104 int pos, char *msg); 105 106 XpdfViewer *viewer; 107 int errorEventType; 108 QListWidget *list; 109 QSize lastSize; 110 }; 111 112 //------------------------------------------------------------------------ 113 // XpdfViewer 114 //------------------------------------------------------------------------ 115 116 class XpdfViewer: public QMainWindow { 117 Q_OBJECT 118 119 public: 120 121 XpdfViewer(XpdfApp *appA, GBool fullScreen); 122 123 static XpdfViewer *create(XpdfApp *app, QString fileName, int page, 124 QString destName, int rot, QString password, 125 GBool fullScreen); 126 127 virtual ~XpdfViewer(); 128 129 virtual QSize sizeHint() const; 130 131 void tweakSize(); 132 133 // Open a file in the current tab. Returns a boolean indicating 134 // success. 135 GBool open(QString fileName, int page, QString destName, int rot, 136 QString password); 137 138 // Open a file in a new tab. Returns a boolean indicating success. 139 GBool openInNewTab(QString fileName, int page, QString destName, 140 int rot, QString password, GBool switchToTab); 141 142 // Check that [fileName] is open in the current tab -- if not, open 143 // it. In either case, switch to [page] or [destName]. Returns a 144 // boolean indicating success. 145 GBool checkOpen(QString fileName, int page, QString destName, 146 QString password); 147 148 virtual QMenu *createPopupMenu(); 149 150 // Start up the remote server socket. 151 void startRemoteServer(const QString &remoteServerName); 152 153 // Execute a command [cmd], with [event] for context. 154 void execCmd(const char *cmd, QInputEvent *event); 155 156 private slots: 157 158 void remoteServerConnection(); 159 void remoteServerRead(); 160 161 void pdfResized(); 162 void pdfPaintDone(bool finished); 163 void preLoad(); 164 void postLoad(); 165 void keyPress(QKeyEvent *e); 166 void mousePress(QMouseEvent *e); 167 void mouseRelease(QMouseEvent *e); 168 void mouseClick(QMouseEvent *e); 169 void mouseDoubleClick(QMouseEvent *e); 170 void mouseTripleClick(QMouseEvent *e); 171 void mouseWheel(QWheelEvent *e); 172 void mouseMove(QMouseEvent *e); 173 void pageChange(int pg); 174 void sidebarSplitterMoved(int pos, int index); 175 #if XPDFWIDGET_PRINTING 176 void printStatus(int nextPage, int firstPage, int lastPage); 177 void cancelPrint(); 178 #endif 179 180 void openMenuAction(); 181 void openInNewWinMenuAction(); 182 void reloadMenuAction(); 183 void saveAsMenuAction(); 184 void saveImageMenuAction(); 185 #if XPDFWIDGET_PRINTING 186 void printMenuAction(); 187 #endif 188 void quitMenuAction(); 189 void copyMenuAction(); 190 void singlePageModeMenuAction(); 191 void continuousModeMenuAction(); 192 void sideBySideSingleModeMenuAction(); 193 void sideBySideContinuousModeMenuAction(); 194 void horizontalContinuousModeMenuAction(); 195 void fullScreenMenuAction(bool checked); 196 void rotateClockwiseMenuAction(); 197 void rotateCounterclockwiseMenuAction(); 198 void zoomToSelectionMenuAction(); 199 void toggleToolbarMenuAction(bool checked); 200 void toggleSidebarMenuAction(bool checked); 201 void viewPageLabelsMenuAction(bool checked); 202 void newTabMenuAction(); 203 void newWindowMenuAction(); 204 void closeTabMenuAction(); 205 void closeWindowMenuAction(); 206 void openErrorWindowMenuAction(); 207 void helpMenuAction(); 208 void keyBindingsMenuAction(); 209 void aboutMenuAction(); 210 211 void popupMenuAction(int idx); 212 213 void toggleSidebarButtonPressed(); 214 void pageNumberChanged(); 215 void backButtonPressed(); 216 void forwardButtonPressed(); 217 void zoomOutButtonPressed(); 218 void zoomInButtonPressed(); 219 void zoomIndexChanged(const QString &zoomText); 220 void zoomEditingFinished(); 221 void fitWidthButtonPressed(); 222 void fitPageButtonPressed(); 223 void selectModeButtonPressed(); 224 void statusIndicatorPressed(); 225 void findTextChanged(); 226 void findNextButtonPressed(); 227 void findPrevButtonPressed(); 228 void newTabButtonPressed(); 229 230 void switchTab(QListWidgetItem *current, QListWidgetItem *previous); 231 void infoComboBoxChanged(int idx); 232 void outlineItemClicked(const QModelIndex& idx); 233 void layerItemClicked(const QModelIndex& idx); 234 void attachmentSaveClicked(int idx); 235 236 void clearFindError(); 237 238 private: 239 240 friend class XpdfErrorWindow; 241 242 //--- commands 243 int mouseX(QInputEvent *event); 244 int mouseY(QInputEvent *event); 245 void cmdAbout(GString *args[], int nArgs, QInputEvent *event); 246 void cmdBlockSelectMode(GString *args[], int nArgs, QInputEvent *event); 247 void cmdCheckOpenFile(GString *args[], int nArgs, QInputEvent *event); 248 void cmdCheckOpenFileAtDest(GString *args[], int nArgs, QInputEvent *event); 249 void cmdCheckOpenFileAtPage(GString *args[], int nArgs, QInputEvent *event); 250 void cmdCloseTabOrQuit(GString *args[], int nArgs, QInputEvent *event); 251 void cmdCloseSidebar(GString *args[], int nArgs, QInputEvent *event); 252 void cmdCloseSidebarMoveResizeWin(GString *args[], int nArgs, QInputEvent *event); 253 void cmdCloseSidebarResizeWin(GString *args[], int nArgs, QInputEvent *event); 254 void cmdCloseWindowOrQuit(GString *args[], int nArgs, QInputEvent *event); 255 void cmdContinuousMode(GString *args[], int nArgs, QInputEvent *event); 256 void cmdCopy(GString *args[], int nArgs, QInputEvent *event); 257 void cmdCopyLinkTarget(GString *args[], int nArgs, QInputEvent *event); 258 #if 0 // for debugging 259 void cmdDebug1(GString *args[], int nArgs, QInputEvent *event); 260 #endif 261 void cmdEndPan(GString *args[], int nArgs, QInputEvent *event); 262 void cmdEndSelection(GString *args[], int nArgs, QInputEvent *event); 263 void cmdExpandSidebar(GString *args[], int nArgs, QInputEvent *event); 264 void cmdFind(GString *args[], int nArgs, QInputEvent *event); 265 void cmdFindFirst(GString *args[], int nArgs, QInputEvent *event); 266 void cmdFindNext(GString *args[], int nArgs, QInputEvent *event); 267 void cmdFindPrevious(GString *args[], int nArgs, QInputEvent *event); 268 void cmdFocusToDocWin(GString *args[], int nArgs, QInputEvent *event); 269 void cmdFocusToPageNum(GString *args[], int nArgs, QInputEvent *event); 270 void cmdFollowLink(GString *args[], int nArgs, QInputEvent *event); 271 void cmdFollowLinkInNewTab(GString *args[], int nArgs, QInputEvent *event); 272 void cmdFollowLinkInNewTabNoSel(GString *args[], int nArgs, QInputEvent *event); 273 void cmdFollowLinkInNewWin(GString *args[], int nArgs, QInputEvent *event); 274 void cmdFollowLinkInNewWinNoSel(GString *args[], int nArgs, QInputEvent *event); 275 void cmdFollowLinkNoSel(GString *args[], int nArgs, QInputEvent *event); 276 void cmdFullScreenMode(GString *args[], int nArgs, QInputEvent *event); 277 void cmdGoBackward(GString *args[], int nArgs, QInputEvent *event); 278 void cmdGoForward(GString *args[], int nArgs, QInputEvent *event); 279 void cmdGotoDest(GString *args[], int nArgs, QInputEvent *event); 280 void cmdGotoLastPage(GString *args[], int nArgs, QInputEvent *event); 281 void cmdGotoPage(GString *args[], int nArgs, QInputEvent *event); 282 void cmdHelp(GString *args[], int nArgs, QInputEvent *event); 283 void cmdHideToolbar(GString *args[], int nArgs, QInputEvent *event); 284 void cmdHorizontalContinuousMode(GString *args[], int nArgs, QInputEvent *event); 285 void cmdLinearSelectMode(GString *args[], int nArgs, QInputEvent *event); 286 void cmdLoadTabState(GString *args[], int nArgs, QInputEvent *event); 287 void cmdNewTab(GString *args[], int nArgs, QInputEvent *event); 288 void cmdNewWindow(GString *args[], int nArgs, QInputEvent *event); 289 void cmdNextPage(GString *args[], int nArgs, QInputEvent *event); 290 void cmdNextPageNoScroll(GString *args[], int nArgs, QInputEvent *event); 291 void cmdNextTab(GString *args[], int nArgs, QInputEvent *event); 292 void cmdOpen(GString *args[], int nArgs, QInputEvent *event); 293 void cmdOpenErrorWindow(GString *args[], int nArgs, QInputEvent *event); 294 void cmdOpenFile(GString *args[], int nArgs, QInputEvent *event); 295 void cmdOpenFileAtDest(GString *args[], int nArgs, QInputEvent *event); 296 void cmdOpenFileAtDestIn(GString *args[], int nArgs, QInputEvent *event); 297 void cmdOpenFileAtPage(GString *args[], int nArgs, QInputEvent *event); 298 void cmdOpenFileAtPageIn(GString *args[], int nArgs, QInputEvent *event); 299 void cmdOpenFileIn(GString *args[], int nArgs, QInputEvent *event); 300 void cmdOpenIn(GString *args[], int nArgs, QInputEvent *event); 301 void cmdOpenSidebar(GString *args[], int nArgs, QInputEvent *event); 302 void cmdOpenSidebarMoveResizeWin(GString *args[], int nArgs, QInputEvent *event); 303 void cmdOpenSidebarResizeWin(GString *args[], int nArgs, QInputEvent *event); 304 void cmdPageDown(GString *args[], int nArgs, QInputEvent *event); 305 void cmdPageUp(GString *args[], int nArgs, QInputEvent *event); 306 void cmdPostPopupMenu(GString *args[], int nArgs, QInputEvent *event); 307 void cmdPrevPage(GString *args[], int nArgs, QInputEvent *event); 308 void cmdPrevPageNoScroll(GString *args[], int nArgs, QInputEvent *event); 309 void cmdPrevTab(GString *args[], int nArgs, QInputEvent *event); 310 #if XPDFWIDGET_PRINTING 311 void cmdPrint(GString *args[], int nArgs, QInputEvent *event); 312 #endif 313 void cmdQuit(GString *args[], int nArgs, QInputEvent *event); 314 void cmdRaise(GString *args[], int nArgs, QInputEvent *event); 315 void cmdReload(GString *args[], int nArgs, QInputEvent *event); 316 void cmdRotateCW(GString *args[], int nArgs, QInputEvent *event); 317 void cmdRotateCCW(GString *args[], int nArgs, QInputEvent *event); 318 void cmdRun(GString *args[], int nArgs, QInputEvent *event); 319 void cmdSaveAs(GString *args[], int nArgs, QInputEvent *event); 320 void cmdSaveImage(GString *args[], int nArgs, QInputEvent *event); 321 void cmdSaveTabState(GString *args[], int nArgs, QInputEvent *event); 322 void cmdScrollDown(GString *args[], int nArgs, QInputEvent *event); 323 void cmdScrollDownNextPage(GString *args[], int nArgs, QInputEvent *event); 324 void cmdScrollLeft(GString *args[], int nArgs, QInputEvent *event); 325 void cmdScrollOutlineDown(GString *args[], int nArgs, QInputEvent *event); 326 void cmdScrollOutlineUp(GString *args[], int nArgs, QInputEvent *event); 327 void cmdScrollRight(GString *args[], int nArgs, QInputEvent *event); 328 void cmdScrollToBottomEdge(GString *args[], int nArgs, QInputEvent *event); 329 void cmdScrollToBottomRight(GString *args[], int nArgs, QInputEvent *event); 330 void cmdScrollToLeftEdge(GString *args[], int nArgs, QInputEvent *event); 331 void cmdScrollToRightEdge(GString *args[], int nArgs, QInputEvent *event); 332 void cmdScrollToTopEdge(GString *args[], int nArgs, QInputEvent *event); 333 void cmdScrollToTopLeft(GString *args[], int nArgs, QInputEvent *event); 334 void cmdScrollUp(GString *args[], int nArgs, QInputEvent *event); 335 void cmdScrollUpPrevPage(GString *args[], int nArgs, QInputEvent *event); 336 void cmdSelectLine(GString *args[], int nArgs, QInputEvent *event); 337 void cmdSelectWord(GString *args[], int nArgs, QInputEvent *event); 338 void cmdSetSelection(GString *args[], int nArgs, QInputEvent *event); 339 void cmdShowKeyBindings(GString *args[], int nArgs, QInputEvent *event); 340 void cmdShowToolbar(GString *args[], int nArgs, QInputEvent *event); 341 void cmdShrinkSidebar(GString *args[], int nArgs, QInputEvent *event); 342 void cmdSideBySideContinuousMode(GString *args[], int nArgs, QInputEvent *event); 343 void cmdSideBySideSingleMode(GString *args[], int nArgs, QInputEvent *event); 344 void cmdSinglePageMode(GString *args[], int nArgs, QInputEvent *event); 345 void cmdStartExtendedSelection(GString *args[], int nArgs, QInputEvent *event); 346 void cmdStartPan(GString *args[], int nArgs, QInputEvent *event); 347 void cmdStartSelection(GString *args[], int nArgs, QInputEvent *event); 348 void cmdToggleContinuousMode(GString *args[], int nArgs, QInputEvent *event); 349 void cmdToggleFullScreenMode(GString *args[], int nArgs, QInputEvent *event); 350 void cmdToggleSelectMode(GString *args[], int nArgs, QInputEvent *event); 351 void cmdToggleSidebar(GString *args[], int nArgs, QInputEvent *event); 352 void cmdToggleSidebarMoveResizeWin(GString *args[], int nArgs, QInputEvent *event); 353 void cmdToggleSidebarResizeWin(GString *args[], int nArgs, QInputEvent *event); 354 void cmdToggleToolbar(GString *args[], int nArgs, QInputEvent *event); 355 void cmdViewPageLabels(GString *args[], int nArgs, QInputEvent *event); 356 void cmdViewPageNumbers(GString *args[], int nArgs, QInputEvent *event); 357 void cmdWindowMode(GString *args[], int nArgs, QInputEvent *event); 358 void cmdZoomFitPage(GString *args[], int nArgs, QInputEvent *event); 359 void cmdZoomFitWidth(GString *args[], int nArgs, QInputEvent *event); 360 void cmdZoomIn(GString *args[], int nArgs, QInputEvent *event); 361 void cmdZoomOut(GString *args[], int nArgs, QInputEvent *event); 362 void cmdZoomPercent(GString *args[], int nArgs, QInputEvent *event); 363 void cmdZoomToSelection(GString *args[], int nArgs, QInputEvent *event); 364 int scaleScroll(int delta); 365 void followLink(QInputEvent *event, GBool onlyIfNoSel, 366 GBool newTab, GBool newWindow); 367 368 //--- GUI events 369 int getModifiers(Qt::KeyboardModifiers qtMods); 370 int getContext(Qt::KeyboardModifiers qtMods); 371 int getMouseButton(Qt::MouseButton qtBtn); 372 virtual void keyPressEvent(QKeyEvent *e); 373 virtual void dragEnterEvent(QDragEnterEvent *e); 374 virtual void dropEvent(QDropEvent *e); 375 virtual bool eventFilter(QObject *watched, QEvent *event); 376 377 //--- GUI setup 378 void createWindow(); 379 void createToolBar(); 380 QToolButton *addToolBarButton(const QIcon &icon, 381 const char *slot, const char *tip); 382 XpdfMenuButton *addToolBarMenuButton(const QIcon &icon, 383 const char *tip, QMenu *menu); 384 void addToolBarSeparator(); 385 void addToolBarSpacing(int w); 386 void addToolBarStretch(); 387 void createMainMenu(); 388 void createXpdfPopupMenu(); 389 QWidget *createTabPane(); 390 QWidget *createInfoPane(); 391 void updateInfoPane(); 392 void destroyWindow(); 393 void enterFullScreenMode(); 394 void exitFullScreenMode(); 395 void addTab(); 396 void closeTab(XpdfTabInfo *tab); 397 void gotoTab(int idx); 398 void updateModeInfo(); 399 void updateZoomInfo(); 400 void updateSelectModeInfo(); 401 void updateDocInfo(); 402 void updatePageNumberOrLabel(int pg); 403 void updateOutline(int pg); 404 void setOutlineOpenItems(const QModelIndex &idx); 405 void fillAttachmentList(); 406 void statusIndicatorStart(); 407 void statusIndicatorStop(); 408 void statusIndicatorOk(); 409 void statusIndicatorError(); 410 void showFindError(); 411 void createKeyBindingsDialog(); 412 QString createKeyBindingsHTML(); 413 void createAboutDialog(); 414 void execSaveImageDialog(); 415 416 static XpdfViewerCmd cmdTab[]; 417 418 XpdfApp *app; 419 420 // menu 421 QMenuBar *mainMenu; 422 QMenu *displayModeSubmenu; 423 QAction *fullScreenMenuItem; 424 QAction *toggleToolbarMenuItem; 425 QAction *toggleSidebarMenuItem; 426 QAction *viewPageLabelsMenuItem; 427 428 // popup menu 429 QMenu *popupMenu; 430 QSignalMapper *popupMenuSignalMapper; 431 432 // toolbar 433 int toolBarFontSize; // used for HiDPI scaling 434 QToolBar *toolBar; 435 QLineEdit *pageNumber; 436 QLabel *pageCount; 437 QComboBox *zoomComboBox; 438 QToolButton *fitWidthBtn; 439 QToolButton *fitPageBtn; 440 QToolButton *selectModeBtn; 441 PropertyListAnimation *indicatorAnimation; 442 QList<QVariant> indicatorIcons; 443 QList<QVariant> indicatorErrIcons; 444 QLineEdit *findEdit; 445 QAction *findCaseSensitiveAction; 446 QAction *findWholeWordsAction; 447 448 // sidebar pane 449 QSplitter *sidebarSplitter; 450 int initialSidebarWidth; 451 int sidebarWidth; 452 QListWidget *tabList; 453 QComboBox *infoComboBox; 454 QStackedLayout *infoStack; 455 456 // viewer pane 457 QStackedWidget *viewerStack; 458 459 QLabel *linkTargetBar; 460 QString linkTargetInfo; 461 462 GList *tabInfo; // [XpdfTabInfo] 463 XpdfTabInfo *currentTab; 464 465 double scaleFactor; 466 467 XpdfWidget::DisplayMode fullScreenPreviousDisplayMode; 468 double fullScreenPreviousZoom; 469 470 QTimer *findErrorTimer; 471 472 XpdfErrorWindow *errorWindow; 473 QDialog *keyBindingsDialog; 474 QDialog *aboutDialog; 475 #if XPDFWIDGET_PRINTING 476 QProgressDialog *printStatusDialog; 477 #endif 478 479 QString lastFileOpened; 480 481 QLocalServer *remoteServer; 482 }; 483 484 #endif 485