//========================================================================
//
// XpdfWidget.h
//
// Copyright 2009-2021 Glyph & Cog, LLC
//
//========================================================================
//! \mainpage
//!
//! XpdfWidget is a PDF viewer widget class for Qt.
//!
//! Change history
//!
//! Copyright 2009-2022 Glyph & Cog, LLC
//! \file
#ifndef XPDFWIDGET_H
#define XPDFWIDGET_H
#include
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include
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 /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 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