aboutsummaryrefslogtreecommitdiff
path: root/src-qt5
diff options
context:
space:
mode:
authorZackaryWelch <welch.zackary@gmail.com>2018-04-04 16:55:48 -0400
committerZackaryWelch <welch.zackary@gmail.com>2018-04-04 16:55:48 -0400
commit0e00960a81337b407898728e01f44373d0537aab (patch)
tree44cad19e23e31052e9741c77ec25338d6475b63b /src-qt5
parentAdded support for internal links. Code added for Poppler backend but not enab... (diff)
downloadlumina-0e00960a81337b407898728e01f44373d0537aab.tar.gz
lumina-0e00960a81337b407898728e01f44373d0537aab.tar.bz2
lumina-0e00960a81337b407898728e01f44373d0537aab.zip
Added propper text annotation handling and changed how links and annotations are shown
Diffstat (limited to 'src-qt5')
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp24
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/PrintWidget.h83
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/Renderer-mupdf.cpp86
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/Renderer-poppler.cpp8
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/Renderer.h3
5 files changed, 166 insertions, 38 deletions
diff --git a/src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp b/src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp
index 73e47091..e9a0ed34 100644
--- a/src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp
+++ b/src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp
@@ -224,22 +224,18 @@ void PrintWidget::populateScene()
for (int i = 0; i < pages.size(); i++){
scene->removeItem(pages.at(i));
}
- for(int i = 0; i < links.size(); i++) {
- if(links[i].size() > 0) {
- qDeleteAll(links[i]);
- links[i].clear();
- }
- }
- links.clear();
qDeleteAll(pages);
pages.clear();
+ //links.clear();
+ //annots.clear();
int numPages = BACKEND->numPages();
if(BACKEND->hashSize() < numPages){ return; } //nothing to show yet
for (int i = 0; i < numPages; i++) {
QImage pagePicture = BACKEND->imageHash(i);
QSize paperSize = pagePicture.size();
- QList<QGraphicsItem*> linkLocations;
+ //QList<QGraphicsItem*> linkLocations;
+ //QList<QGraphicsItem*> annotLocations;
if(pagePicture.isNull()) {
qDebug() << "NULL IMAGE ON PAGE " << i;
@@ -254,9 +250,17 @@ void PrintWidget::populateScene()
for(int k = 0; k < BACKEND->linkSize(i); k++) {
LinkItem *lItem = new LinkItem(item, BACKEND->linkList(i, k));
lItem->setOpacity(0.1);
- linkLocations.append(lItem);
+ //linkLocations.append(lItem);
+ }
+ //qDebug() << "Creating annotations for:" << i;
+ for(int k = 0; k < BACKEND->annotSize(i); k++) {
+ AnnotItem *aItem = new AnnotItem(item, BACKEND->annotList(i, k), BACKEND->annotLoc(i, k));
+ AnnotZone *aZone = new AnnotZone(item, BACKEND->annotLoc(i, k), aItem);
+ aItem->setVisible(false);
+ //annotLocations.append(aItem);
}
- links.insert(i, linkLocations);
+ //links.insert(i, linkLocations);
+ //annots.insert(i, annotLocations);
}
}
}
diff --git a/src-qt5/desktop-utils/lumina-pdf/PrintWidget.h b/src-qt5/desktop-utils/lumina-pdf/PrintWidget.h
index 3860b011..a95af6fa 100644
--- a/src-qt5/desktop-utils/lumina-pdf/PrintWidget.h
+++ b/src-qt5/desktop-utils/lumina-pdf/PrintWidget.h
@@ -19,9 +19,56 @@
#include <QStyleOptionGraphicsItem>
#include <QtMath>
#include <QPageLayout>
+#include <QTextDocument>
#include "Renderer.h"
#include "TextData.h"
+class AnnotItem: public QGraphicsItem {
+public:
+ AnnotItem(QGraphicsItem *parent, QList<QString> textData, QRectF loc) : QGraphicsItem(parent), author(textData[0]), text(textData[1]) {
+ setCacheMode(DeviceCoordinateCache);
+ QString allText = "Author: " + author + "\n\n" + text;
+ QTextDocument document;
+ document.setDefaultFont(QFont("Helvitica", 10, QFont::Normal));
+ document.setPageSize(QSize(120, 120));
+ document.setHtml(allText);
+ loc.moveTopLeft(QPointF(loc.center().x(), loc.center().y()+loc.height()/2));
+ loc.setSize(document.size()+QSize(10, 10));
+ bbox = loc;
+ }
+
+ QRectF boundingRect() const Q_DECL_OVERRIDE { return bbox; }
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(widget);
+ QString allText = "Author: " + author + "\n\n" + text;
+ painter->setClipRect(option->exposedRect);
+ painter->setFont(QFont("Helvitica", 10, QFont::Normal));
+ painter->setBrush(QBrush(QColor(255, 255, 177, 255)));
+ painter->drawRect(bbox);
+ painter->setPen(QPen(QColor("Black")));
+ painter->drawText(bbox, Qt::AlignLeft | Qt::TextWordWrap, allText);
+ }
+
+private:
+ QRectF bbox;
+ QString author;
+ QString text;
+};
+
+class AnnotZone: public QGraphicsItem {
+public:
+ AnnotZone(QGraphicsItem *parent, QRectF _bbox, AnnotItem *_annot) : QGraphicsItem(parent), bbox(_bbox), annot(_annot) { }
+ QRectF boundingRect() const Q_DECL_OVERRIDE { return bbox; }
+ AnnotItem* annotation() const { return annot; }
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) Q_DECL_OVERRIDE { Q_UNUSED(widget); Q_UNUSED(painter); Q_UNUSED(option); }
+
+private:
+ QRectF bbox;
+ AnnotItem *annot;
+};
+
class LinkItem: public QGraphicsItem {
public:
LinkItem(QGraphicsItem *parent, TextData *_data) : QGraphicsItem(parent), bbox(_data->loc()), data(_data) {
@@ -186,24 +233,38 @@ protected:
emit resized();
}
+ void clearItems(QList<QGraphicsItem*> itemList, QGraphicsItem *item) {
+ foreach(QGraphicsItem *graphicsItem, itemList) {
+ if(item == graphicsItem)
+ continue;
+ if(graphicsItem == dynamic_cast<LinkItem*>(graphicsItem))
+ graphicsItem->setOpacity(0.1);
+ if(graphicsItem == dynamic_cast<AnnotItem*>(graphicsItem))
+ graphicsItem->setVisible(false);
+ }
+ }
+
void mouseMoveEvent(QMouseEvent *e) Q_DECL_OVERRIDE {
QGraphicsView::mouseMoveEvent(e);
- QGraphicsItem *item = scene->itemAt(mapToScene(e->pos()), transform());
- if(item) {
- LinkItem *link = dynamic_cast<LinkItem*>(item);
- if(link)
- link->setOpacity(1);
+ if(QGraphicsItem *item = scene->itemAt(mapToScene(e->pos()), transform())) {
QList<QGraphicsItem*> linkList;
+ if(item == dynamic_cast<AnnotItem*>(item))
+ item = item->parentItem();
+
if(PageItem *page = dynamic_cast<PageItem*>(item))
linkList = page->childItems();
else
- linkList = link->parentItem()->childItems();
- foreach(QGraphicsItem *linkItem, linkList) {
- if(dynamic_cast<LinkItem*>(linkItem) == link)
- continue;
- dynamic_cast<LinkItem*>(linkItem)->setOpacity(0.1);
+ linkList = item->parentItem()->childItems();
+
+ if(LinkItem *link = dynamic_cast<LinkItem*>(item)){
+ item->setOpacity(1);
+ }else if(AnnotZone *annotZone = dynamic_cast<AnnotZone*>(item)){
+ annotZone->annotation()->setVisible(true);
+ item = annotZone->annotation();
}
+
+ clearItems(linkList, item);
}
}
@@ -216,7 +277,7 @@ protected:
if(!BACKEND->isExternalLink(page->pageNumber()-1, link->getData()->text())) {
BACKEND->handleLink(link->getData()->text());
}else{
- //Handle external link
+ ExternalLinkDialog
}
link->setOpacity(0.1);
}
diff --git a/src-qt5/desktop-utils/lumina-pdf/Renderer-mupdf.cpp b/src-qt5/desktop-utils/lumina-pdf/Renderer-mupdf.cpp
index 9b2a43f3..31a07e01 100644
--- a/src-qt5/desktop-utils/lumina-pdf/Renderer-mupdf.cpp
+++ b/src-qt5/desktop-utils/lumina-pdf/Renderer-mupdf.cpp
@@ -7,6 +7,29 @@
#include <QFuture>
#include <QtConcurrent>
+class Annot{
+ public:
+ Annot(fz_context *_ctx, pdf_annot *_fzAnnot, char *_text, char *_author, QRectF _loc = QRectF()) : fzAnnot(_fzAnnot), ctx(_ctx), loc(_loc) {
+ author = (_author) ? QString::fromLocal8Bit(_author) : QString();
+ text = (_text) ? QString::fromLocal8Bit(_text) : QString();
+ }
+
+ ~Annot() {
+ fz_drop_annot(ctx, (fz_annot*)fzAnnot);
+ }
+
+ QString getAuthor() { return author; }
+ QString getText() { return text; }
+ QRectF getLoc() { return loc; }
+
+ private:
+ pdf_annot *fzAnnot;
+ fz_context *ctx;
+ QString author;
+ QString text;
+ QRectF loc;
+};
+
class Link {
public:
Link(fz_context *_ctx, fz_link *_fzLink, char *_uri, int _page, QRectF _loc = QRectF()) : fzLink(_fzLink), ctx(_ctx) {
@@ -29,14 +52,15 @@ class Link {
class Data {
public:
- Data(int _pagenum, fz_context *_ctx, fz_display_list *_list, fz_rect _bbox, fz_matrix _ctm, double _sf, fz_link *_link) : pagenumber(_pagenum), ctx(_ctx), list(_list), bbox(_bbox), ctm(_ctm), sf(_sf) {
+ Data(int _pagenum, fz_context *_ctx, fz_display_list *_list, fz_rect _bbox, fz_matrix _ctm, double _sf, fz_link *_link, QList<Annot*> &_annot) : pagenumber(_pagenum), ctx(_ctx), list(_list), bbox(_bbox), ctm(_ctm), sf(_sf), annotList(_annot) {
while(_link) {
QRectF rect(sf*_link->rect.x0, sf*_link->rect.y0, sf*(_link->rect.x1 - _link->rect.x0), sf*(_link->rect.y1 - _link->rect.y0));
Link *link = new Link(_ctx, _link, _link->uri, _pagenum, rect);
- linkList.push_back(link);
+ linkList.append(link);
_link = _link->next;
}
+
}
~Data() {
@@ -44,10 +68,13 @@ class Data {
fz_drop_display_list(ctx, list);
qDeleteAll(linkList);
linkList.clear();
+ qDeleteAll(annotList);
+ annotList.clear();
}
int getPage() { return pagenumber; }
QList<Link*> getLinkList() { return linkList; }
+ QList<Annot*> getAnnotList() { return annotList; }
fz_context* getContext() { return ctx; }
fz_display_list* getDisplayList() { return list; }
QRectF getScaledRect() { return QRectF(sf*bbox.x0, sf*bbox.y0, sf*(bbox.x1-bbox.x0), sf*(bbox.y1 - bbox.y0)); }
@@ -67,6 +94,7 @@ class Data {
fz_matrix ctm;
QList<Link*> linkList;
double sf;
+ QList<Annot*> annotList;
fz_pixmap *pix;
QImage img;
@@ -241,6 +269,7 @@ void renderer(Data *data, Renderer *obj)
fz_drop_device(ctx, dev);
fz_drop_context(ctx);
+ //qDebug() << "Finished rendering:" << pagenum;
emit obj->PageLoaded(pagenum);
}
@@ -251,10 +280,11 @@ void Renderer::renderPage(int pagenum, QSize DPI, int degrees){
fz_rect bbox;
fz_display_list *list;
- double pageDPI = 96.0;
- double sf = DPI.width() / pageDPI;
- fz_scale(&matrix, sf, sf);
- fz_pre_rotate(&matrix, degrees);
+ //double pageDPI = 96.0;
+ //double sf = DPI.width() / pageDPI;
+ double sf = 1;
+ //fz_scale(&matrix, sf, sf);
+ fz_rotate(&matrix, degrees);
fz_page *PAGE = fz_load_page(CTX, DOC, pagenum);
fz_bound_page(CTX, PAGE, &bbox);
@@ -264,25 +294,35 @@ void Renderer::renderPage(int pagenum, QSize DPI, int degrees){
list = fz_new_display_list(CTX, &bbox);
fz_device *dev = fz_new_list_device(CTX, list);
fz_run_page(CTX, PAGE, dev, &fz_identity, NULL);
- fz_annot *annot = fz_first_annot(CTX, PAGE);
- while(annot) {
+ fz_link *link = fz_load_links(CTX, PAGE);
+ pdf_annot *_annot = pdf_first_annot(CTX, (pdf_page*)PAGE);
+ QList<Annot*> annotList;
+
+ //qDebug() << "Starting annotations for:" << pagenum;
+ while(_annot) {
+ pdf_run_annot(CTX, _annot, dev, &fz_identity, NULL);
fz_rect anotBox;
- fz_bound_annot(CTX, annot, &anotBox);
- fz_run_annot(CTX, annot, dev, &matrix, NULL);
-
- QRectF rect(anotBox.x0, anotBox.y0, (anotBox.x1-anotBox.x0), (anotBox.y1 - anotBox.y0));
- qDebug() << "Annotation:" << rect << "at" << pagenum;
- annot = fz_next_annot(CTX, annot);
+ pdf_bound_annot(CTX, _annot, &anotBox);
+ QRectF rect(sf*anotBox.x0, sf*anotBox.y0, sf*(anotBox.x1-anotBox.x0), sf*(anotBox.y1 - anotBox.y0));
+ char *contents = NULL, *author = NULL;
+ fz_try(CTX)
+ contents = pdf_copy_annot_contents(CTX, _annot);
+ fz_catch(CTX) { }
+ fz_try(CTX)
+ author = pdf_copy_annot_author(CTX, _annot);
+ fz_catch(CTX) { }
+
+ Annot *annot = new Annot(CTX, _annot, contents, author, rect);
+ annotList.append(annot);
+ _annot = _annot->next;
}
- fz_link *link = fz_load_links(CTX, PAGE);
-
fz_close_device(CTX, dev);
fz_drop_device(CTX, dev);
fz_drop_page(CTX, PAGE);
- data = new Data(pagenum, CTX, list, bbox, matrix, sf, link);
+ data = new Data(pagenum, CTX, list, bbox, matrix, sf, link, annotList);
data->setRenderThread(QtConcurrent::run(&renderer, data, this));
}
@@ -328,6 +368,18 @@ int Renderer::linkSize(int pagenum) {
return dataHash[pagenum]->getLinkList().size();
}
+QList<QString> Renderer::annotList(int pagenum, int entry) {
+ return QList<QString>() << dataHash[pagenum]->getAnnotList()[entry]->getAuthor() << dataHash[pagenum]->getAnnotList()[entry]->getText();
+}
+
+QRectF Renderer::annotLoc(int pagenum, int entry) {
+ return dataHash[pagenum]->getAnnotList()[entry]->getLoc();
+}
+
+int Renderer::annotSize(int pagenum) {
+ return dataHash[pagenum]->getAnnotList().size();
+}
+
bool Renderer::isExternalLink(int pagenum, QString text) {
QList<Link*> linkList = dataHash[pagenum]->getLinkList();
foreach(Link *link, linkList) {
diff --git a/src-qt5/desktop-utils/lumina-pdf/Renderer-poppler.cpp b/src-qt5/desktop-utils/lumina-pdf/Renderer-poppler.cpp
index 98a351bd..7354cf38 100644
--- a/src-qt5/desktop-utils/lumina-pdf/Renderer-poppler.cpp
+++ b/src-qt5/desktop-utils/lumina-pdf/Renderer-poppler.cpp
@@ -190,8 +190,16 @@ TextData* Renderer::linkList(int pageNum, int entry) {
return 0;
}
+QList<QString> Renderer::annotList(int pageNum, int entry) {
+ return QList<QString>() << QString() << QString();
+}
+
int Renderer::linkSize(int pageNum) { return linkHash[pageNum].size(); }
+int Renderer::annotSize(int pageNum) { return 0; }
+
+QRectF Renderer::annotLoc(int pageNum, int entry) { return QRectF(); }
+
bool Renderer::isExternalLink(int pageNum, QString text) {
Poppler::Link* trueLink;
foreach(QList<Link*> linkArray, linkHash) {
diff --git a/src-qt5/desktop-utils/lumina-pdf/Renderer.h b/src-qt5/desktop-utils/lumina-pdf/Renderer.h
index cc48b089..4dd3e3b1 100644
--- a/src-qt5/desktop-utils/lumina-pdf/Renderer.h
+++ b/src-qt5/desktop-utils/lumina-pdf/Renderer.h
@@ -48,6 +48,9 @@ public:
void handleLink(QString);
TextData *linkList(int, int);
int linkSize(int);
+ QList<QString> annotList(int, int);
+ int annotSize(int);
+ QRectF annotLoc(int, int);
bool isExternalLink(int, QString);
void clearHash();
bgstack15