ginebra2/WebChromeItem.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 23 Jun 2010 17:59:43 +0300
changeset 5 0f2326c2a325
parent 0 1450b09d0cfd
child 6 1c3b8676e58c
permissions -rw-r--r--
Revision: 201024 Kit: 2010125

/*
* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program.  If not,
* see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/".
*
* 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)
    : ChromeItem(NULL, 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()));
    m_snippet = snippet;

    //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: 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;
    ChromeItem::paint(painter, opt, widget);
  }


  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