ginebra2/WebChromeItem.cpp
changeset 6 1c3b8676e58c
parent 5 0f2326c2a325
equal deleted inserted replaced
5:0f2326c2a325 6:1c3b8676e58c
     1 /*
     1 /*
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
     2  * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     3  * All rights reserved.
     4 *
     4  *
     5 * This program is free software: you can redistribute it and/or modify
     5  * This program is free software: you can redistribute it and/or modify
     6 * it under the terms of the GNU Lesser General Public License as published by
     6  * it under the terms of the GNU Lesser General Public License as published by
     7 * the Free Software Foundation, version 2.1 of the License.
     7  * the Free Software Foundation, version 2.1 of the License.
     8 *
     8  *
     9 * This program is distributed in the hope that it will be useful,
     9  * This program is distributed in the hope that it will be useful,
    10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12 * GNU Lesser General Public License for more details.
    12  * GNU Lesser General Public License for more details.
    13 *
    13  *
    14 * You should have received a copy of the GNU Lesser General Public License
    14  * You should have received a copy of the GNU Lesser General Public License
    15 * along with this program.  If not,
    15  * along with this program.  If not,
    16 * see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/".
    16  * see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/".
    17 *
    17  *
    18 * Description:
    18  * Description:
    19 *
    19  *
    20 */
    20  */
    21 
    21 
    22 #include "WebChromeItem.h"
    22 #include "WebChromeItem.h"
    23 #include "ChromeWidget.h"
    23 #include "ChromeWidget.h"
    24 #include "ChromeRenderer.h"
    24 #include "ChromeRenderer.h"
    25 #include "ChromeDOM.h"
    25 #include "ChromeDOM.h"
    31 #include <QWebHitTestResult>
    31 #include <QWebHitTestResult>
    32 #include <QWebFrame>
    32 #include <QWebFrame>
    33 #include <QGraphicsView>
    33 #include <QGraphicsView>
    34 #include <QDebug>
    34 #include <QDebug>
    35 
    35 
    36 namespace GVA {
    36 namespace GVA
       
    37 {
    37 #ifndef NO_QSTM_GESTURE
    38 #ifndef NO_QSTM_GESTURE
    38 using namespace qstmGesture;
    39 using namespace qstmGesture;
    39 #endif
    40 #endif
    40   WebChromeItem::WebChromeItem(const QRectF& ownerArea, ChromeWidget *chrome, const QWebElement & element, QGraphicsItem* parent)
    41 WebChromeItem::WebChromeItem(ChromeWidget *chrome, const QWebElement & element, QGraphicsItem* parent) :
    41     : ChromeItem(NULL, parent),
    42     ChromeItem(NULL, parent)
    42       m_ownerArea(ownerArea),
    43     , m_chrome(chrome)
    43       m_chrome(chrome),
    44     , m_element(element)
    44       m_element(element),
    45     , m_painting(false)
    45       m_painting(false)
    46 {
    46   {
    47     setFlags(QGraphicsItem::ItemIsFocusable);
    47 
    48     //Adjust the element size to match the element rectangle
    48 
    49     updateSizes();
    49     // G1: Prevent hover events from passing through to the underlying widget.
    50 #ifndef NO_QSTM_GESTURE
    50     //setAcceptHoverEvents(true); ?
    51     grabGesture(QStm_Gesture::assignedType());
    51 
    52 #endif
    52     //setFocusPolicy(Qt::ClickFocus);
    53     //Use QGraphicsScene cached rendering NB: This might degrade rendering quality for some animation transforms
    53     //setOpacity(0.50);
    54     setCacheMode(QGraphicsItem::ItemCoordinateCache);
       
    55 }
       
    56 
       
    57 WebChromeItem::~WebChromeItem()
       
    58 {
       
    59 
       
    60 }
       
    61 
       
    62 void WebChromeItem::init(WebChromeSnippet * snippet)
       
    63 {
       
    64     //TODO: revisit this, don't use owner area
       
    65     //setCachedHandlers(chrome()->dom()->getCachedHandlers(snippet->elementId(), ownerArea()));
       
    66     m_snippet = snippet;
       
    67 
       
    68     //When chrome is resized owner areas for snippets may change
       
    69     //NB: Maybe this needs to be done on chromeRepainted too?
       
    70 
       
    71     QObject::connect(renderer(), SIGNAL(chromeResized()), snippet, SLOT(updateOwnerArea()));
       
    72 
       
    73     QObject::connect(this, SIGNAL(contextMenu(QGraphicsSceneContextMenuEvent *)), snippet,
       
    74         SLOT(onContextMenuEvent(QGraphicsSceneContextMenuEvent *)));
       
    75 }
       
    76 
       
    77 QGraphicsScene * WebChromeItem::scene()
       
    78 {
       
    79   return m_chrome->layout()->scene();
       
    80 }
       
    81 
       
    82 ChromeRenderer * WebChromeItem::renderer()
       
    83 {
       
    84     return m_chrome->renderer();
       
    85 }
       
    86 
       
    87 //Adjust size to match the element rectangle
       
    88 void WebChromeItem::updateSizes()
       
    89 {
    54     //Set preferred size so item will resize as part of anchor layout
    90     //Set preferred size so item will resize as part of anchor layout
    55     setFlags(QGraphicsItem::ItemIsFocusable);
    91     setPreferredSize(m_element.geometry().width(), m_element.geometry().height());
    56     setPreferredSize(ownerArea.width(), ownerArea.height());
       
    57     //Also resize in case item is not part of anchor layout
    92     //Also resize in case item is not part of anchor layout
    58     resize(preferredSize());
    93     resize(preferredSize());
    59 #ifndef NO_QSTM_GESTURE
    94 }
    60     grabGesture(QStm_Gesture::assignedType());
    95 
    61 #endif
    96 // NB: For now we only handle onclick (actually mouseUp). Fix this
    62     //Use QGraphicsScene cached rendering NB: This might degrade rendering quality for some animation transforms
    97 // NB: Modify for multiple cached handlers: mouse click, long press
    63     setCacheMode(QGraphicsItem::ItemCoordinateCache);
    98 // and support handlers not executed in js engine.
    64   }
    99 
    65 
   100 void WebChromeItem::cachedHandlerEvent(QGraphicsSceneMouseEvent * ev)
    66   WebChromeItem::~WebChromeItem()
   101 {
    67   {
   102     for (int i = 0; i < m_handlers.size(); i++) {
    68 
   103         const CachedHandler & handler = m_handlers.at(i);
    69   }
   104         if (handler.rect().contains(ev->pos())) {
    70 
   105             //m_chrome->evalWithEngineContext(handler.script());
    71   void WebChromeItem::init(WebChromeSnippet * snippet)
   106             handler.invoke();
    72   {
   107             return;
    73     setCachedHandlers(chrome()->dom()->getCachedHandlers(snippet->elementId(), ownerArea()));
   108         }
    74     m_snippet = snippet;
       
    75 
       
    76     //When chrome is resized owner areas for snippets may change
       
    77     //NB: Maybe this needs to be done on chromeRepainted too?
       
    78     
       
    79     QObject::connect(
       
    80             renderer(),
       
    81             SIGNAL(chromeResized()),
       
    82             snippet,
       
    83             SLOT(updateOwnerArea()));
       
    84 
       
    85     QObject::connect(
       
    86             this,
       
    87             SIGNAL(contextMenu(QGraphicsSceneContextMenuEvent *)),
       
    88             snippet,
       
    89             SLOT(onContextMenuEvent(QGraphicsSceneContextMenuEvent *)));
       
    90   }
       
    91 
       
    92   QGraphicsScene * WebChromeItem::scene()
       
    93   {
       
    94     return m_chrome->getScene();
       
    95   }
       
    96 
       
    97   ChromeRenderer * WebChromeItem::renderer()
       
    98   {
       
    99     return m_chrome->renderer();
       
   100   }
       
   101 
       
   102   void WebChromeItem::setOwnerArea(const QRectF& ownerArea)
       
   103   {
       
   104     m_ownerArea = ownerArea;
       
   105     //Set preferred size so item will resize as part of anchor layout
       
   106     setPreferredSize(ownerArea.width(), ownerArea.height());
       
   107     //Also resize in case item is not part of anchor layout
       
   108     resize(preferredSize());
       
   109   }
       
   110 
       
   111   // NB: For now we only handle onclick (actually mouseUp). Fix this
       
   112   // NB: Modify for multiple cached handlers: mouse click, long press
       
   113   // and support handlers not executed in js engine.
       
   114 
       
   115   void WebChromeItem::cachedHandlerEvent(QGraphicsSceneMouseEvent * ev)
       
   116   {
       
   117     for (int i = 0; i < m_handlers.size(); i++){
       
   118      const CachedHandler & handler = m_handlers.at(i);
       
   119       if (handler.rect().contains(ev->pos())){
       
   120     qDebug() << "Invoking cached handler: " << handler.script();
       
   121         //m_chrome->evalWithEngineContext(handler.script());
       
   122     handler.invoke();
       
   123         return;
       
   124       }
       
   125     }
   109     }
   126   }
   110 }
   127 
   111 
   128   void WebChromeItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* opt, QWidget* widget)
   112 void WebChromeItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* opt, QWidget* widget)
   129   {
   113 {
   130     Q_UNUSED(opt)
   114     Q_UNUSED(opt)
   131     Q_UNUSED(widget)
   115     Q_UNUSED(widget)
   132 
   116 
   133       //For debugging
       
   134     //painter->fillRect(QRectF(0,0, m_ownerArea.width(), m_ownerArea.height()), Qt::yellow);
       
   135     //qDebug() << " WebChromeItem::paint: " << m_element.attribute("id");
       
   136     m_painting = true;
   117     m_painting = true;
   137     m_element.render(painter);
   118     m_element.render(painter);
   138     m_painting = false;
   119     m_painting = false;
   139     ChromeItem::paint(painter, opt, widget);
   120     ChromeItem::paint(painter, opt, widget);
   140   }
   121 }
   141 
   122 
   142 
   123 void WebChromeItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * ev)
   143   void WebChromeItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * ev)
   124 {
   144   {
       
   145 
       
   146     // qDebug() << "ChromeRenderer::contextMenuEvent";
       
   147     ev->setAccepted(true);
   125     ev->setAccepted(true);
   148     //Signal context menu event
   126     //Signal context menu event
   149     emit contextMenu(ev);
   127     emit contextMenu(ev);
   150   }
   128 }
   151 
   129 
   152   void WebChromeItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent * ev)
   130 void WebChromeItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent * ev)
   153   {
   131 {
   154 
       
   155     forwardMouseEvent(QEvent::MouseButtonDblClick, ev);
   132     forwardMouseEvent(QEvent::MouseButtonDblClick, ev);
   156   }
   133 }
   157 
   134 
   158   void WebChromeItem::grabFocus()
   135 void WebChromeItem::grabFocus()
   159   {
   136 {
   160     //setFocusProxy(m_chrome->renderer());
   137     //setFocusProxy(m_chrome->renderer());
   161     setFocus();
   138     setFocus();
   162   }
   139 }
   163 
   140 
   164   void WebChromeItem::mousePressEvent(QGraphicsSceneMouseEvent * ev)
   141 void WebChromeItem::mousePressEvent(QGraphicsSceneMouseEvent * ev)
   165   {
   142 {
   166     //On mouse press, first invoke any cached handlers.
   143     //On mouse press, first invoke any cached handlers.
   167     cachedHandlerEvent(ev);
   144     cachedHandlerEvent(ev);
   168     //Then do normal mouse press handling
   145     //Then do normal mouse press handling
   169     setFocus();
   146     setFocus();
   170    // setFocusProxy(m_chrome->renderer());
   147     // setFocusProxy(m_chrome->renderer());
   171     forwardMouseEvent(QEvent::MouseButtonPress, ev);
   148     forwardMouseEvent(QEvent::MouseButtonPress, ev);
   172   }
   149 }
   173 
   150 
   174   void WebChromeItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * ev)
   151 void WebChromeItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * ev)
   175   {
   152 {
   176     forwardMouseEvent(QEvent::MouseButtonRelease, ev);
   153     forwardMouseEvent(QEvent::MouseButtonRelease, ev);
   177 #if defined __SYMBIAN32__
   154 #if defined __SYMBIAN32__
   178 // FIXME Remove this, it will be fixed Qt 4.6.3 ?
   155     // FIXME Remove this, it will be fixed Qt 4.6.3 ?
   179  /*   
   156     /*   
   180    if (ev->button() == Qt::LeftButton) {
   157      if (ev->button() == Qt::LeftButton) {
   181         QPoint p = QPoint(int(m_ownerArea.x()), int(m_ownerArea.y())) + ev->pos().toPoint();
   158      QRectF elementRectangle = m_element.geometry();
   182         QWebFrame* frame = m_chrome->renderer()->page()->mainFrame();
   159      QPoint p = QPoint(int(elementRectangle.x()), int(elementRectangle.y())) + ev->pos().toPoint();
   183         QWebHitTestResult htr = frame->hitTestContent(p);
   160      QWebFrame* frame = m_chrome->renderer()->page()->mainFrame();
   184         if (htr.isContentEditable()) {
   161      QWebHitTestResult htr = frame->hitTestContent(p);
   185             QEvent vkbEvent(QEvent::RequestSoftwareInputPanel);
   162      if (htr.isContentEditable()) {
   186             QList<QGraphicsView*> views = m_chrome->renderer()->scene()->views();
   163      QEvent vkbEvent(QEvent::RequestSoftwareInputPanel);
   187             QWidget* view = qobject_cast<QWidget*>(views.value(0));
   164      QList<QGraphicsView*> views = m_chrome->renderer()->scene()->views();
   188             if (view)
   165      QWidget* view = qobject_cast<QWidget*>(views.value(0));
   189               QApplication::sendEvent(view, &vkbEvent);
   166      if (view)
       
   167      QApplication::sendEvent(view, &vkbEvent);
       
   168      }
       
   169      }
       
   170      */
       
   171 #endif
       
   172 }
       
   173 
       
   174 void WebChromeItem::mouseMoveEvent(QGraphicsSceneMouseEvent * ev)
       
   175 {
       
   176     forwardMouseEvent(QEvent::MouseMove, ev);
       
   177 }
       
   178 
       
   179 void WebChromeItem::forwardMouseEvent(QEvent::Type type, QGraphicsSceneMouseEvent *ev)
       
   180 {
       
   181 
       
   182     emit mouseEvent(type);
       
   183     QRectF elementRectangle = m_element.geometry();
       
   184     QMouseEvent shiftedEv(type, QPoint(int(elementRectangle.x()), int(elementRectangle.y()))
       
   185         + ev->pos().toPoint(), ev->button(), ev->buttons(), ev->modifiers());
       
   186     //qDebug() << "elementRectangle: " << elementRectangle << "ev->pos(): " << ev->pos() <<
       
   187     //      "shiftedEv.pos(): " << shiftedEv.pos();
       
   188     QApplication::sendEvent(m_chrome->renderer()->page(), &shiftedEv);
       
   189 }
       
   190 
       
   191 void WebChromeItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
       
   192 {
       
   193     // Translate to a mouse move event.
       
   194     /*
       
   195      QRectF elementRectangle = m_element.geometry(); 
       
   196      QMouseEvent shiftedEv( QEvent::MouseMove, QPoint(int(elementRectangle.x()), int(elementRectangle.y()))+event->pos().toPoint(),
       
   197      Qt::NoButton, Qt::NoButton, Qt::NoModifier);
       
   198      QApplication::sendEvent(m_chrome->renderer(), &shiftedEv); */
       
   199 }
       
   200 /*
       
   201  void WebChromeItem::keyPressEvent ( QKeyEvent * event ) {
       
   202  QApplication::sendEvent(m_chrome->renderer(), event);
       
   203  }
       
   204 
       
   205  void WebChromeItem::keyReleaseEvent ( QKeyEvent * event ) {
       
   206  QApplication::sendEvent(m_chrome->renderer(), event);
       
   207  }
       
   208  */
       
   209 
       
   210 bool WebChromeItem::event(QEvent* event)
       
   211 {
       
   212 #ifndef NO_QSTM_GESTURE
       
   213     if (event->type() == QEvent::Gesture) {
       
   214         QStm_Gesture* gesture = getQStmGesture(event);
       
   215         if (gesture) {
       
   216             QStm_GestureType gtype = gesture->getGestureStmType();
       
   217             if (gtype == QStmTouchGestureType || gtype == QStmReleaseGestureType) {
       
   218                 gesture->sendMouseEvents();
       
   219                 return true;
       
   220             }
   190         }
   221         }
   191     }
   222     }
   192     */
   223 #endif
   193 #endif
   224     return QGraphicsWidget::event(event);
   194   }
   225 }
   195 
       
   196 
       
   197   void WebChromeItem::mouseMoveEvent(QGraphicsSceneMouseEvent * ev)
       
   198   {
       
   199     forwardMouseEvent(QEvent::MouseMove, ev);
       
   200   }
       
   201 
       
   202 
       
   203   void WebChromeItem::forwardMouseEvent(QEvent::Type type, QGraphicsSceneMouseEvent *ev) {
       
   204 
       
   205     emit mouseEvent(type);
       
   206     // m_chrome->renderer()->setFocus();
       
   207     QMouseEvent shiftedEv( type, QPoint(int(m_ownerArea.x()), int(m_ownerArea.y()))+ev->pos().toPoint(),
       
   208                ev->button(), ev->buttons(), ev->modifiers() );
       
   209     //qDebug() << "m_ownerArea: " << m_ownerArea << "ev->pos(): " << ev->pos() <<
       
   210     //      "shiftedEv.pos(): " << shiftedEv.pos();
       
   211     QApplication::sendEvent(m_chrome->renderer()->page(),&shiftedEv);
       
   212   }
       
   213 
       
   214   void WebChromeItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event ) {
       
   215     // Translate to a mouse move event.
       
   216    /* QMouseEvent shiftedEv( QEvent::MouseMove, QPoint(int(m_ownerArea.x()), int(m_ownerArea.y()))+event->pos().toPoint(),
       
   217                Qt::NoButton, Qt::NoButton, Qt::NoModifier);
       
   218     QApplication::sendEvent(m_chrome->renderer(), &shiftedEv); */
       
   219   } 
       
   220   /*
       
   221   void WebChromeItem::keyPressEvent ( QKeyEvent * event ) {
       
   222     qDebug() << "WebChromeItem: keyPressEvent " << event->type();
       
   223     QApplication::sendEvent(m_chrome->renderer(), event);
       
   224   }
       
   225 
       
   226   void WebChromeItem::keyReleaseEvent ( QKeyEvent * event ) {
       
   227     qDebug() << "WebChromeItem: keyReleaseEvent " << event->type();
       
   228     QApplication::sendEvent(m_chrome->renderer(), event);
       
   229   }
       
   230   */
       
   231 
       
   232   bool WebChromeItem::event(QEvent* event)
       
   233   {
       
   234 #ifndef NO_QSTM_GESTURE
       
   235       if (event->type() == QEvent::Gesture) {
       
   236           QStm_Gesture* gesture = getQStmGesture(event);
       
   237           if (gesture) {
       
   238               QStm_GestureType gtype = gesture->getGestureStmType();
       
   239               if (gtype == QStmTouchGestureType || gtype == QStmReleaseGestureType) {
       
   240                   gesture->sendMouseEvents();
       
   241                   return true;
       
   242               }
       
   243           }
       
   244       }
       
   245 #endif
       
   246       return QGraphicsWidget::event(event);
       
   247   }
       
   248 
   226 
   249 } // endof namespace GVA
   227 } // endof namespace GVA