/*
* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
#include "WebChromeItem.h"
#include "ChromeWidget.h"
#include "ChromeRenderer.h"
#include "ChromeDOM.h"
#include "WebChromeSnippet.h"
#ifndef NO_QSTM_GESTURE
#include "qstmgestureevent.h"
#endif
#include <QSizePolicy>
#include <QWebHitTestResult>
#include <QWebFrame>
#include <QGraphicsView>
#include <QDebug>
namespace GVA {
#ifndef NO_QSTM_GESTURE
using namespace qstmGesture;
#endif
WebChromeItem::WebChromeItem(const QRectF& ownerArea, ChromeWidget *chrome, const QWebElement & element, QGraphicsItem* parent)
: QGraphicsWidget(parent),
m_ownerArea(ownerArea),
m_chrome(chrome),
m_element(element),
m_painting(false)
{
// G1: Prevent hover events from passing through to the underlying widget.
//setAcceptHoverEvents(true); ?
//setFocusPolicy(Qt::ClickFocus);
//setOpacity(0.50);
//Set preferred size so item will resize as part of anchor layout
setFlags(QGraphicsItem::ItemIsFocusable);
setPreferredSize(ownerArea.width(), ownerArea.height());
//Also resize in case item is not part of anchor layout
resize(preferredSize());
#ifndef NO_QSTM_GESTURE
grabGesture(QStm_Gesture::assignedType());
#endif
//Use QGraphicsScene cached rendering NB: This might degrade rendering quality for some animation transforms
setCacheMode(QGraphicsItem::ItemCoordinateCache);
}
WebChromeItem::~WebChromeItem()
{
}
void WebChromeItem::init(WebChromeSnippet * snippet)
{
setCachedHandlers(chrome()->dom()->getCachedHandlers(snippet->elementId(), ownerArea()));
//QObject::connect(
// renderer(),
// SIGNAL(chromeRepainted(const QRectF&)),
// this,
// SLOT(repaintFromChrome(const QRectF&))/*, Qt::QueuedConnection*/);
//When chrome is resized owner areas for snippets may change
//NB: Maybe this needs to be done on chromeRepainted too?
QObject::connect(
renderer(),
SIGNAL(chromeResized()),
snippet,
SLOT(updateOwnerArea()));
QObject::connect(
this,
SIGNAL(contextMenu(QGraphicsSceneContextMenuEvent *)),
snippet,
SLOT(onContextMenuEvent(QGraphicsSceneContextMenuEvent *)));
}
QGraphicsScene * WebChromeItem::scene()
{
return m_chrome->getScene();
}
ChromeRenderer * WebChromeItem::renderer()
{
return m_chrome->renderer();
}
void WebChromeItem::setOwnerArea(const QRectF& ownerArea)
{
m_ownerArea = ownerArea;
//Set preferred size so item will resize as part of anchor layout
setPreferredSize(ownerArea.width(), ownerArea.height());
//Also resize in case item is not part of anchor layout
resize(preferredSize());
}
//NB: Not used. Updates now come from renderer directly
void WebChromeItem::repaintFromChrome(const QRectF & rect) // slot
{
QPainter painter;
Q_UNUSED(rect)
qDebug() << "WebChromeItem::repaintFromChrome: dirtyRect: " << rect << " ownerArea: " << m_ownerArea << " elemGeom: " << m_element.geometry();
// Update if this is our rect
if(rect.intersects(m_ownerArea))
update();
}
// NB: For now we only handle onclick (actually mouseUp). Fix this
// NB: Modify for multiple cached handlers: mouse click, long press
// and support handlers not executed in js engine.
void WebChromeItem::cachedHandlerEvent(QGraphicsSceneMouseEvent * ev)
{
for(int i = 0; i < m_handlers.size(); i++){
const CachedHandler & handler = m_handlers.at(i);
if(handler.rect().contains(ev->pos())){
qDebug() << "Invoking cached handler: " << handler.script();
//m_chrome->evalWithEngineContext(handler.script());
handler.invoke();
return;
}
}
}
void WebChromeItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* opt, QWidget* widget)
{
Q_UNUSED(opt)
Q_UNUSED(widget)
//For debugging
//painter->fillRect(QRectF(0,0, m_ownerArea.width(), m_ownerArea.height()), Qt::yellow);
qDebug() << " WebChromeItem::paint: " << m_element.attribute("id");
m_painting = true;
m_element.render(painter);
m_painting = false;
}
void WebChromeItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * ev)
{
// qDebug() << "ChromeRenderer::contextMenuEvent";
ev->setAccepted(true);
//Signal context menu event
emit contextMenu(ev);
}
void WebChromeItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent * ev)
{
forwardMouseEvent(QEvent::MouseButtonDblClick, ev);
}
void WebChromeItem::grabFocus()
{
setFocusProxy(m_chrome->renderer());
setFocus();
}
void WebChromeItem::mousePressEvent(QGraphicsSceneMouseEvent * ev)
{
//On mouse press, first invoke any cached handlers.
cachedHandlerEvent(ev);
//Then do normal mouse press handling
setFocus();
setFocusProxy(m_chrome->renderer());
forwardMouseEvent(QEvent::MouseButtonPress, ev);
}
void WebChromeItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * ev)
{
forwardMouseEvent(QEvent::MouseButtonRelease, ev);
#if defined __SYMBIAN32__
// FIXME Remove this, it will be fixed Qt 4.6.3 ?
if (ev->button() == Qt::LeftButton) {
QPoint p = QPoint(int(m_ownerArea.x()), int(m_ownerArea.y())) + ev->pos().toPoint();
QWebFrame* frame = m_chrome->renderer()->page()->mainFrame();
QWebHitTestResult htr = frame->hitTestContent(p);
if (htr.isContentEditable()) {
QEvent vkbEvent(QEvent::RequestSoftwareInputPanel);
QList<QGraphicsView*> views = m_chrome->renderer()->scene()->views();
QWidget* view = qobject_cast<QWidget*>(views.value(0));
if (view)
QApplication::sendEvent(view, &vkbEvent);
}
}
#endif
}
void WebChromeItem::mouseMoveEvent(QGraphicsSceneMouseEvent * ev)
{
forwardMouseEvent(QEvent::MouseMove, ev);
}
void WebChromeItem::forwardMouseEvent(QEvent::Type type, QGraphicsSceneMouseEvent *ev) {
emit mouseEvent(type);
// m_chrome->renderer()->setFocus();
QMouseEvent shiftedEv( type, QPoint(int(m_ownerArea.x()), int(m_ownerArea.y()))+ev->pos().toPoint(),
ev->button(), ev->buttons(), ev->modifiers() );
//qDebug() << "m_ownerArea: " << m_ownerArea << "ev->pos(): " << ev->pos() <<
// "shiftedEv.pos(): " << shiftedEv.pos();
QApplication::sendEvent(m_chrome->renderer()->page(),&shiftedEv);
}
void WebChromeItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event ) {
// Translate to a mouse move event.
QMouseEvent shiftedEv( QEvent::MouseMove, QPoint(int(m_ownerArea.x()), int(m_ownerArea.y()))+event->pos().toPoint(),
Qt::NoButton, Qt::NoButton, Qt::NoModifier);
QApplication::sendEvent(m_chrome->renderer(), &shiftedEv);
}
/*
void WebChromeItem::keyPressEvent ( QKeyEvent * event ) {
qDebug() << "WebChromeItem: keyPressEvent " << event->type();
QApplication::sendEvent(m_chrome->renderer(), event);
}
void WebChromeItem::keyReleaseEvent ( QKeyEvent * event ) {
qDebug() << "WebChromeItem: keyReleaseEvent " << event->type();
QApplication::sendEvent(m_chrome->renderer(), event);
}
*/
bool WebChromeItem::event(QEvent* event)
{
#ifndef NO_QSTM_GESTURE
if (event->type() == QEvent::Gesture) {
QStm_Gesture* gesture = getQStmGesture(event);
if (gesture) {
QStm_GestureType gtype = gesture->getGestureStmType();
if (gtype == QStmTouchGestureType || gtype == QStmReleaseGestureType) {
gesture->sendMouseEvents();
return true;
}
}
}
#endif
return QGraphicsWidget::event(event);
}
} // endof namespace GVA