typo fix
[pykit.git] / PDFWidget.cc
index e27939b..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_
 
 prefix_ pykit::PDFWidget::PDFWidget(QString const & id, QNetworkAccessManager * manager,
                                     QWidget * parent)
-    : QLabel(parent), id_ (id), manager_ (manager), currentPage_ (0), dpi_ (96.0), x_ (0), y_ (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);
+        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), dpi_ (96.0), x_ (0), y_ (0)
+    : 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);
+        webView->page()->mainFrame()->addToJavaScriptWindowObject(id_, this);
     documentSetup();
 }
 
-prefix_ void pykit::PDFWidget::load(QUrl const & url)
-{
-    QNetworkRequest request (url);
-    QNetworkReply * reply (manager_->get(request));
-    connect(reply, SIGNAL(finished()), this, SLOT(netLoadDocument()));
-}
-
-prefix_ void pykit::PDFWidget::zoomIn()
-{
-    zoomMode_ = Manual;
-    double n (dpi_ + ZoomStepDpi);
-    if (n > ZoomMaxDpi)
-        n = ZoomMaxDpi;
-    if (n != dpi_) {
-        dpi_ = n;
-        showPage();
-    }
-}
-
-prefix_ void pykit::PDFWidget::zoomOut()
+prefix_ pykit::PDFWidget::~PDFWidget()
 {
-    zoomMode_ = Manual;
-    double n (dpi_ - ZoomStepDpi);
-    if (n < ZoomMinDpi)
-        n = ZoomMinDpi;
-    if (n != dpi_) {
-        dpi_ = n;
-        showPage();
-    }
+    if (rubberBand_)
+        delete rubberBand_;
 }
 
-prefix_ void pykit::PDFWidget::zoomDPI(double dpi)
-{
-    zoomMode_ = Manual;
-    if (dpi < ZoomMinDpi)
-        dpi = ZoomMinDpi;
-    if (dpi > ZoomMaxDpi)
-        dpi = ZoomMaxDpi;
-    if (dpi != dpi_) {
-        dpi_ = dpi;
-        showPage();
-    }
-}
 
-prefix_ int pykit::PDFWidget::zoomWidth(int w)
-{
-    zoomMode_ = Width;
-    if (! document_)
-        return 0;
-    if (w == -1)
-        w = width();
-    QSizeF pageSize (document_->page(currentPage_)->pageSizeF());
-    double n = 72.0 * w / pageSize.width();
-    if (n > ZoomMaxDpi)
-        n = ZoomMaxDpi;
-    if (n < ZoomMinDpi)
-        n = ZoomMinDpi;
-    if (n != dpi_) {
-        dpi_ = n;
-        showPage();
-    }
-    return pageSize.height() * dpi_ / 72.0;
-}
-
-prefix_ int pykit::PDFWidget::zoomHeight()
+prefix_ void pykit::PDFWidget::load(QUrl const & url)
 {
-    zoomMode_ = Height;
-    if (! document_)
-        return 0;
-    QSizeF pageSize (document_->page(currentPage_)->pageSizeF());
-    double n = 72.0 * height() / pageSize.height();
-    if (n > ZoomMaxDpi)
-        n = ZoomMaxDpi;
-    if (n < ZoomMinDpi)
-        n = ZoomMinDpi;
-    if (n != dpi_) {
-        dpi_ = n;
-        showPage();
-    }
-    return pageSize.width() * dpi_ / 72.0;
+    QNetworkRequest request (url);
+    QNetworkReply * reply (manager_->get(request));
+    connect(reply, SIGNAL(finished()), this, SLOT(netLoadDocument()));
 }
 
-prefix_ void pykit::PDFWidget::zoomFit()
+prefix_ void pykit::PDFWidget::resizeEvent(QResizeEvent *)
 {
-    zoomMode_ = Fit;
     if (! document_)
         return;
     QSizeF pageSize (document_->page(currentPage_)->pageSizeF());
-    double xres = 72.0 * width() / pageSize.width();
-    double yres = 72.0 * height() / pageSize.height();
-    double n = xres < yres ? xres : yres;
-    if (n > ZoomMaxDpi)
-        n = ZoomMaxDpi;
-    if (n < ZoomMinDpi)
-        n = ZoomMinDpi;
+    double n = 72.0 * width() / pageSize.width();
     if (n != dpi_) {
         dpi_ = n;
         showPage();
     }
 }
 
-prefix_ int pykit::PDFWidget::getPDFWidth()
+prefix_ void pykit::PDFWidget::mousePressEvent(QMouseEvent * event)
 {
-    if (! document_)
-        return 0;
-    QSizeF pageSize (document_->page(currentPage_)->pageSizeF());
-    return pageSize.width() * dpi_ / 72.0;
+    origin_ = event->pos();
+    if (! rubberBand_)
+        rubberBand_ = new QRubberBand(QRubberBand::Rectangle, this);
+    rubberBand_->setGeometry(QRect(origin_, QSize()));
+    rubberBand_->show();
 }
 
-prefix_ int pykit::PDFWidget::getPDFHeight()
+prefix_ void pykit::PDFWidget::mouseMoveEvent(QMouseEvent * event)
 {
-    if (! document_)
-        return 0;
-    QSizeF pageSize (document_->page(currentPage_)->pageSizeF());
-    return pageSize.height() * dpi_ / 72.0;
+    if (rubberBand_)
+        rubberBand_->setGeometry(QRect(origin_, event->pos()).normalized());
 }
 
-prefix_ void pykit::PDFWidget::resizeEvent(QResizeEvent *)
+prefix_ void pykit::PDFWidget::mouseReleaseEvent(QMouseEvent *)
 {
-    switch (zoomMode_) {
-    case Manual:
-        break;
-    case Width:
-        zoomWidth();
-        break;
-    case Height:
-        zoomHeight();
-        break;
-    case Fit:
-        zoomFit();
-        break;
+    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);
     }
-    showPage();
 }
 
 prefix_ void pykit::PDFWidget::netLoadDocument()
@@ -197,16 +117,44 @@ prefix_ void pykit::PDFWidget::documentSetup()
     document_->setRenderHint(Poppler::Document::Antialiasing, true);
     document_->setRenderHint(Poppler::Document::TextAntialiasing, true);
     document_->setRenderHint(Poppler::Document::TextHinting, false);
-    zoomFit();
+    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()
 {
     if (! document_)
         return;
     QImage image (document_->page(currentPage_)->renderToImage(
-                      dpi_, dpi_, x_, y_, width(), height()));
+                      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));
 }