summaryrefslogtreecommitdiffstats
path: root/webview.cpp
blob: 4e3783d6de11aad4eb3c2b223e858bc3e3258c89 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include "webview.h"
#include <QMouseEvent>
#include <QWebFrame>
#include <QWebHitTestResult>
#include <QWebElement>
#include <QLinearGradient>
#include <QDebug>

WebView::WebView(QGraphicsItem * parent)
        : QGraphicsWebView(parent)
        , m_scrapRect(QRect())
        , m_scrapSelected(false)
{
    setAcceptHoverEvents(true);
}

void WebView::hoverMoveEvent(QGraphicsSceneHoverEvent* event)
{
    if (m_scrapSelected) {
        QGraphicsWebView::hoverMoveEvent(event);
        return;
    }
    QWebFrame* mainFrame = page()->mainFrame();
    if (mainFrame != page()->frameAt(event->pos().toPoint()) ||
        mainFrame->scrollBarGeometry(Qt::Horizontal).contains(event->pos().toPoint()) ||
        mainFrame->scrollBarGeometry(Qt::Vertical).contains(event->pos().toPoint())) {
        m_scrapRect = QRect();
        QGraphicsWebView::hoverMoveEvent(event);
        return;
    }
    QWebElement hitElement = mainFrame->hitTestContent(event->pos().toPoint()).element();
    QRect hitRect = hitElement.geometry();
    if ((event->modifiers() & Qt::ControlModifier) != Qt::ControlModifier) {
        // So we can use Ctrl+Hover to find small items
        while (hitRect.height() < 100 || hitRect.width() < 100) {
            if (hitElement.isNull() || hitElement == mainFrame->documentElement())
                break;
            hitElement = hitElement.parent();
            hitRect = hitElement.geometry();
        }
    }
    if (hitRect.translated(-mainFrame->scrollPosition()).contains(event->pos().toPoint())) {
        m_scrapRect = hitRect;
    } else {
        m_scrapRect = QRect();
    }
    QGraphicsWebView::hoverMoveEvent(event);
    update();
}

void WebView::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    if (page()->mainFrame()->scrollBarGeometry(Qt::Horizontal).contains(event->pos().toPoint()) ||
        page()->mainFrame()->scrollBarGeometry(Qt::Vertical).contains(event->pos().toPoint())) {
        QGraphicsWebView::mousePressEvent(event);
        return;
    }
    if (m_scrapRect.isValid()) {
        if (!m_scrapSelected) {
            m_scrapSelected = true;
            update();
            qDebug() << "selected scrap rect" << m_scrapRect;
        }
    } else {
        QGraphicsWebView::mousePressEvent(event);
        return;
    }
}

void WebView::keyPressEvent(QKeyEvent *event) {
    if (event->key() == Qt::Key_Escape) {
        m_scrapSelected = false;
        update();
    }
}

void WebView::paint(QPainter* painter, const QStyleOptionGraphicsItem* options, QWidget* widget)
{
    QGraphicsWebView::paint(painter, options, widget);

    QPainterPath pageAreaPath, greyedoutPath;
    QPainterPath scrollbars;
    if (page() && page()->mainFrame()) {
        pageAreaPath.addRect(page()->mainFrame()->geometry());
        scrollbars.addRect(page()->mainFrame()->scrollBarGeometry(Qt::Horizontal));
        scrollbars.addRect(page()->mainFrame()->scrollBarGeometry(Qt::Vertical));
        pageAreaPath -= scrollbars;
    }
    greyedoutPath = pageAreaPath;
    if (m_scrapRect.isValid()) {
        QPainterPath scrapPath;
        QRect scrapRect = m_scrapRect.translated(-page()->mainFrame()->scrollPosition());
        scrapPath.addRect(scrapRect);
        greyedoutPath -= scrapPath;
    }
    painter->setClipPath(greyedoutPath);
    painter->setPen(Qt::NoPen);
    painter->setBrush(QBrush(Qt::black));
    painter->setOpacity(0.5);
    painter->drawRect(rect());
    if (m_scrapRect.isValid()) {
        QRect scrapRect = m_scrapRect.translated(-page()->mainFrame()->scrollPosition());
        painter->setClipPath(pageAreaPath);
        painter->setOpacity(1);
        painter->setPen(QPen(Qt::white, 2));
        painter->setBrush(Qt::NoBrush);
        painter->drawRect(scrapRect);
        if (m_scrapSelected) {
            QList<QPoint> nodes;
            nodes << scrapRect.topLeft() << scrapRect.topRight();
            nodes << scrapRect.bottomLeft() << scrapRect.bottomRight();
            nodes << QPoint(scrapRect.center().x(), scrapRect.top());
            nodes << QPoint(scrapRect.center().x(), scrapRect.bottom());
            nodes << QPoint(scrapRect.left(), scrapRect.center().y());
            nodes << QPoint(scrapRect.right(), scrapRect.center().y());
            foreach(QPoint node, nodes) {
                QLinearGradient g(node - QPointF(5, 5), node + QPointF(5, 5));
                g.setColorAt(0, Qt::white);
                g.setColorAt(0.9, Qt::black);
                painter->setBrush(g);
                painter->setPen(Qt::NoPen);
                painter->drawEllipse(node, 5, 5);
            }
        }
    }
}