00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <QtGui/QApplication>
00021 #include <QtGui/QGraphicsSceneContextMenuEvent>
00022 #include <QtGui/QGraphicsSceneDragDropEvent>
00023 #include <QtGui/QGraphicsSceneMouseEvent>
00024 #include <QtGui/QGraphicsSceneWheelEvent>
00025 #include <QtGui/QKeyEvent>
00026 #include <QtGui/QStyleOptionGraphicsItem>
00027
00028 #include <fixx11h.h>
00029 #include <QtWebKit/QWebFrame>
00030 #include <QtWebKit/QWebPage>
00031
00032 #include <QtCore/QTimer>
00033
00034 #include <kdebug.h>
00035 #include <accessmanager.h>
00036
00037 #include "plasma/widgets/webview.h"
00038
00039 namespace Plasma
00040 {
00041
00042 class WebViewPrivate
00043 {
00044 public:
00045 WebViewPrivate(WebView *parent)
00046 : q(parent),
00047 dragToScroll(false),
00048 dragging(false),
00049 dragTimeout(false),
00050 dragTimeoutTimer(0)
00051 {
00052 }
00053
00054 void loadingFinished(bool success);
00055 void updateRequested(const QRect &dirtyRect);
00056 void scrollRequested(int dx, int dy, const QRect &scrollRect);
00057 void dragTimeoutExpired();
00058
00059 WebView *q;
00060 QWebPage *page;
00061 bool loaded;
00062 bool dragToScroll;
00063 bool dragging;
00064 bool dragTimeout;
00065 QTimer *dragTimeoutTimer;
00066 };
00067
00068 WebView::WebView(QGraphicsItem *parent)
00069 : QGraphicsWidget(parent),
00070 d(new WebViewPrivate(this))
00071 {
00072 d->page = 0;
00073 d->loaded = false;
00074 setAcceptsHoverEvents(true);
00075 setFlags(QGraphicsItem::ItemIsFocusable);
00076
00077 QWebPage *page = new QWebPage(this);
00078 page->setNetworkAccessManager(new KIO::AccessManager(page));
00079 QPalette palette = qApp->palette();
00080 palette.setBrush(QPalette::Base, Qt::transparent);
00081 page->setPalette(palette);
00082 setPage(page);
00083 }
00084
00085 WebView::~WebView()
00086 {
00087 delete d;
00088 }
00089
00090 void WebView::setUrl(const KUrl &url)
00091 {
00092 d->loaded = false;
00093 if (d->page) {
00094 d->page->mainFrame()->load(url);
00095 }
00096 }
00097
00098 KUrl WebView::url() const
00099 {
00100 return d->page ? d->page->mainFrame()->url() : KUrl();
00101 }
00102
00103 void WebView::setHtml(const QByteArray &html, const KUrl &baseUrl)
00104 {
00105 d->loaded = false;
00106 if (d->page) {
00107 d->page->mainFrame()->setContent(html, QString(), baseUrl);
00108 }
00109 }
00110
00111 void WebView::setHtml(const QString &html, const KUrl &baseUrl)
00112 {
00113 d->loaded = false;
00114 if (d->page) {
00115 d->page->mainFrame()->setHtml(html, baseUrl);
00116 }
00117 }
00118
00119 QString WebView::html() const
00120 {
00121 return d->page ? d->page->mainFrame()->toHtml() : QByteArray();
00122 }
00123
00124 QRectF WebView::geometry() const
00125 {
00126 if (d->loaded && d->page) {
00127 return d->page->mainFrame()->geometry();
00128 }
00129
00130 return QGraphicsWidget::geometry();
00131 }
00132
00133 void WebView::setPage(QWebPage *page)
00134 {
00135 if (page == d->page) {
00136 return;
00137 }
00138
00139 if (d->page) {
00140 if (d->page->parent() == this) {
00141 delete d->page;
00142 } else {
00143 disconnect(d->page, 0, this, 0);
00144 }
00145 }
00146
00147 d->page = page;
00148
00149 if (d->page) {
00150 connect(d->page, SIGNAL(loadProgress(int)),
00151 this, SIGNAL(loadProgress(int)));
00152 connect(d->page, SIGNAL(loadFinished(bool)),
00153 this, SLOT(loadingFinished(bool)));
00154 connect(d->page, SIGNAL(repaintRequested(const QRect&)),
00155 this, SLOT(updateRequested(const QRect&)));
00156 connect(d->page, SIGNAL(scrollRequested(int, int, const QRect &)),
00157 this, SLOT(scrollRequested(int, int, const QRect &)));
00158 }
00159 }
00160
00161 QWebPage *WebView::page() const
00162 {
00163 return d->page;
00164 }
00165
00166 QWebFrame *WebView::mainFrame() const
00167 {
00168 return d->page ? d->page->mainFrame() : 0;
00169 }
00170
00171 void WebView::setDragToScroll(bool drag)
00172 {
00173 d->dragToScroll = drag;
00174 }
00175
00176 bool WebView::dragToScroll()
00177 {
00178 return d->dragToScroll;
00179 }
00180
00181 void WebView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
00182 {
00183 Q_UNUSED(widget)
00184
00185 if (d->loaded && d->page) {
00186
00187 d->page->mainFrame()->render(painter, option->rect);
00188 }
00189 }
00190
00191 void WebView::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
00192 {
00193 if (!d->page) {
00194 QGraphicsWidget::mouseMoveEvent(event);
00195 return;
00196 }
00197
00198 if (d->dragToScroll && d->dragTimeout) {
00199 QPointF deltaPos = event->pos() - event->lastPos();
00200 d->page->mainFrame()->setScrollBarValue(Qt::Horizontal, d->page->mainFrame()->scrollBarValue(Qt::Horizontal) - deltaPos.x());
00201 d->page->mainFrame()->setScrollBarValue(Qt::Vertical, d->page->mainFrame()->scrollBarValue(Qt::Vertical) - deltaPos.y());
00202 d->dragging = true;
00203 } else {
00204 if (d->dragTimeoutTimer) {
00205 d->dragTimeoutTimer->stop();
00206 }
00207 QMouseEvent me(QEvent::MouseMove, event->pos().toPoint(), event->button(),
00208 event->buttons(), event->modifiers());
00209 d->page->event(&me);
00210 if (me.isAccepted()) {
00211 event->accept();
00212 }
00213 }
00214 }
00215
00216 void WebView::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
00217 {
00218 if (!d->page) {
00219 QGraphicsWidget::hoverMoveEvent(event);
00220 return;
00221 }
00222
00223 QMouseEvent me(QEvent::MouseMove, event->pos().toPoint(), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
00224 d->page->event(&me);
00225 if (me.isAccepted()) {
00226 event->accept();
00227 }
00228 }
00229
00230 void WebView::mousePressEvent(QGraphicsSceneMouseEvent *event)
00231 {
00232 if (!d->page) {
00233 QGraphicsWidget::mousePressEvent(event);
00234 return;
00235 }
00236
00237 d->dragTimeout = false;
00238 if (!d->dragTimeoutTimer) {
00239 d->dragTimeoutTimer = new QTimer(this);
00240 d->dragTimeoutTimer->setSingleShot(true);
00241 connect(d->dragTimeoutTimer, SIGNAL(timeout()), this, SLOT(dragTimeoutExpired()));
00242 }
00243 d->dragTimeoutTimer->start(250);
00244
00245 setFocus();
00246
00247 QMouseEvent me(QEvent::MouseButtonPress, event->pos().toPoint(), event->button(),
00248 event->buttons(), event->modifiers());
00249 d->page->event(&me);
00250 if (me.isAccepted()) {
00251 event->accept();
00252 }
00253 }
00254
00255 void WebView::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
00256 {
00257 if (!d->page) {
00258 QGraphicsWidget::mouseDoubleClickEvent(event);
00259 return;
00260 }
00261
00262 QMouseEvent me(QEvent::MouseButtonDblClick, event->pos().toPoint(), event->button(),
00263 event->buttons(), event->modifiers());
00264 d->page->event(&me);
00265 if (me.isAccepted()) {
00266 event->accept();
00267 }
00268 }
00269
00270 void WebView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
00271 {
00272 if (!d->page || d->dragging) {
00273 d->dragging = false;
00274 QGraphicsWidget::mouseReleaseEvent(event);
00275 return;
00276 }
00277
00278 QMouseEvent me(QEvent::MouseButtonRelease, event->pos().toPoint(), event->button(),
00279 event->buttons(), event->modifiers());
00280 d->page->event(&me);
00281 if (me.isAccepted()) {
00282 event->accept();
00283 }
00284 }
00285
00286 void WebView::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
00287 {
00288 if (!d->page) {
00289 QGraphicsWidget::contextMenuEvent(event);
00290 return;
00291 }
00292
00293 QContextMenuEvent ce(static_cast<QContextMenuEvent::Reason>(event->reason()),
00294 event->pos().toPoint(), event->screenPos());
00295
00296 if (d->page->swallowContextMenuEvent(&ce)) {
00297 event->accept();
00298 } else {
00299 d->page->updatePositionDependentActions(event->pos().toPoint());
00300
00301 d->page->event(&ce);
00302 if (ce.isAccepted()) {
00303 event->accept();
00304 }
00305 }
00306 }
00307
00308 void WebView::wheelEvent(QGraphicsSceneWheelEvent *event)
00309 {
00310 if (!d->page) {
00311 QGraphicsWidget::wheelEvent(event);
00312 return;
00313 }
00314
00315 QWheelEvent we(event->pos().toPoint(), event->delta(), event->buttons(),
00316 event->modifiers(), event->orientation());
00317
00318 d->page->event(&we);
00319
00320 if (we.isAccepted()) {
00321 event->accept();
00322 } else {
00323 QGraphicsWidget::wheelEvent(event);
00324 }
00325 }
00326
00327 void WebView::keyPressEvent(QKeyEvent * event)
00328 {
00329 if (!d->page) {
00330 QGraphicsWidget::keyPressEvent(event);
00331 return;
00332 }
00333
00334 d->page->event(event);
00335
00336 if (!event->isAccepted()) {
00337 QGraphicsWidget::keyPressEvent(event);
00338 }
00339 }
00340
00341 void WebView::keyReleaseEvent(QKeyEvent * event)
00342 {
00343 if (!d->page) {
00344 QGraphicsWidget::keyReleaseEvent(event);
00345 return;
00346 }
00347
00348 d->page->event(event);
00349
00350 if (!event->isAccepted()) {
00351 QGraphicsWidget::keyPressEvent(event);
00352 }
00353 }
00354
00355 void WebView::focusInEvent(QFocusEvent * event)
00356 {
00357 if (d->page) {
00358 d->page->event(event);
00359 }
00360
00361 QGraphicsWidget::focusInEvent(event);
00362 }
00363
00364 void WebView::focusOutEvent(QFocusEvent * event)
00365 {
00366 if (d->page) {
00367 d->page->event(event);
00368 }
00369
00370 QGraphicsWidget::focusOutEvent(event);
00371 }
00372
00373 void WebView::dragEnterEvent(QGraphicsSceneDragDropEvent * event)
00374 {
00375 if (!d->page) {
00376 QGraphicsWidget::dragEnterEvent(event);
00377 return;
00378 }
00379
00380 QDragEnterEvent de(event->pos().toPoint(), event->possibleActions(), event->mimeData(),
00381 event->buttons(), event->modifiers());
00382 d->page->event(&de);
00383
00384 if (de.isAccepted()) {
00385 event->accept();
00386 }
00387 }
00388
00389 void WebView::dragLeaveEvent(QGraphicsSceneDragDropEvent * event)
00390 {
00391 if (!d->page) {
00392 QGraphicsWidget::dragLeaveEvent(event);
00393 return;
00394 }
00395
00396 QDragLeaveEvent de;
00397 d->page->event(&de);
00398
00399 if (de.isAccepted()) {
00400 event->accept();
00401 }
00402 }
00403
00404 void WebView::dragMoveEvent(QGraphicsSceneDragDropEvent * event)
00405 {
00406 if (!d->page) {
00407 QGraphicsWidget::dragMoveEvent(event);
00408 return;
00409 }
00410
00411
00412
00413 QDragMoveEvent de(event->pos().toPoint(), event->possibleActions(), event->mimeData(),
00414 event->buttons(), event->modifiers());
00415 d->page->event(&de);
00416
00417 if (de.isAccepted()) {
00418 event->accept();
00419 }
00420 }
00421
00422 void WebView::dropEvent(QGraphicsSceneDragDropEvent * event)
00423 {
00424 if (!d->page) {
00425 QGraphicsWidget::dropEvent(event);
00426 return;
00427 }
00428
00429 QDragMoveEvent de(event->pos().toPoint(), event->possibleActions(), event->mimeData(),
00430 event->buttons(), event->modifiers());
00431 d->page->event(&de);
00432
00433 if (de.isAccepted()) {
00434 event->accept();
00435 }
00436 }
00437
00438 void WebView::setGeometry(const QRectF &geometry)
00439 {
00440 QGraphicsWidget::setGeometry(geometry);
00441 d->page->setViewportSize(geometry.size().toSize());
00442 }
00443
00444 void WebViewPrivate::loadingFinished(bool success)
00445 {
00446 loaded = success;
00447 emit q->loadFinished(success);
00448 q->update();
00449 }
00450
00451 void WebViewPrivate::updateRequested(const QRect &dirtyRect)
00452 {
00453 if (loaded && page) {
00454 q->update(QRectF(dirtyRect.topLeft().x(), dirtyRect.topLeft().y(),
00455 dirtyRect.width(), dirtyRect.height()));
00456 }
00457 }
00458
00459 void WebViewPrivate::scrollRequested(int dx, int dy, const QRect &scrollRect)
00460 {
00461 Q_UNUSED(dx)
00462 Q_UNUSED(dy)
00463 updateRequested(scrollRect);
00464 }
00465
00466 void WebViewPrivate::dragTimeoutExpired()
00467 {
00468 dragTimeout = true;
00469 }
00470
00471 }
00472
00473 #include "webview.moc"
00474