PDF cut-and-paste
[pykit.git] / PDFWidget.cc
1 // $Id$
2 //
3 // Copyright (C) 2010
4 //     Stefan Bund <info@j32.de>
5
6 /** \file
7     \brief PDFWidget non-inline non-template implementation */
8
9 #include "PDFWidget.hh"
10 //#include "PDFWidget.ih"
11
12 // Custom includes
13 #include <iostream>
14 #include <QNetworkRequest>
15 #include <QNetworkReply>
16 #include <QKeyEvent>
17 #include <QWebView>
18 #include <QWebFrame>
19 #include <QApplication>
20 #include <QClipboard>
21
22 //#include "PDFWidget.mpp"
23 #define prefix_
24 ///////////////////////////////cc.p////////////////////////////////////////
25
26 prefix_ pykit::PDFWidget::PDFWidget(QString const & id, QNetworkAccessManager * manager,
27                                     QWidget * parent)
28     : QLabel(parent), id_ (id), manager_ (manager), currentPage_ (0), rubberBand_ (0)
29
30 {
31     QWebView * webView (dynamic_cast<QWebView*>(parent));
32     if (webView && !id_.isEmpty())
33         webView->page()->mainFrame()->addToJavaScriptWindowObject(id_,this);
34 }
35
36 prefix_ pykit::PDFWidget::PDFWidget(QString const & id, QString const & document,
37                                     QNetworkAccessManager * manager, QWidget * parent)
38     : QLabel(parent), id_ (id), manager_ (manager), currentPage_ (0), rubberBand_ (0)
39
40 {
41     setFocusPolicy(Qt::WheelFocus);
42     document_.reset(Poppler::Document::load(document));
43     QWebView * webView (dynamic_cast<QWebView*>(parent));
44     if (webView && !id_.isEmpty())
45         webView->page()->mainFrame()->addToJavaScriptWindowObject(id_,this);
46     documentSetup();
47 }
48
49 prefix_ pykit::PDFWidget::~PDFWidget()
50 {
51     if (rubberBand_)
52         delete rubberBand_;
53 }
54
55
56 prefix_ void pykit::PDFWidget::load(QUrl const & url)
57 {
58     QNetworkRequest request (url);
59     QNetworkReply * reply (manager_->get(request));
60     connect(reply, SIGNAL(finished()), this, SLOT(netLoadDocument()));
61 }
62
63 prefix_ void pykit::PDFWidget::resizeEvent(QResizeEvent *)
64 {
65     if (! document_)
66         return;
67     QSizeF pageSize (document_->page(currentPage_)->pageSizeF());
68     double n = 72.0 * width() / pageSize.width();
69     if (n != dpi_) {
70         dpi_ = n;
71         showPage();
72     }
73 }
74
75 prefix_ void pykit::PDFWidget::mousePressEvent(QMouseEvent * event)
76 {
77     origin_ = event->pos();
78     if (! rubberBand_)
79         rubberBand_ = new QRubberBand(QRubberBand::Rectangle, this);
80     rubberBand_->setGeometry(QRect(origin_, QSize()));
81     rubberBand_->show();
82 }
83
84 prefix_ void pykit::PDFWidget::mouseMoveEvent(QMouseEvent * event)
85 {
86     if (rubberBand_)
87         rubberBand_->setGeometry(QRect(origin_, event->pos()).normalized());
88 }
89
90 prefix_ void pykit::PDFWidget::mouseReleaseEvent(QMouseEvent * event)
91 {
92     if (rubberBand_) {
93         QMatrix matrix (dpi_ / 72.0, 0, 0, dpi_ / 72.0, 0, 0);
94         QRectF rect (matrix.inverted().mapRect(QRect(rubberBand_->pos(), rubberBand_->size())));
95         QString text = document_->page(currentPage_)->text(rect);
96         if (! text.isEmpty())
97             QApplication::clipboard()->setText(text);
98     }
99 }
100
101 prefix_ void pykit::PDFWidget::netLoadDocument()
102 {
103     QNetworkReply * reply = static_cast<QNetworkReply*>(sender());
104     if (reply->error() != QNetworkReply::NoError)
105         return;
106     QByteArray data (reply->read(reply->size()));
107     document_.reset(Poppler::Document::loadFromData(data));
108     documentSetup();
109     reply->deleteLater();
110 }
111
112 prefix_ void pykit::PDFWidget::documentSetup()
113 {
114     if (! document_)
115         return;
116     document_->setRenderHint(Poppler::Document::Antialiasing, true);
117     document_->setRenderHint(Poppler::Document::TextAntialiasing, true);
118     document_->setRenderHint(Poppler::Document::TextHinting, false);
119     resizeEvent(0);
120     showPage();
121 }
122
123 prefix_ void pykit::PDFWidget::showPage()
124 {
125     if (! document_)
126         return;
127     QImage image (document_->page(currentPage_)->renderToImage(
128                       dpi_, dpi_, 0, 0, width(), height()));
129     setPixmap(QPixmap::fromImage(image));
130 }
131
132 ///////////////////////////////cc.e////////////////////////////////////////
133 #undef prefix_
134 //#include "PDFWidget.mpp"
135
136 \f
137 // Local Variables:
138 // mode: c++
139 // fill-column: 100
140 // comment-column: 40
141 // c-file-style: "j32"
142 // indent-tabs-mode: nil
143 // ispell-local-dictionary: "american"
144 // compile-command: "make"
145 // End: