typo fix
[pykit.git] / PDFWidget.cc
index a768e4f..02976cd 100644 (file)
 
 // Custom includes
 #include <iostream>
+#include <boost/foreach.hpp>
 #include <QNetworkRequest>
 #include <QNetworkReply>
+#include <QKeyEvent>
+#include <QWebView>
+#include <QWebFrame>
+#include <QApplication>
+#include <QClipboard>
 
 //#include "PDFWidget.mpp"
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
 
-prefix_ pykit::PDFWidget::PDFWidget(QNetworkAccessManager * manager, QWidget * parent)
-    : QLabel(parent), manager_ (manager), currentPage_ (0)
-{}
-
-prefix_ pykit::PDFWidget::PDFWidget(QString const & document, QNetworkAccessManager * manager,
+prefix_ pykit::PDFWidget::PDFWidget(QString const & id, QNetworkAccessManager * manager,
                                     QWidget * parent)
-    : QLabel(parent), manager_ (manager), currentPage_ (0)
+    : QLabel(parent), id_ (id), manager_ (manager), currentPage_ (0), rubberBand_ (0)
+
 {
+    QWebView * webView (dynamic_cast<QWebView*>(parent));
+    if (webView && !id_.isEmpty())
+        webView->page()->mainFrame()->addToJavaScriptWindowObject(id_, this);
+}
+
+prefix_ pykit::PDFWidget::PDFWidget(QString const & id, QString const & document,
+                                    QNetworkAccessManager * manager, QWidget * parent)
+    : QLabel(parent), id_ (id), manager_ (manager), currentPage_ (0), rubberBand_ (0)
+
+{
+    setFocusPolicy(Qt::WheelFocus);
     document_.reset(Poppler::Document::load(document));
+    QWebView * webView (dynamic_cast<QWebView*>(parent));
+    if (webView && !id_.isEmpty())
+        webView->page()->mainFrame()->addToJavaScriptWindowObject(id_, this);
     documentSetup();
-    showPage();
 }
 
+prefix_ pykit::PDFWidget::~PDFWidget()
+{
+    if (rubberBand_)
+        delete rubberBand_;
+}
+
+
 prefix_ void pykit::PDFWidget::load(QUrl const & url)
 {
     QNetworkRequest request (url);
@@ -38,6 +61,44 @@ prefix_ void pykit::PDFWidget::load(QUrl const & url)
     connect(reply, SIGNAL(finished()), this, SLOT(netLoadDocument()));
 }
 
+prefix_ void pykit::PDFWidget::resizeEvent(QResizeEvent *)
+{
+    if (! document_)
+        return;
+    QSizeF pageSize (document_->page(currentPage_)->pageSizeF());
+    double n = 72.0 * width() / pageSize.width();
+    if (n != dpi_) {
+        dpi_ = n;
+        showPage();
+    }
+}
+
+prefix_ void pykit::PDFWidget::mousePressEvent(QMouseEvent * event)
+{
+    origin_ = event->pos();
+    if (! rubberBand_)
+        rubberBand_ = new QRubberBand(QRubberBand::Rectangle, this);
+    rubberBand_->setGeometry(QRect(origin_, QSize()));
+    rubberBand_->show();
+}
+
+prefix_ void pykit::PDFWidget::mouseMoveEvent(QMouseEvent * event)
+{
+    if (rubberBand_)
+        rubberBand_->setGeometry(QRect(origin_, event->pos()).normalized());
+}
+
+prefix_ void pykit::PDFWidget::mouseReleaseEvent(QMouseEvent *)
+{
+    if (rubberBand_) {
+        QMatrix matrix (dpi_ / 72.0, 0, 0, dpi_ / 72.0, 0, 0);
+        QRectF rect (matrix.inverted().mapRect(QRect(rubberBand_->pos(), rubberBand_->size())));
+        QString text = document_->page(currentPage_)->text(rect);
+        if (! text.isEmpty())
+            QApplication::clipboard()->setText(text);
+    }
+}
+
 prefix_ void pykit::PDFWidget::netLoadDocument()
 {
     QNetworkReply * reply = static_cast<QNetworkReply*>(sender());
@@ -46,15 +107,34 @@ prefix_ void pykit::PDFWidget::netLoadDocument()
     QByteArray data (reply->read(reply->size()));
     document_.reset(Poppler::Document::loadFromData(data));
     documentSetup();
-    showPage();
     reply->deleteLater();
 }
 
 prefix_ void pykit::PDFWidget::documentSetup()
 {
+    if (! document_)
+        return;
     document_->setRenderHint(Poppler::Document::Antialiasing, true);
     document_->setRenderHint(Poppler::Document::TextAntialiasing, true);
     document_->setRenderHint(Poppler::Document::TextHinting, false);
+    resizeEvent(0);
+    Poppler::Page::SearchDirection dir (Poppler::Page::FromTop);
+    highlightAreas_.clear();
+    BOOST_FOREACH(QString const & str, highlightStrings_) {
+        QRectF highlightArea;
+        while (document_->page(currentPage_)->search(str, highlightArea, dir,
+                                                     Poppler::Page::CaseInsensitive)) {
+            highlightAreas_.push_back(highlightArea);
+            dir = Poppler::Page::NextResult;
+        }
+    }
+    showPage();
+}
+
+prefix_ void pykit::PDFWidget::highlightString(QString const & str)
+{
+    highlightStrings_.append(str);
+    documentSetup();
 }
 
 prefix_ void pykit::PDFWidget::showPage()
@@ -62,7 +142,19 @@ prefix_ void pykit::PDFWidget::showPage()
     if (! document_)
         return;
     QImage image (document_->page(currentPage_)->renderToImage(
-                      physicalDpiX(), physicalDpiY()));
+                      dpi_, dpi_, 0, 0, width(), height()));
+    QMatrix matrix (dpi_ / 72.0, 0, 0, dpi_ / 72.0, 0, 0);
+
+    QPainter painter;
+    painter.begin(&image);
+    painter.setCompositionMode(QPainter::CompositionMode_Darken);
+    BOOST_FOREACH(QRectF const & highlightArea, highlightAreas_) {
+        QRect highlightRect = matrix.mapRect(highlightArea).toRect();
+        highlightRect.adjust(-2, -2, 2, 1);
+        painter.fillRect(highlightRect, QColor(244, 229, 0));
+    }
+    painter.end();
+
     setPixmap(QPixmap::fromImage(image));
 }
 
@@ -78,5 +170,5 @@ prefix_ void pykit::PDFWidget::showPage()
 // c-file-style: "j32"
 // indent-tabs-mode: nil
 // ispell-local-dictionary: "american"
-// compile-command: "scons -U"
+// compile-command: "make"
 // End: