diff options
Diffstat (limited to 'xpdf-qt/XpdfWidget.h')
-rw-r--r-- | xpdf-qt/XpdfWidget.h | 1029 |
1 files changed, 1029 insertions, 0 deletions
diff --git a/xpdf-qt/XpdfWidget.h b/xpdf-qt/XpdfWidget.h new file mode 100644 index 0000000..0e33d0d --- /dev/null +++ b/xpdf-qt/XpdfWidget.h @@ -0,0 +1,1029 @@ +//======================================================================== +// +// XpdfWidget.h +// +// Copyright 2009-2021 Glyph & Cog, LLC +// +//======================================================================== + +//! \mainpage +//! +//! XpdfWidget is a PDF viewer widget class for Qt. +//! <br><br> +//! <a href="changes.html">Change history</a> +//! <br><br> +//! Copyright 2009-2022 Glyph & Cog, LLC + +//! \file + +#ifndef XPDFWIDGET_H +#define XPDFWIDGET_H + +#include <aconf.h> + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include <QAbstractScrollArea> + +class QMutex; +class QTimer; +#if XPDFWIDGET_PRINTING +class QPrinter; +class QPrintDialog; +#endif + +class GString; +class PDFDoc; +class QtPDFCore; + +//------------------------------------------------------------------------ + + +/*! Opaque handle used to represent an outline node. */ +typedef void *XpdfOutlineHandle; + +/*! Opaque handle used to represent a layer. */ +typedef void *XpdfLayerHandle; + +/*! Opaque handle used to represent a layer display order tree node. */ +typedef void *XpdfLayerOrderHandle; + +/*! Opaque handle used to represent an annotation. */ +typedef void *XpdfAnnotHandle; + +/*! Opaque handle used to represent a form field. */ +typedef void *XpdfFormFieldHandle; + +/*! Opaque handle used to represent a PDF document. */ +typedef void *XpdfDocHandle; + +//------------------------------------------------------------------------ + +/*! Text search result, returned by XpdfWidget::findAll(). */ +struct XpdfFindResult { + + //! \cond PROTECTED + XpdfFindResult(int pageA, double xMinA, double yMinA, + double xMaxA, double yMaxA) + : page(pageA), xMin(xMinA), yMin(yMinA), xMax(xMaxA), yMax(yMaxA) {} + XpdfFindResult(): page(0), xMin(0), yMin(0), xMax(0), yMax(0) {} + //! \endcond + + /*! Page number. */ + int page; + + /*! \name Bounding box. */ + ///@{ + double xMin, yMin, xMax, yMax; + ///@} +}; + +//------------------------------------------------------------------------ + +//! A PDF viewer widget class for Qt. +class XpdfWidget: public QAbstractScrollArea { + Q_OBJECT + +public: + + //! Error codes returned by certain XpdfViewer functions. + enum ErrorCode { + pdfOk = 0, //!< no error + pdfErrOpenFile = 1, //!< couldn't open the PDF file + pdfErrBadCatalog = 2, //!< couldn't read the page catalog + pdfErrDamaged = 3, //!< PDF file was damaged and couldn't be + //!< repaired + pdfErrEncrypted = 4, //!< file was encrypted and password was + //!< incorrect or not supplied + pdfErrHighlightFile = 5, //!< nonexistent or invalid highlight file + pdfErrBadPrinter = 6, //!< invalid printer + pdfErrPrinting = 7, //!< error during printing + pdfErrPermission = 8, //!< PDF file doesn't allow that operation + pdfErrBadPageNum = 9, //!< invalid page number + pdfErrFileIO = 10, //!< file I/O error + pdfErrNoHandle = 1001, //!< NULL object handle + pdfErrOutOfMemory = 1002, //!< out of memory + pdfErrBusy = 1003, //!< PDF component is busy + pdfErrBadArg = 1004 //!< invalid argument + }; + + //! Display modes, to be passed to XpdfWidget::setDisplayMode(). + enum DisplayMode { + pdfDisplaySingle, //!< single page + pdfDisplayContinuous, //!< pages stacked vertically + pdfDisplaySideBySideSingle, //!< two facing pages + pdfDisplaySideBySideContinuous, //!< facing pages, stacked vertically + pdfDisplayHorizontalContinuous //!< pages stacked horizontally + }; + + //! \name Zoom values + //! Special values for XpdfWidget::setZoom() / XpdfWidget::getZoom() + //@{ + static const int zoomToPage = -1; //!< zoom to fit whole page + static const int zoomToWidth = -2; //!< zoom to fit page width + static const int zoomToHeight = -3; //!< zoom to fit page height + //@} + + //! \name Find flags + //! Flags to be passed to XpdfWidget::find() + //@{ + //! search backward from the starting point + static const int findBackward = 0x00000001; + //! perform a case-sensitive search (default is case-insensitive) + static const int findCaseSensitive = 0x00000002; + //! start searching from the previous search result + static const int findNext = 0x00000004; + //! limit the search to the current page + static const int findOnePageOnly = 0x00000008; + //! limit the search to whole words + static const int findWholeWord = 0x00000010; + //@} + + //! Initialize the XpdfWidget class, reading a configuration file. + //! If \a configFileName is non-empty, the specified file is + //! tried first. If \a configFileName is empty, or the file + //! doesn't exist, the default location is tried (\c <exe-dir>/xpdfrc + //! on Windows; \c ~/\c .xpdfrc on Unix). + //! + //! This function must be called before any other XpdfWidget functions + //! (including the constructor). It will be called automatically + //! (with a NULL \a configFileName) if it hasn't already been + //! called when the first XpdfWidget function is used. + static void init(const QString &configFileName = QString()); + + //! Process a configuration command, i.e., one line of an xpdfrc file. + //! Note that this applies globally to all XpdfWidget instances. + static void setConfig(const QString &command); + + //! The XpdfWidget constructor. + //! \param paperColor the paper background color (which should generally + //! be left as white) + //! \param matteColor the matte color displayed between pages, and around + //! pages that are smaller than the window + //! \param reverseVideo sets reverse video at startup + //! \param parentA the parent QWidget + XpdfWidget(const QColor &paperColor = QColor(0xff, 0xff, 0xff), + const QColor &matteColor = QColor(0x80, 0x80, 0x80), + bool reverseVideo = false, QWidget *parentA = 0); + + //! The XpdfWidget constructor. + //! \param paperColor the paper background color (which should generally + //! be left as white) + //! \param matteColor the matte color displayed between pages, and around + //! pages that are smaller than the window + //! \param reverseVideo sets reverse video at startup + //! \param parentA the parent QWidget + //! This version has the \a parent argument first so it works correctly + //! with Qt Designer. + XpdfWidget(QWidget *parentA, + const QColor &paperColor = QColor(0xff, 0xff, 0xff), + const QColor &matteColor = QColor(0x80, 0x80, 0x80), + bool reverseVideo = false); + + //! Destroys the XpdfWidget. + virtual ~XpdfWidget(); + + //! Control handling of hyperlinks. + //! If enabled, the viewer will follow hyperlinks when clicked with the + //! left mouse button. If disabled, the viewer will ignore left mouse + //! button clicks on hyperlinks. The default is enabled. + void enableHyperlinks(bool on); + + //! Control handling of external hyperlinks. + //! This setting allows disabling external hyperlinks (links that + //! open another PDF file, or that involve a URL), independent of + //! internal hyperlinks (links to locations within the same PDF + //! file). This setting is ignored if all hyperlinks are disabled + //! (enableHyperlinks(false)). The default is enabled. + void enableExternalHyperlinks(bool on); + + //! Control handling of text selection. + //! If enabled, the viewer will allow the user to select rectangular + //! regions of text when the user drags with the left mouse button. If + //! disabled, dragging with the left mouse button is ignored. The + //! default is enabled. + void enableSelect(bool on); + + //! Control mouse panning. + //! If enabled, dragging with the middle mouse button pressed will pan + //! the page. If disabled, the middle button is ignored. The default + //! is enabled. + void enablePan(bool on); + + //! Control touchscreen panning. + //! If enabled, QPanGestures are recognized and used to pan the PDF + //! view. + void enableTouchPan(bool on); + + //! Control touchscreen zooming. + //! If enabled QPinchGestures are recognized and used to pinch-zoom + //! the PDF view. + void enableTouchZoom(bool on); + + //! Control keypress passthrough. + //! If enabled, XpdfWidget will pass keypress events through to the + //! keyPress signal, with no other processing. If disabled, XpdfWidget + //! will implement some built-in key bindings. The default is disabled. + void setKeyPassthrough(bool on) { keyPassthrough = on; } + + //! Control mouse event passthrough. + //! If enabled, XpdfWidget will pass mouse events through to the + //! mousePress/mouseRelease signals, with no other processing. If + //! disabled, XpdfWidget will implement some built-in mouse handling + //! (in addition to sending the signals). The default is disabled. + void setMousePassthrough(bool on) { mousePassthrough = on; } + + //! Control the password dialog. + //! If enabled, the viewer will show a password dialog for encrypted + //! files; if disabled, it will simply return \c pdfErrEncrypted unless + //! the correct password is passed to \c pdfLoadFileWithPassword. The + //! default is enabled. + void showPasswordDialog(bool showDlg); + + //! Set the matte color, i.e., the color used for background outside + //! the actual page area. The default is a medium gray. + void setMatteColor(const QColor &matteColor); + + //! Turn reverse video mode on/off. The default is off. + void setReverseVideo(bool reverse); + + //! Set the cursor. The requested cursor will only be displayed in + //! the viewport (not in the scrollbars). + void setCursor(const QCursor &cursor); + + //! Reset to the default cursor. + void unsetCursor(); + + //! Load a PDF file and display its first page. + //! \param fileName the PDF file to load + //! \param password a string to be tried first as the owner password + //! and then as the user password + //! \return \c pdfOk if successful; an error code, otherwise + ErrorCode loadFile(const QString &fileName, + const QString &password = ""); + + //! Load a PDF file from a memory buffer and display its first page. + //! \param buffer the PDF file in memory + //! \param bufferLength length of \a buffer + //! \param password a string to be tried first as the owner password + //! and then as the user password + //! \return \c pdfOk if successful; an error code otherwise + ErrorCode loadMem(const char *buffer, unsigned int bufferLength, + const QString &password = ""); + + //! Load a PDF file and return a handle. + + //! This function can be safely called from a non-GUI thread. Use + //! XpdfWidget::loadDoc (on the GUI thread) to load the document + //! handle into the viewer. The handle returned in *\c docPtr + //! should be passed to either XpdfWidget::loadDoc or + //! XpdfWidget::freeDoc. + //! + //! Calling XpdfWidget::readDoc + XpdfWidget::loadDoc is equivalent + //! to calling XpdfWidget::loadFile. The difference is that readDoc + //! can be called on a background thread to avoid stalling the user + //! interface. + //! \param docPtr the PDF document handle will be returned her + //! \param fileName the PDF file to load + //! \param password a string to be tried first as the owner password + //! and then as the user password + //! \return \c pdfOk if successful; an error code, otherwise + ErrorCode readDoc(XpdfDocHandle *docPtr, + const QString &fileName, + const QString &password = ""); + + //! Load a PDF document and display its first page. + //! This function displays a PDF document handle created by + //! XpdfWidget::readDoc. The document handle should not be used for + //! anything else after calling this function. + //! \return \c pdfOk if successful; an error code, otherwise + ErrorCode loadDoc(XpdfDocHandle doc); + + //! Free a PDF document. + //! This function frees a PDF document handle created by + //! XpdfWidget::readDoc. It should only be called if the document + //! is not going to be displayed. That is: after calling + //! XpdfWidget::readDoc, you should call either XpdfWidget::loadDoc + //! or XpdfWidget::freeDoc. The document handle should not be used + //! for anything else after calling this function. + void freeDoc(XpdfDocHandle doc); + + //! Reload the current PDF file. + //! This reloads the current PDF file, maintaining the zoom and + //! scroll position (if possible). This only works if the PDF file + //! was loaded from a file (i.e., with XpdfWidget::loadFile, not + //! with XpdfWidget::loadMem). + //! \return \c pdfOk if successful; an error code otherwise + ErrorCode reload(); + + //! Close the currently open PDF file (if any). + //! Calling this function is optional - the current PDF file will be + //! automatically closed if XpdfWidget::loadFile or XpdfWidget::loadMem + //! is called. + void closeFile(); + + //! Save the PDF file with another name. + //! \param fileName the file to be written + //! \return \c pdfOk if successful; an error code otherwise + ErrorCode saveAs(const QString &fileName); + + //! Get the file name of the currently open PDF file. + QString getFileName() const; + + //! Returns true if there is currently a PDF file open. + bool hasOpenDocument() const; + + //! Return the number of pages in the currently open PDF file. + //! Returns -1 if no file is open. + int getNumPages() const; + + //! Return the currently displayed page number. + //! Returns -1 if no file is open. + int getCurrentPage() const; + + //! Return the page number corresponding to the middle of the + //! window. + int getMidPage() const; + + //! Display the specified page. + void gotoPage(int pageNum); + + //! Display the first page. + //! This is equivalent to \code + //! gotoPage(1) + //! \endcode + void gotoFirstPage(); + + //! Display the last page. + //! This is equivalent to \code + //! gotoPage(getNumPages()) + //! \endcode + void gotoLastPage(); + + //! Display the next page. + void gotoNextPage(bool scrollToTop = true); + + //! Display the previous page. + void gotoPreviousPage(bool scrollToTop = true); + + //! Go to a named destination. + bool gotoNamedDestination(const QString &dest); + + //! Go forward along the history list. + void goForward(); + + //! Go backward along the history list. + void goBackward(); + + //! Scroll one screen up. + void scrollPageUp(); + + //! Scroll one screen down. + void scrollPageDown(); + + //! Scroll the page so that the top-left corner of the window is + //! (\a xx,\a yy) pixels from the top-left corner of the PDF page. + void scrollTo(int xx, int yy); + + //! Scroll the page by (\a dx,\a dy) pixels. If \a dx is positive, + //! scrolls right; if \a dx is negative, scrolls left. Similarly, + //! positive and negative values of \a dy scroll down and up, + //! respectively. + void scrollBy(int dx, int dy); + + //! Return the current scroll position x coordinate. + int getScrollX() const; + + //! Return the current scroll position y coordinate. + int getScrollY() const; + + //! Change the zoom factor. + //! This can be a percentage factor (where 100 means 72 dpi) or one of + //! the special values, XpdfWidget::zoomToPage or XpdfWidget::zoomToWidth. + void setZoom(double zoom); + + //! Return the current zoom factor. + //! This can be a percentage factor or one of the special values, + //! XpdfWidget::zoomToPage or XpdfWidget::zoomToWidth. + double getZoom() const; + + //! Return the current zoom factor as a percentage. + //! If the zoom is set to XpdfWidget::zoomToPage or + //! XpdfWidget::zoomToWidth, returns the computed zoom percentage + //! for the specified page, based on the current window size. + double getZoomPercent(int page = 1) const; + + //! Zoom in to the specified rectangle. + //! The coordinate system is the same one used by + //! XpdfWidget::getCurrentSelection. This function will set the zoom + //! factor and scroll position so that the specified rectangle just fits + //! in the window. + void zoomToRect(int page, double xMin, double yMin, + double xMax, double yMax); + + //! Set the zoom factor, while maintaining the current center. + //! Accepts the same zoom values as XpdfWidget::setZoom. + void zoomCentered(double zoom); + + //! Zoom so that the current page(s) fill the window width. + //! Maintains the vertical center. + void zoomToCurrentWidth(); + + //! Change the page rotation. + //! \param rotate rotation angle in degrees - must be 0, 90, 180, or 270 + void setRotate(int rotate); + + //! Return the current page rotation. + //! The angle can be 0, 90, 180, or 270. + int getRotate() const; + + //! Set continuous or single-page view mode. + //! Deprecated: this is equivalent to calling setDisplayMode() with + //! pdfDisplaySingle or pdfDisplayContinuous. + //! \param continuous true for continous view mode, false for single-page + //! view mode + void setContinuousMode(bool continuous); + + //! Return true if the viewer is in continuous view mode, or false + //! if it is in any other mode. Deprecated: see getDisplayMode(). + bool getContinuousMode() const; + + //! Set the display mode. + void setDisplayMode(DisplayMode mode); + + //! Return the current display mode. + DisplayMode getDisplayMode(); + + //! Returns true if the mouse is currently over a hyperlink. + bool mouseOverLink(); + + //! Returns true if the specified coordinates are inside a + //! hyperlink. Note: This function expects PDF coordinates, not window + //! coordinates. + bool onLink(int page, double xx, double yy); + + //! Get destination information for the hyperlink at the specified + //! page and coordinates. If there is a link at the specified + //! point, returns a string suitable for displaying to a user; + //! otherwise returns an empty string. Note: This function expects + //! PDF coordinates, not window coordinates. + QString getLinkInfo(int page, double xx, double yy); + + //! Get destination information for the hyperlink under the mouse. + //! If the mouse is currently over a hyperlink, return an info + //! string (same as with getLinkInfo()); otherwise return an empty + //! string. + QString getMouseLinkInfo(); + + //! Activate the link (if any) at the specified page and coordinates. + //! Returns true if successful. Note: This function expects PDF + //! coordinates, not window coordinates. + bool gotoLinkAt(int page, double xx, double yy); + + //! Check for an annotation containing the specified point. + //! Returns NULL if there is no annotation at this point. Note: + //! This function expects PDF coordinates, not window coordinates. + XpdfAnnotHandle onAnnot(int page, double xx, double yy); + + //! Get the annotation type. + QString getAnnotType(XpdfAnnotHandle annot); + + //! Get the annotation's content. + //! Usage of this depends on the annotation type. + QString getAnnotContent(XpdfAnnotHandle annot); + + //! Check for a form field containing the specified point. + //! Returns NULL if there is no annotation at this point. Note: + //! This function expects PDF coordinates, not window coordinates. + XpdfFormFieldHandle onFormField(int page, double xx, double yy); + + //! Get the form field's type. + QString getFormFieldType(XpdfFormFieldHandle field); + + //! Get the form field's name. + QString getFormFieldName(XpdfFormFieldHandle field); + + //! Get the form field's content. + //! Usage of this depends on the field type. + QString getFormFieldValue(XpdfFormFieldHandle field); + + //! Get the form field's bounding box. + void getFormFieldBBox(XpdfFormFieldHandle field, int *pageNum, + double *xMin, double *yMin, + double *xMax, double *yMax); + + //! Convert window coordinates to PDF coordinates. Returns true if + //! successful, i.e., if the specified point falls on a PDF page. + bool convertWindowToPDFCoords(int winX, int winY, + int *page, double *pdfX, double *pdfY); + + //! Convert PDF coordinates to window coordinates. + void convertPDFToWindowCoords(int page, double pdfX, double pdfY, + int *winX, int *winY); + + //! Enable or disable window redraws. + //! This is useful, e.g., for avoiding extra redraws during window + //! resizing. Deprecated -- this just calls setUpdatesEnabled(). + void enableRedraw(bool enable); + + //! Return the coordinates of the specified page box. + //! \param page the page number + //! \param box the requested page box - one of "media", "crop", + //! "bleed", "trim", or "art" (\a box is not case-sensitive) + //! \param *xMin returns the minimum x coordinate of the box + //! \param *yMin returns the minimum y coordinate of the box + //! \param *xMax returns the maximum x coordinate of the box + //! \param *yMax returns the maximum y coordinate of the box + //! + //! All coordinates are in points (1 point = 1/72 inch). + void getPageBox(int page, const QString &box, + double *xMin, double *yMin, double *xMax, double *yMax) const; + + //! Return the width of the specified page. + //! This function returns the crop box width, measured in points + //! (1 point = 1/72 inch). + double getPageWidth(int page) const; + + //! Return the height of the specified page. + //! This function returns the crop box height, measured in points + //! (1 point = 1/72 inch). + double getPageHeight(int page) const; + + //! Get the default rotation for the specified page. + //! This is the default viewing rotation specified in the PDF file - + //! it will be one of 0, 90, 180, or 270. + int getPageRotation(int page) const; + + //! Check to see if there is a selection. + //! Returns true if there is a currently active selection. + bool hasSelection(); + + //! Returns the current selection. + //! If there is a currently active selection, sets *\a page, (*\a x0,*\a y0), + //! and (*\a x1,*\a y1) to the page number and upper-left and lower-right + //! coordinates, respectively, and returns true. If there is no selection, + //! returns false. + bool getCurrentSelection(int *page, double *x0, double *y0, + double *x1, double *y1) const; + + //! Set the selection. + //! Sets the current selection to the rectangle with upper-left corner + //! (\a x0,\a y0) and lower-right corner (\a x1,\a y1) on \a page. + void setCurrentSelection(int page, double x0, double y0, + double x1, double y1); + + //! Clear the selection. + void clearSelection(); + + //! Check for block selection mode. + //! Returns true if the current selection mode is block. + bool isBlockSelectMode(); + + //! Check for linear selection mode. + //! Returns true if the current selection mode is linear. + bool isLinearSelectMode(); + + //! Set block selection mode. + //! In this mode, the selection is a simple rectangle. Any part of + //! the page can be selected, regardless of the content on the page. + void setBlockSelectMode(); + + //! Set linear selection mode. + //! In this mode, the selection follows text. Non-text regions + //! cannot be selected. + void setLinearSelectMode(); + + //! Set the selection color. + void setSelectionColor(const QColor &selectionColor); + + + //! Force a complete redraw. + void forceRedraw(); + +#if XPDFWIDGET_PRINTING + //! Checks to see if printing is allowed. + //! This function returns false if the currently displayed PDF file + //! is encrypted and does not allow printing (or if no PDF file is + //! currently open). The owner password can be used to circumvent + //! this: if a valid owner password was supplied to + //! XpdfWidget::loadFile, this function will always return true. If + //! this function returns false, the printing functions will return + //! an error. + bool okToPrint() const; + + //! Print the currently displayed PDF file. + //! Prints the currently displayed PDF file. If \a showDialog is + //! true, displays the Qt print dialog, and uses the printer + //! selected by the user. If \a showDialog is false, prints to the + //! default printer without showing any dialogs. + ErrorCode print(bool showDialog); + + //! Print the currently displayed PDF file. + //! Prints the currently displayed PDF file to \a prt. + ErrorCode print(QPrinter *prt); + + //! Cancel an in-progress print job. This should be called in + //! response to a printStatus signal. + void cancelPrint() { printCanceled = true; } + + void updatePrintStatus(int nextPage, int firstPage, int lastPage); + bool isPrintCanceled() { return printCanceled; } + + //! Set the horizontal and vertical print resolution, in dots per + //! inch (DPI). The horizontal and vertical resolutions are + //! typically the same. (There are exceptions, such as some chart + //! printers.) + void setPrintDPI(int hDPI, int vDPI); +#endif // XPDFWIDGET_PRINTING + + //! Convert a page to a color image. + //! This function converts the page number \a page to a 24-bit RGB + //! bitmap, at a resolution of \a dpi dots per inch. If \a + //! transparent is true, the returned image will be 32-bit ARGB + //! instead, and will include an alpha channel. + QImage convertPageToImage(int page, double dpi, bool transparent = false); + + //! Convert a rectangular region of a page to a color image. + //! This function converts a rectangular region, defined by corners + //! (\a x0,\a y0) and (\a x1,\a y1), of page number \a page to a + //! 24-bit RGB bitmap, at a resolution of \a dpi dots per inch. If + //! \a transparent is true, the returned image will be 32-bit ARGB + //! instead, and will include an alpha channel. + QImage convertRegionToImage(int page, double x0, double y0, + double x1, double y1, double dpi, + bool transparent = false); + + //! Retrieve an embedded thumbnail image. + //! This function returns the embedded thumbnail image for the + //! specified page, or a null image if there is no embedded + //! thumbnail. This function does not do any rasterization -- it + //! only returns a non-null image if there is an embedded thumbnail + //! in the PDF file. + QImage getThumbnail(int page); + + //! Checks to see if text extraction is allowed. + //! This function returns false if the currently displayed PDF file + //! is encrypted and does not allow extraction of text (or if no PDF + //! file is currently open). The owner password can be used to + //! circumvent this: if a valid owner password was supplied to + //! XpdfWidget::loadFile, this function will always return true. + //! If this function returns false, the text extraction functions will + //! not return any text. + bool okToExtractText() const; + + //! Set the encoding to use for text extraction. + //! The following encodings are predefined: + //! - \c "Latin1": ISO-8859-1 (this is the default value) + //! - \c "ASCII7": 7-bit ASCII + //! - \c "UTF-8": Unicode in UTF-8 format + //! - \c "UCS-2": Unicode in UCS-2 format + //! + //! Additional encodings can be defined via the xpdfrc config file. + void setTextEncoding(const QString &encodingName); + + //! Extract text from a region of a page. + //! This function extracts and returns text from the rectangular + //! region, defined by corners (\a x0,\a y0) and (\a x1,\a y1), of + //! page number \a page. The coordinates returned by + //! XpdfWidget::getCurrentSelection may be passed directly to this + //! function. Returns an empty string if no file is open or if + //! text extraction is not allowed. + QString extractText(int page, double x0, double y0, + double x1, double y1); + + //! Get the currently selected text. + //! Returns an empty string if there is no selection (or if there is + //! no text in the selected region). + QString getSelectedText(); + + //! Copy the current selection to the clipboard. + void copySelection(); + + //! Find a text string. + //! This function searches for a Unicode text string. Starts + //! searching after (before, if searching backward) the current + //! selection (if there is a selection), or at the top (bottom, + //! if searching backward) of the current page (if there is no + //! selection). The \a flags argument consists of zero or more + //! of the following, or-ed together: + //! - \c findBackward - search backward from the starting point + //! - \c findCaseSensitive - perform a case-sensitive search + //! (default is case-insensitive) + //! - \c findNext - start searching from the previous search result + //! - \c findOnePageOnly - limit the search to the current page + //! - \c findWholeWord - limit the search to whole words + bool find(const QString &text, int flags = 0); + + //! Find all occurrences of a text string. + //! This function searches for a Unicode text string, in pages + //! \a firstPage .. \a lastPage. The \a flags argument consists of + //! zero or more of the following, or-ed together: + //! - \c findCaseSensitive - perform a case-sensitive search + //! (default is case-insensitive) + //! - \c findWholeWord - limit the search to whole words + //! Returns a list of search results. + QVector<XpdfFindResult> findAll(const QString &text, int firstPage, + int lastPage, int flags = 0); + + //! Check if the PDF file has page labels. + //! Return true if the currently open PDF file has page labels. + bool hasPageLabels(); + + //! Convert a page number to a page label. + //! Return the page label for page number \a pageNum. Returns an + //! empty string if the page number is invalid or if the PDF file + //! doesn't have page labels. + QString getPageLabelFromPageNum(int pageNum); + + //! Convert a page label to a page number. + //! Return the page number for \a pageLabel. Returns -1 if there is + //! no matching page label or if the PDF file doesn't have page + //! labels. + int getPageNumFromPageLabel(QString pageLabel); + + //! Return the number of children of an outline tree node. + //! This function returns the number of children of node \a outline, + //! or the number of root outline entries if \a outline is \c NULL. + int getOutlineNumChildren(XpdfOutlineHandle outline); + + //! Return a child of an outline tree node. + //! This function returns the \a idx 'th child of node \a outline, + //! or the \a idx 'th root entry if \a outline is \c NULL. + XpdfOutlineHandle getOutlineChild(XpdfOutlineHandle outline, int idx); + + //! Return the parent of an outline tree node. + //! This function returns the parent of node \a outline, or NULL if + //! \a outline is a root item. + XpdfOutlineHandle getOutlineParent(XpdfOutlineHandle outline); + + //! Get the title of an outline tree node. + //! This function returns the title of node \a outline. + QString getOutlineTitle(XpdfOutlineHandle outline); + + //! Return true if the specified outline entry starts open. + bool getOutlineStartsOpen(XpdfOutlineHandle outline); + + //! Return the target page number for the specified outline entry. + int getOutlineTargetPage(XpdfOutlineHandle outline); + + //! Jump to the target of the specified outline entry. + void gotoOutlineTarget(XpdfOutlineHandle outline); + + //! Return the number of layers in the PDF file. + //! Note that a PDF file can have zero or more layers. + int getNumLayers() const; + + //! Get a layer handle. + //! This function returns a handle for the \a idx 'th layer. + XpdfLayerHandle getLayer(int idx) const; + + //! Get the name of a layer. + //! This function returns the title of \a layer. + QString getLayerName(XpdfLayerHandle layer) const; + + //! Get the visibility state of a layer. + //! Returns true if the layer is currently visible, false if not. + bool getLayerVisibility(XpdfLayerHandle layer) const; + + //! Set the visibility state of a layer. + //! \param layer the layer handle + //! \param visibility the new state - true for visible, false for not + //! visible + void setLayerVisibility(XpdfLayerHandle layer, bool visibility); + + //! Get the suggested state for this layer in viewing mode. + //! This function returns one of: + //! - 1: on + //! - 0: off + //! - -1: unset + int getLayerViewState(XpdfLayerHandle layer) const; + + //! Get the suggested state for this layer in printing mode. + //! This function returns one of: + //! - 1: on + //! - 0: off + //! - -1: unset + int getLayerPrintState(XpdfLayerHandle layer) const; + + //! Get the root of the layer display order tree. + XpdfLayerOrderHandle getLayerOrderRoot() const; + + //! Check the type of a layer display order tree node. + //! Returns true if the specified node of the layer display order + //! tree is a name; false if the node is a layer. + bool getLayerOrderIsName(XpdfLayerOrderHandle order) const; + + //! Get the name of a layer display order tree node. + //! This should only be called if getLayerOrderIsName returns true. + QString getLayerOrderName(XpdfLayerOrderHandle order) const; + + //! Get the layer associated with a layer display order tree node. + XpdfLayerHandle getLayerOrderLayer(XpdfLayerOrderHandle order); + + //! Returns the number of children attached to a layer display order + //! tree node. + int getLayerOrderNumChildren(XpdfLayerOrderHandle order); + + //! Returns the \a idx 'th child of a layer display order tree node. + XpdfLayerOrderHandle getLayerOrderChild(XpdfLayerOrderHandle order, int idx); + + //! Return the parent of a layer display order tree node. + //! This function returns the parent of node \a order, or NULL if \a + //! order is the root node. + XpdfLayerOrderHandle getLayerOrderParent(XpdfLayerOrderHandle order); + + //! Return the number of embedded files in the current PDF file. + int getNumEmbeddedFiles(); + + //! Return the name of the \a idx 'th embedded file. + QString getEmbeddedFileName(int idx); + + //! Save the \a idx 'th embedded file with the specified file name. + //! Returns true if successful. + bool saveEmbeddedFile(int idx, QString fileName); + + //--- for internal use + + //! \cond + + virtual QSize sizeHint() const; + QtPDFCore *getCore() { return core; } + + //! \endcond + +signals: + + //! This signal is emitted whenever the viewer displays a new page. + //! It can be triggered by user actions (e.g., the PageDown button), + //! or program control (e.g., the gotoNextPage function). + //! \param pageNum - the new page number + void pageChange(int pageNum); + + //! This signal is emitted whenever the page shown at the middle of + //! the window changes. + //! It is similar to XpdfWidget::pageChange, except that it reflects + //! the page shown at the middle of the window (instead of the page + //! at the top of the window). + void midPageChange(int pageNum); + + //! This signal is emitted just before a PDF file is loaded. + void preLoad(); + + //! This signal is emitted just after a PDF file is loaded. + void postLoad(); + + //! This signal is emitted whenever a key is pressed. + void keyPress(QKeyEvent *e); + + //! This signal is emitted whenever a mouse button is pressed. + void mousePress(QMouseEvent *e); + + //! This signal is emitted whenever a mouse button is released. + void mouseRelease(QMouseEvent *e); + + //! This signal is emitted whenever a mouse button is clicked. + //! A click is defined as a button press and release within a short + //! distance of each other (a few pixels). The sequence of signals + //! is: mousePress, possibly a few mouseMoves, mouseRelease, and + //! then mouseClick. + void mouseClick(QMouseEvent *e); + + //! This signal is emitted whenever a mouse button is double-clicked. + //! Double clicks are two clicks within a few pixels of each other, + //! and within a certain time of each other. The sequence of + //! signals is: mousePress, mouseRelease, mouseClick, mousePress, + //! mouseRelease, mouseDoubleClick. There may also be mouseMoves + //! between the presses and releases. + void mouseDoubleClick(QMouseEvent *e); + + //! This signal is emitted whenever a mouse button is triple-clicked. + //! Triple clicks are three clicks within a few pixels of each + //! other, and within a certain time of each other. The sequence of + //! signals is: mousePress, mouseRelease, mouseClick, mousePress, + //! mouseRelease, mouseDoubleClick, mousePress, mouseRelease, + //! mouseTripleClick. There may also be mouseMoves between the + //! presses and releases. + void mouseTripleClick(QMouseEvent *e); + + //! This signal is emitted whenever the mouse pointer is moved. + void mouseMove(QMouseEvent *e); + + //! This signal is emitted whenever a mouse wheel is clicked. + void mouseWheel(QWheelEvent *e); + + //! This signal is emitted whenever the user clicks on a hyperlink. + //! \param linkType the type of link - one of: + //! - \c "goto": a link to another page in the same PDF + //! file - \a dest is empty; \a page is the destination + //! page number + //! - \c "pdf": a link to another PDF file - \a dest is the + //! target PDF file; \a page is 0 + //! - \c "launch": an arbitrary command to be run - \a dest + //! is the command; \a page is 0 + //! - \c "url": a URL link - \a dest is the URL; \a page is 0 + //! - \c "named": a "named action" link - \a dest is the + //! action (see the PDF spec for details); \a page is 0 + //! - \c "unknown": an unknown link type - \a dest is empty; + //! \a page is 0 + //! \param dest destination string + //! \param page destination page number + void linkClick(const QString &linkType, const QString &dest, int page); + + //! This signal is emitted when the user selects an area. + //! Use XpdfWidget::getCurrentSelection to retrieve the selection. + void selectDone(); + + //! This signal is emitted whenever the widget is repainted. \a + //! finished is true if the painted view is complete, or false if + //! this was an incremental update, i.e., if the view is still being + //! rendered. + void paintDone(bool finished); + + //! This signal is emitted when the widget is resized. + void resized(); + + +#if XPDFWIDGET_PRINTING + //! This signal is called before each page is spooled, and after the + //! last page is spooled. It is typically used to update a print + //! status dialog. \a nextPage is the next page to be printed. + //! \a firstPage and \a lastPage specify the range of pages being + //! printed. + void printStatus(int nextPage, int firstPage, int lastPage); +#endif + + //! \cond PROTECTED + + void tileDone(); + + //! \endcond + +protected: + + //! \cond PROTECTED + + virtual void paintEvent(QPaintEvent *eventA); + virtual void resizeEvent(QResizeEvent *eventA); + virtual void scrollContentsBy(int dx, int dy); + virtual void keyPressEvent(QKeyEvent *e); + virtual void mousePressEvent(QMouseEvent *e); + virtual void mouseReleaseEvent(QMouseEvent *e); + virtual void mouseMoveEvent(QMouseEvent *e); + virtual void wheelEvent(QWheelEvent *e); + virtual bool eventFilter(QObject *obj, QEvent *event); + + //! \endcond + +private slots: + + void tick(); + +private: + + void setup(const QColor &paperColor, const QColor &matteColor, + bool reverseVideo); + static void updateCbk(void *data, GString *fileName, + int pageNum, int numPages, + const char *linkLabel); + static void midPageChangedCbk(void *data, int pageNum); + static void preLoadCbk(void *data); + static void postLoadCbk(void *data); + static void linkCbk(void *data, const char *type, + const char *dest, int page); + static void selectDoneCbk(void *data); + static void paintDoneCbk(void *data, bool finished); + static void tileDoneCbk(void *data); + + friend class XpdfViewer; + bool getLinkTarget(int page, double xx, double yy, + QString &targetFileName, int &targetPage, + QString &targetDest); + +#if XPDFWIDGET_PRINTING + QPrinter *printerForDialog; + QPrintDialog *printDialog; + int printHDPI, printVDPI; + bool printCanceled; +#endif + + static QMutex initMutex; + + QtPDFCore *core; + double scaleFactor; + + bool keyPassthrough; + bool mousePassthrough; + int lastMousePressX[3], lastMousePressY[3]; + ulong lastMousePressTime[3]; + bool lastMouseEventWasPress; + + bool touchPanEnabled; + bool touchZoomEnabled; + double pinchZoomStart; + + QTimer *tickTimer; +}; + +#endif |