Add PDFWidget JavaScript API
[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
20 //#include "PDFWidget.mpp"
21 #define prefix_
22 ///////////////////////////////cc.p////////////////////////////////////////
23
24 prefix_ pykit::PDFWidget::PDFWidget(QString const & id, QNetworkAccessManager * manager,
25                                     QWidget * parent)
26     : QLabel(parent), id_ (id), manager_ (manager), currentPage_ (0), dpi_ (96.0), x_ (0), y_ (0)
27
28 {
29     QWebView * webView (dynamic_cast<QWebView*>(parent));
30     if (webView && !id_.isEmpty())
31         webView->page()->mainFrame()->addToJavaScriptWindowObject(id_,this);
32 }
33
34 prefix_ pykit::PDFWidget::PDFWidget(QString const & id, QString const & document,
35                                     QNetworkAccessManager * manager, QWidget * parent)
36     : QLabel(parent), id_ (id), manager_ (manager), currentPage_ (0), dpi_ (96.0), x_ (0), y_ (0)
37
38 {
39     setFocusPolicy(Qt::WheelFocus);
40     document_.reset(Poppler::Document::load(document));
41     QWebView * webView (dynamic_cast<QWebView*>(parent));
42     if (webView && !id_.isEmpty())
43         webView->page()->mainFrame()->addToJavaScriptWindowObject(id_,this);
44     documentSetup();
45 }
46
47 prefix_ void pykit::PDFWidget::load(QUrl const & url)
48 {
49     QNetworkRequest request (url);
50     QNetworkReply * reply (manager_->get(request));
51     connect(reply, SIGNAL(finished()), this, SLOT(netLoadDocument()));
52 }
53
54 prefix_ void pykit::PDFWidget::zoomIn()
55 {
56     zoomMode_ = Manual;
57     double n (dpi_ + ZoomStepDpi);
58     if (n > ZoomMaxDpi)
59         n = ZoomMaxDpi;
60     if (n != dpi_) {
61         dpi_ = n;
62         showPage();
63     }
64 }
65
66 prefix_ void pykit::PDFWidget::zoomOut()
67 {
68     zoomMode_ = Manual;
69     double n (dpi_ - ZoomStepDpi);
70     if (n < ZoomMinDpi)
71         n = ZoomMinDpi;
72     if (n != dpi_) {
73         dpi_ = n;
74         showPage();
75     }
76 }
77
78 prefix_ void pykit::PDFWidget::zoomDPI(double dpi)
79 {
80     zoomMode_ = Manual;
81     if (dpi < ZoomMinDpi)
82         dpi = ZoomMinDpi;
83     if (dpi > ZoomMaxDpi)
84         dpi = ZoomMaxDpi;
85     if (dpi != dpi_) {
86         dpi_ = dpi;
87         showPage();
88     }
89 }
90
91 prefix_ int pykit::PDFWidget::zoomWidth(int w)
92 {
93     zoomMode_ = Width;
94     if (! document_)
95         return 0;
96     if (w == -1)
97         w = width();
98     QSizeF pageSize (document_->page(currentPage_)->pageSizeF());
99     double n = 72.0 * w / pageSize.width();
100     if (n > ZoomMaxDpi)
101         n = ZoomMaxDpi;
102     if (n < ZoomMinDpi)
103         n = ZoomMinDpi;
104     if (n != dpi_) {
105         dpi_ = n;
106         showPage();
107     }
108     return pageSize.height() * dpi_ / 72.0;
109 }
110
111 prefix_ int pykit::PDFWidget::zoomHeight()
112 {
113     zoomMode_ = Height;
114     if (! document_)
115         return 0;
116     QSizeF pageSize (document_->page(currentPage_)->pageSizeF());
117     double n = 72.0 * height() / pageSize.height();
118     if (n > ZoomMaxDpi)
119         n = ZoomMaxDpi;
120     if (n < ZoomMinDpi)
121         n = ZoomMinDpi;
122     if (n != dpi_) {
123         dpi_ = n;
124         showPage();
125     }
126     return pageSize.width() * dpi_ / 72.0;
127 }
128
129 prefix_ void pykit::PDFWidget::zoomFit()
130 {
131     zoomMode_ = Fit;
132     if (! document_)
133         return;
134     QSizeF pageSize (document_->page(currentPage_)->pageSizeF());
135     double xres = 72.0 * width() / pageSize.width();
136     double yres = 72.0 * height() / pageSize.height();
137     double n = xres < yres ? xres : yres;
138     if (n > ZoomMaxDpi)
139         n = ZoomMaxDpi;
140     if (n < ZoomMinDpi)
141         n = ZoomMinDpi;
142     if (n != dpi_) {
143         dpi_ = n;
144         showPage();
145     }
146 }
147
148 prefix_ int pykit::PDFWidget::getPDFWidth()
149 {
150     if (! document_)
151         return 0;
152     QSizeF pageSize (document_->page(currentPage_)->pageSizeF());
153     return pageSize.width() * dpi_ / 72.0;
154 }
155
156 prefix_ int pykit::PDFWidget::getPDFHeight()
157 {
158     if (! document_)
159         return 0;
160     QSizeF pageSize (document_->page(currentPage_)->pageSizeF());
161     return pageSize.height() * dpi_ / 72.0;
162 }
163
164 prefix_ void pykit::PDFWidget::resizeEvent(QResizeEvent *)
165 {
166     switch (zoomMode_) {
167     case Manual:
168         break;
169     case Width:
170         zoomWidth();
171         break;
172     case Height:
173         zoomHeight();
174         break;
175     case Fit:
176         zoomFit();
177         break;
178     }
179     showPage();
180 }
181
182 prefix_ void pykit::PDFWidget::netLoadDocument()
183 {
184     QNetworkReply * reply = static_cast<QNetworkReply*>(sender());
185     if (reply->error() != QNetworkReply::NoError)
186         return;
187     QByteArray data (reply->read(reply->size()));
188     document_.reset(Poppler::Document::loadFromData(data));
189     documentSetup();
190     reply->deleteLater();
191 }
192
193 prefix_ void pykit::PDFWidget::documentSetup()
194 {
195     if (! document_)
196         return;
197     document_->setRenderHint(Poppler::Document::Antialiasing, true);
198     document_->setRenderHint(Poppler::Document::TextAntialiasing, true);
199     document_->setRenderHint(Poppler::Document::TextHinting, false);
200     zoomFit();
201     showPage();
202 }
203
204 prefix_ void pykit::PDFWidget::showPage()
205 {
206     if (! document_)
207         return;
208     QImage image (document_->page(currentPage_)->renderToImage(
209                       dpi_, dpi_, x_, y_, width(), height()));
210     setPixmap(QPixmap::fromImage(image));
211 }
212
213 ///////////////////////////////cc.e////////////////////////////////////////
214 #undef prefix_
215 //#include "PDFWidget.mpp"
216
217 \f
218 // Local Variables:
219 // mode: c++
220 // fill-column: 100
221 // comment-column: 40
222 // c-file-style: "j32"
223 // indent-tabs-mode: nil
224 // ispell-local-dictionary: "american"
225 // compile-command: "make"
226 // End: