summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/pdf/qpdflink.cpp37
-rw-r--r--src/pdf/qpdflink.h6
-rw-r--r--src/pdf/qpdflink_p.h2
-rw-r--r--src/pdf/qpdflinkmodel.cpp59
-rw-r--r--src/pdf/qpdflinkmodel_p.h3
-rw-r--r--src/pdf/qpdflinkmodel_p_p.h18
-rw-r--r--src/pdfquick/qquickpdflinkmodel_p.h8
7 files changed, 74 insertions, 59 deletions
diff --git a/src/pdf/qpdflink.cpp b/src/pdf/qpdflink.cpp
index 091a29729..94d4e741d 100644
--- a/src/pdf/qpdflink.cpp
+++ b/src/pdf/qpdflink.cpp
@@ -39,6 +39,8 @@
#include "qpdflink.h"
#include "qpdflink_p.h"
+#include "qpdflinkmodel_p.h"
+#include <QGuiApplication>
QT_BEGIN_NAMESPACE
@@ -126,6 +128,17 @@ qreal QPdfLink::zoom() const
}
/*!
+ \property QPdfLink::url
+
+ This property holds the destination URL if the link is an external hyperlink;
+ otherwise, it's empty.
+*/
+QUrl QPdfLink::url() const
+{
+ return d->url;
+}
+
+/*!
\property QPdfLink::contextBefore
This property holds adjacent text found on the page before the search string.
@@ -167,6 +180,30 @@ QList<QRectF> QPdfLink::rectangles() const
return d->rects;
}
+/*!
+ Returns a translated representation for display.
+
+ \sa copyToClipboard()
+*/
+QString QPdfLink::toString() const
+{
+ static const QString format = QPdfLinkModel::tr("page %1 location %2,%3 zoom %4");
+ return d->page > 0 ? format.arg(QString::number(d->page),
+ QString::number(d->location.x()),
+ QString::number(d->location.y()),
+ QString::number(d->zoom))
+ : d->url.toString();
+}
+
+/*!
+ Copies the toString() representation of the link to the
+ \l {QGuiApplication::clipboard()}{system clipboard} depending on the \a mode given.
+*/
+void QPdfLink::copyToClipboard(QClipboard::Mode mode) const
+{
+ QGuiApplication::clipboard()->setText(toString(), mode);
+}
+
QDebug operator<<(QDebug dbg, const QPdfLink &link)
{
QDebugStateSaver saver(dbg);
diff --git a/src/pdf/qpdflink.h b/src/pdf/qpdflink.h
index 22de24063..64185554b 100644
--- a/src/pdf/qpdflink.h
+++ b/src/pdf/qpdflink.h
@@ -47,6 +47,7 @@
#include <QtCore/qpoint.h>
#include <QtCore/qrect.h>
#include <QtCore/qshareddata.h>
+#include <QtGui/qclipboard.h>
QT_BEGIN_NAMESPACE
@@ -59,6 +60,7 @@ class QPdfLink
Q_PROPERTY(int page READ page)
Q_PROPERTY(QPointF location READ location)
Q_PROPERTY(qreal zoom READ zoom)
+ Q_PROPERTY(QUrl url READ url)
Q_PROPERTY(QString contextBefore READ contextBefore)
Q_PROPERTY(QString contextAfter READ contextAfter)
Q_PROPERTY(QList<QRectF> rectangles READ rectangles)
@@ -78,15 +80,19 @@ public:
Q_PDF_EXPORT int page() const;
Q_PDF_EXPORT QPointF location() const;
Q_PDF_EXPORT qreal zoom() const;
+ Q_PDF_EXPORT QUrl url() const;
Q_PDF_EXPORT QString contextBefore() const;
Q_PDF_EXPORT QString contextAfter() const;
Q_PDF_EXPORT QList<QRectF> rectangles() const;
+ Q_PDF_EXPORT Q_INVOKABLE QString toString() const;
+ Q_PDF_EXPORT Q_INVOKABLE void copyToClipboard(QClipboard::Mode mode = QClipboard::Clipboard) const;
private: // methods
QPdfLink(int page, QPointF location, qreal zoom);
QPdfLink(int page, QList<QRectF> rects, QString contextBefore, QString contextAfter);
QPdfLink(QPdfLinkPrivate *d);
friend class QPdfDocument;
+ friend class QPdfLinkModelPrivate;
friend class QPdfSearchModelPrivate;
friend class QPdfPageNavigator;
friend class QQuickPdfPageNavigator;
diff --git a/src/pdf/qpdflink_p.h b/src/pdf/qpdflink_p.h
index 7cda6edfc..4acfc4182 100644
--- a/src/pdf/qpdflink_p.h
+++ b/src/pdf/qpdflink_p.h
@@ -55,6 +55,7 @@
#include <QPointF>
#include <QRectF>
+#include <QUrl>
QT_BEGIN_NAMESPACE
@@ -79,6 +80,7 @@ public:
qreal zoom = 1;
QString contextBefore;
QString contextAfter;
+ QUrl url;
QList<QRectF> rects;
};
diff --git a/src/pdf/qpdflinkmodel.cpp b/src/pdf/qpdflinkmodel.cpp
index fba9c23c4..4997cd314 100644
--- a/src/pdf/qpdflinkmodel.cpp
+++ b/src/pdf/qpdflinkmodel.cpp
@@ -37,6 +37,7 @@
**
****************************************************************************/
+#include "qpdflink_p.h"
#include "qpdflinkmodel_p.h"
#include "qpdflinkmodel_p_p.h"
#include "qpdfdocument_p.h"
@@ -76,18 +77,20 @@ int QPdfLinkModel::rowCount(const QModelIndex &parent) const
QVariant QPdfLinkModel::data(const QModelIndex &index, int role) const
{
Q_D(const QPdfLinkModel);
- const QPdfLinkModelPrivate::Link &link = d->links.at(index.row());
+ const auto &link = d->links.at(index.row());
switch (Role(role)) {
+ case Role::Link:
+ return QVariant::fromValue(link);
case Role::Rect:
- return link.rect;
+ return link.rectangles().empty() ? QVariant() : link.rectangles().constFirst();
case Role::Url:
- return link.url;
+ return link.url();
case Role::Page:
- return link.page;
+ return link.page();
case Role::Location:
- return link.location;
+ return link.location();
case Role::Zoom:
- return link.zoom;
+ return link.zoom();
case Role::_Count:
break;
}
@@ -169,16 +172,16 @@ void QPdfLinkModelPrivate::update()
qCWarning(qLcLink) << "skipping link with invalid bounding box";
continue; // while enumerating links
}
- Link linkData;
- linkData.rect = QRectF(rect.left, pageHeight - rect.top,
+ QPdfLink linkData;
+ linkData.d->rects << QRectF(rect.left, pageHeight - rect.top,
rect.right - rect.left, rect.top - rect.bottom);
FPDF_DEST dest = FPDFLink_GetDest(doc, linkAnnot);
FPDF_ACTION action = FPDFLink_GetAction(linkAnnot);
switch (FPDFAction_GetType(action)) {
case PDFACTION_UNSUPPORTED: // this happens with valid links in some PDFs
case PDFACTION_GOTO: {
- linkData.page = FPDFDest_GetDestPageIndex(doc, dest);
- if (linkData.page < 0) {
+ linkData.d->page = FPDFDest_GetDestPageIndex(doc, dest);
+ if (linkData.d->page < 0) {
qCWarning(qLcLink) << "skipping link with invalid page number";
continue; // while enumerating links
}
@@ -186,25 +189,25 @@ void QPdfLinkModelPrivate::update()
FS_FLOAT x, y, zoom;
ok = FPDFDest_GetLocationInPage(dest, &hasX, &hasY, &hasZoom, &x, &y, &zoom);
if (!ok) {
- qCWarning(qLcLink) << "link with invalid location and/or zoom @" << linkData.rect;
+ qCWarning(qLcLink) << "link with invalid location and/or zoom @" << linkData.d->rects;
break; // at least we got a page number, so the link will jump there
}
if (hasX && hasY)
- linkData.location = QPointF(x, pageHeight - y);
+ linkData.d->location = QPointF(x, pageHeight - y);
if (hasZoom)
- linkData.zoom = zoom;
+ linkData.d->zoom = zoom;
break;
}
case PDFACTION_URI: {
unsigned long len = FPDFAction_GetURIPath(doc, action, nullptr, 0);
if (len < 1) {
- qCWarning(qLcLink) << "skipping link with empty URI @" << linkData.rect;
+ qCWarning(qLcLink) << "skipping link with empty URI @" << linkData.d->rects;
continue; // while enumerating links
} else {
QByteArray buf(len, 0);
unsigned long got = FPDFAction_GetURIPath(doc, action, buf.data(), len);
Q_ASSERT(got == len);
- linkData.url = QString::fromLatin1(buf.data(), got - 1);
+ linkData.d->url = QString::fromLatin1(buf.data(), got - 1);
}
break;
}
@@ -212,13 +215,13 @@ void QPdfLinkModelPrivate::update()
case PDFACTION_REMOTEGOTO: {
unsigned long len = FPDFAction_GetFilePath(action, nullptr, 0);
if (len < 1) {
- qCWarning(qLcLink) << "skipping link with empty file path @" << linkData.rect;
+ qCWarning(qLcLink) << "skipping link with empty file path @" << linkData.d->rects;
continue; // while enumerating links
} else {
QByteArray buf(len, 0);
unsigned long got = FPDFAction_GetFilePath(action, buf.data(), len);
Q_ASSERT(got == len);
- linkData.url = QUrl::fromLocalFile(QString::fromLatin1(buf.data(), got - 1)).toString();
+ linkData.d->url = QUrl::fromLocalFile(QString::fromLatin1(buf.data(), got - 1)).toString();
// Unfortunately, according to comments in fpdf_doc.h, if it's PDFACTION_REMOTEGOTO,
// we can't get the page and location without first opening the linked document
@@ -237,7 +240,7 @@ void QPdfLinkModelPrivate::update()
if (webLinks) {
int count = FPDFLink_CountWebLinks(webLinks);
for (int i = 0; i < count; ++i) {
- Link linkData;
+ QPdfLink linkData;
int len = FPDFLink_GetURL(webLinks, i, nullptr, 0);
if (len < 1) {
qCWarning(qLcLink) << "skipping link" << i << "with empty URL";
@@ -245,16 +248,15 @@ void QPdfLinkModelPrivate::update()
QList<unsigned short> buf(len);
int got = FPDFLink_GetURL(webLinks, i, buf.data(), len);
Q_ASSERT(got == len);
- linkData.url = QString::fromUtf16(
+ linkData.d->url = QString::fromUtf16(
reinterpret_cast<const char16_t *>(buf.data()), got - 1);
}
- FPDFLink_GetTextRange(webLinks, i, &linkData.textStart, &linkData.textCharCount);
len = FPDFLink_CountRects(webLinks, i);
for (int r = 0; r < len; ++r) {
double left, top, right, bottom;
bool success = FPDFLink_GetRect(webLinks, i, r, &left, &top, &right, &bottom);
if (success) {
- linkData.rect = QRectF(left, pageHeight - top, right - left, top - bottom);
+ linkData.d->rects << QRectF(left, pageHeight - top, right - left, top - bottom);
links << linkData;
}
}
@@ -267,8 +269,8 @@ void QPdfLinkModelPrivate::update()
// All done
FPDF_ClosePage(pdfPage);
if (Q_UNLIKELY(qLcLink().isDebugEnabled())) {
- for (const Link &l : links)
- qCDebug(qLcLink) << l.rect << l.toString();
+ for (const auto &l : links)
+ qCDebug(qLcLink) << l;
}
q->endResetModel();
}
@@ -281,17 +283,6 @@ void QPdfLinkModel::onStatusChanged(QPdfDocument::Status status)
d->update();
}
-QString QPdfLinkModelPrivate::Link::toString() const
-{
- QString ret;
- if (page >= 0)
- return QLatin1String("page ") + QString::number(page) +
- QLatin1String(" location ") + QString::number(location.x()) + QLatin1Char(',') + QString::number(location.y()) +
- QLatin1String(" zoom ") + QString::number(zoom);
- else
- return url.toString();
-}
-
QT_END_NAMESPACE
#include "moc_qpdflinkmodel_p.cpp"
diff --git a/src/pdf/qpdflinkmodel_p.h b/src/pdf/qpdflinkmodel_p.h
index 495370fe1..35fa28dcd 100644
--- a/src/pdf/qpdflinkmodel_p.h
+++ b/src/pdf/qpdflinkmodel_p.h
@@ -69,7 +69,8 @@ class Q_PDF_EXPORT QPdfLinkModel : public QAbstractListModel
public:
enum class Role : int {
- Rect = Qt::UserRole,
+ Link = Qt::UserRole,
+ Rect,
Url,
Page,
Location,
diff --git a/src/pdf/qpdflinkmodel_p_p.h b/src/pdf/qpdflinkmodel_p_p.h
index 14c8bc734..276a49fe9 100644
--- a/src/pdf/qpdflinkmodel_p_p.h
+++ b/src/pdf/qpdflinkmodel_p_p.h
@@ -52,6 +52,7 @@
//
#include "qpdflinkmodel_p.h"
+#include "qpdflink.h"
#include <private/qabstractitemmodel_p.h>
#include "third_party/pdfium/public/fpdfview.h"
@@ -69,23 +70,8 @@ public:
void update();
- struct Link {
- // where it is on the current page
- QRectF rect;
- int textStart = -1;
- int textCharCount = 0;
- // destination inside PDF
- int page = -1; // -1 means look at the url instead
- QPointF location;
- qreal zoom = 0; // 0 means no specified zoom: don't change when clicking
- // web destination
- QUrl url;
-
- QString toString() const;
- };
-
QPdfDocument *document = nullptr;
- QList<Link> links;
+ QList<QPdfLink> links;
int page = 0;
};
diff --git a/src/pdfquick/qquickpdflinkmodel_p.h b/src/pdfquick/qquickpdflinkmodel_p.h
index 156444828..153639e43 100644
--- a/src/pdfquick/qquickpdflinkmodel_p.h
+++ b/src/pdfquick/qquickpdflinkmodel_p.h
@@ -73,16 +73,8 @@ public:
QQuickPdfDocument *document() const;
void setDocument(QQuickPdfDocument *document);
-signals:
- void documentChanged();
-
-private:
- void updateResults();
-
private:
QQuickPdfDocument *m_quickDocument;
- QList<QPolygonF> m_linksGeometry;
-
Q_DISABLE_COPY(QQuickPdfLinkModel)
};