ginebra/chromesnippet.cpp
branchGCC_SURGE
changeset 8 2e16851ffecd
parent 2 bf4420e9fa4d
parent 6 1c3b8676e58c
equal deleted inserted replaced
2:bf4420e9fa4d 8:2e16851ffecd
     1 /*
       
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "chromesnippet.h"
       
    20 #include "chromesnippetjsobject.h"
       
    21 #include "chromewidget.h"
       
    22 #include "graphicsitemanimation.h"
       
    23 #include "scriptobjects.h"
       
    24 
       
    25 #include <QGraphicsLinearLayout>
       
    26 #include <QGraphicsSceneContextMenuEvent>
       
    27 #include <QImage>
       
    28 #include <QPainter>
       
    29 #include "qwebframe.h"
       
    30 #include "qwebpage.h"
       
    31 #include "chromeview.h"
       
    32 
       
    33 bool ChromeSnippet::contextMenuFlag = false;
       
    34 
       
    35 ChromeSnippet::ChromeSnippet(QGraphicsItem * parent, ChromeWidget * owner, QObject *jsParent, const QString &docElementId)
       
    36   : QGraphicsRectItem(parent),
       
    37     m_owner(owner),
       
    38     m_docElementId(docElementId),
       
    39     m_layout(0),
       
    40     m_visibilityAnimator(0),
       
    41     m_attentionAnimator(0),
       
    42     m_dragging(false),
       
    43     m_draggable(false),
       
    44     m_anchor("AnchorNone"),
       
    45     m_anchorOffset(0),
       
    46     m_hidesContent(false),
       
    47     m_isHiding(false),
       
    48     m_jsObject(new ChromeSnippetJSObject(jsParent, *this, docElementId))
       
    49 {
       
    50 	  // Prevent hover events from passing through to the underlying widget.
       
    51     setAcceptHoverEvents(true);
       
    52 }
       
    53 
       
    54 ChromeSnippet::~ChromeSnippet()
       
    55 {
       
    56   //qDebug() << "ChromeSnippet::~ChromeSnippet: " << m_docElementId;
       
    57   if(m_visibilityAnimator)
       
    58     delete m_visibilityAnimator;
       
    59   if(m_attentionAnimator)
       
    60     delete m_attentionAnimator;
       
    61   if(m_jsObject)
       
    62     delete m_jsObject;
       
    63 }
       
    64 
       
    65 void ChromeSnippet::setOwnerArea(const QRectF& ownerArea)
       
    66 {
       
    67   m_ownerArea = ownerArea; 
       
    68 }
       
    69 
       
    70 QRectF& ChromeSnippet::ownerArea(){
       
    71   return m_ownerArea;
       
    72 }
       
    73 
       
    74 void ChromeSnippet::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
       
    75 {
       
    76   Q_UNUSED(option)
       
    77   Q_UNUSED(widget)
       
    78 
       
    79   //qDebug() << "ChromeSnippet::paint: " << m_docElementId << " " << m_ownerArea;
       
    80   //If this snippet has no children, draw the snippet. Otherwise let the children draw themselves.
       
    81   // NB: Make this behavior configurable?
       
    82   if(childItems().isEmpty()){
       
    83 #ifdef Q_OS_SYMBIAN
       
    84   painter->drawPixmap(QPoint(0, 0), *m_owner->buffer(), m_ownerArea);
       
    85 #else
       
    86   painter->drawImage(QPoint(0, 0), *m_owner->buffer(), m_ownerArea);
       
    87 #endif
       
    88   }
       
    89 }
       
    90 
       
    91 void ChromeSnippet::updateChildGeometries()
       
    92 {
       
    93   //NB: layouts should be usable here, but the behavior
       
    94   //is weird. Investigage further.
       
    95   /* delete m_layout;
       
    96   m_layout = new QGraphicsLinearLayout();
       
    97   QList<QGraphicsItem*> children = childItems();
       
    98   for(int i = 0; i < children.size(); i++){
       
    99     ChromeSnippet * child = dynamic_cast<ChromeSnippet*>(children[i]);
       
   100     m_layout->addItem(child);
       
   101   }
       
   102   setLayout(m_layout);
       
   103   */
       
   104   // For now just lay out in a row according to the html layout
       
   105   
       
   106         
       
   107   QList<QGraphicsItem*> children = childItems();
       
   108   for(int i = 0; i < children.size(); i++){
       
   109     ChromeSnippet * child = dynamic_cast<ChromeSnippet*>(children[i]);  
       
   110   	child->setPos(child->ownerArea().x(), 0);
       
   111   }
       
   112   
       
   113   if((docElementId() == "ContextMenuBgId") || (docElementId() == "ContextMenuId")) // hide context menu
       
   114   {
       
   115   	hide();  			
       
   116   }
       
   117   
       
   118   	  
       
   119 }
       
   120 bool ChromeSnippet::getContextMenuFlag()
       
   121 {
       
   122 	return contextMenuFlag;
       
   123 }
       
   124 
       
   125 void ChromeSnippet::mousePressEvent(QGraphicsSceneMouseEvent * ev)
       
   126 {
       
   127   // qDebug() << "ChromeSnippet::mousePressEvent: " << scene()->focusItem();
       
   128   // qDebug() << "ChromeSnippet::mousePressEvent: " << docElementId() << m_ownerArea << ev->pos();
       
   129   
       
   130   
       
   131   QRect qr = m_owner->getDocElementRect("contextMenuButton");  
       
   132   ChromeSnippet *cmsn = m_owner->getSnippet("ContextMenuId");	
       
   133    
       
   134   qreal qx = ev->pos().x();
       
   135   qreal qy = ev->pos().y();
       
   136   bool cmVisibility = cmsn->isVisible();
       
   137 
       
   138   if(!cmVisibility)
       
   139   	contextMenuFlag = false;
       
   140   else  if(qx >= qr.left() && qx <= qr.right() && (docElementId() == "WebViewToolbarId"))
       
   141   {
       
   142   		contextMenuFlag = true;  		
       
   143   		return;
       
   144   }
       
   145   
       
   146   
       
   147   contextMenuFlag = false;
       
   148   
       
   149   passMouseEventToPage(QEvent::MouseButtonPress, ev);
       
   150   m_owner->chromePage()->view()->setFocus();
       
   151   
       
   152   if(docElementId() == "ContextMenuBgId")
       
   153   {
       
   154   	ChromeSnippet *sn = m_owner->getSnippet("ContextMenuId");	
       
   155   	if(sn)
       
   156   		sn->hide();
       
   157   	hide();
       
   158   }
       
   159   else if(docElementId() != "ContextMenuId")
       
   160   {
       
   161   	ChromeSnippet *sn = m_owner->getSnippet("ContextMenuId");	
       
   162   	if(sn)
       
   163   		sn->hide();
       
   164   	ChromeSnippet *sn2 = m_owner->getSnippet("ContextMenuBgId");	
       
   165   	if(sn2)
       
   166   		sn2->hide();
       
   167   	
       
   168   }
       
   169  
       
   170   ev->accept();
       
   171 
       
   172   //FIXME hide the Suggests snippet or not
       
   173   ChromeSnippet* ssn = m_owner->getSnippet("SuggestsId");
       
   174   if (ssn && ssn->isVisible()) {
       
   175       if (docElementId() == "SuggestsId") {
       
   176           if (m_ownerArea.height() < ev->pos().y())
       
   177               hide();
       
   178       }
       
   179       else
       
   180           ssn->hide();
       
   181   }
       
   182 }
       
   183 
       
   184 void ChromeSnippet::mouseReleaseEvent(QGraphicsSceneMouseEvent * ev)
       
   185 {
       
   186 	
       
   187   if(m_dragging) {
       
   188     emit m_jsObject->dragFinished();
       
   189     m_dragging = false;
       
   190   }
       
   191   passMouseEventToPage(QEvent::MouseButtonRelease, ev);
       
   192 }
       
   193 
       
   194 
       
   195 void ChromeSnippet::mouseMoveEvent(QGraphicsSceneMouseEvent * ev)
       
   196 {
       
   197   if(m_draggable) {
       
   198       if(!m_dragging) {
       
   199           m_dragging = true;
       
   200           emit m_jsObject->dragStarted();
       
   201       }
       
   202       moveBy((ev->pos()-ev->lastPos()).x(),(ev->pos()-ev->lastPos()).y());
       
   203   }
       
   204   else {
       
   205       passMouseEventToPage(QEvent::MouseMove, ev);
       
   206   }
       
   207 }
       
   208 
       
   209 
       
   210 void ChromeSnippet::mouseDoubleClickEvent(QGraphicsSceneMouseEvent * ev)
       
   211 {
       
   212   passMouseEventToPage(QEvent::MouseButtonDblClick, ev);
       
   213   if(m_owner && m_owner->chromePage())
       
   214       m_owner->chromePage()->view()->setFocus();
       
   215 }
       
   216 
       
   217 void ChromeSnippet::passMouseEventToPage(QEvent::Type type, QGraphicsSceneMouseEvent *ev) {
       
   218   ev->accept();
       
   219   if(m_owner && m_owner->chromePage()) {
       
   220       // Translate the mouse press to the owner's coords and forward to owner page
       
   221       QMouseEvent shiftedEv( type, QPoint(int(m_ownerArea.x()), int(m_ownerArea.y()))+ev->pos().toPoint(),
       
   222                              ev->button(), ev->buttons(), ev->modifiers() );
       
   223     
       
   224       //qDebug() << "ChromeSnippet::passMouseEventToPage: " << shiftedEv.pos() << " " << &shiftedEv;
       
   225       m_owner->chromePage()->event(&shiftedEv);
       
   226   }
       
   227 }
       
   228 
       
   229 void ChromeSnippet::hoverMoveEvent(QGraphicsSceneHoverEvent *event ) {
       
   230   // Translate to a mouse move event.
       
   231   QMouseEvent shiftedEv( QEvent::MouseMove, QPoint(int(m_ownerArea.x()), int(m_ownerArea.y()))+event->pos().toPoint(),
       
   232                          Qt::NoButton, Qt::NoButton, Qt::NoModifier);
       
   233   if(m_owner && m_owner->chromePage())
       
   234         m_owner->chromePage()->event(&shiftedEv);
       
   235 }
       
   236 
       
   237 void ChromeSnippet::keyPressEvent ( QKeyEvent * event ) {
       
   238   event->accept();
       
   239   QApplication::sendEvent(m_owner->chromePage()->view(), event);
       
   240 }
       
   241 
       
   242 void ChromeSnippet::keyReleaseEvent ( QKeyEvent * event ) {
       
   243   event->accept();
       
   244   QApplication::sendEvent(m_owner->chromePage()->view(), event);
       
   245 }
       
   246 
       
   247 void ChromeSnippet::contextMenuEvent(QGraphicsSceneContextMenuEvent* event) 
       
   248 {
       
   249     event->accept();
       
   250 }
       
   251 
       
   252 void ChromeSnippet::setVisibilityAnimator(const QString& animatorName)
       
   253 {
       
   254   setVisibilityAnimator(VisibilityAnimator::create(animatorName, this));
       
   255 }
       
   256 
       
   257 void ChromeSnippet::setAttentionAnimator(const QString& animatorName)
       
   258 {
       
   259   setAttentionAnimator(AttentionAnimator::create(animatorName, this));
       
   260 }
       
   261 
       
   262 void ChromeSnippet::toggleVisibility()                    
       
   263 {
       
   264   m_isHiding = (m_isHiding)?false:true;
       
   265 
       
   266   if(m_isHiding)
       
   267     emit m_jsObject->onHide();
       
   268   if(m_visibilityAnimator){
       
   269     emit m_jsObject->dragStarted();
       
   270     m_visibilityAnimator->toggleVisibility();
       
   271     emit m_jsObject->dragFinished();
       
   272   }
       
   273   else {
       
   274     (m_isHiding)?QGraphicsRectItem::hide():QGraphicsRectItem::show();
       
   275   }
       
   276   if(!m_isHiding)
       
   277       emit m_jsObject->onShow();
       
   278 }
       
   279 
       
   280 void ChromeSnippet::show(bool useAnimation){
       
   281   if(m_isHiding){
       
   282     if(useAnimation)
       
   283       toggleVisibility();
       
   284     else{
       
   285       QGraphicsRectItem::show();
       
   286       m_isHiding = false;
       
   287       emit m_jsObject->onShow();
       
   288     }
       
   289   }
       
   290 }
       
   291 
       
   292 void ChromeSnippet::hide(bool useAnimation){
       
   293   if(!m_isHiding){
       
   294     if(useAnimation)
       
   295       toggleVisibility();
       
   296     else{
       
   297       QGraphicsItem::hide();
       
   298       m_isHiding = true;
       
   299       emit m_jsObject->onHide();
       
   300     }
       
   301   }
       
   302 }
       
   303 
       
   304 void ChromeSnippet::toggleAttention()                    
       
   305 {
       
   306   qDebug() << "ChromeSnippet::toggleAttention";
       
   307   if(m_attentionAnimator){
       
   308     m_attentionAnimator->toggleActive();
       
   309   }
       
   310 }
       
   311 
       
   312 QObject *ChromeSnippet::animate(int duration) {
       
   313   GraphicsItemAnimation *an = new GraphicsItemAnimation(this, duration);
       
   314   m_owner->chromePage()->mainFrame()->addToJavaScriptWindowObject("animation", an, QScriptEngine::ScriptOwnership);
       
   315   return an;
       
   316 }
       
   317 
       
   318 QObject *ChromeSnippet::getGeometry() const {
       
   319     ScriptRectF *r = new ScriptRectF(rect());
       
   320     m_owner->chromePage()->mainFrame()->addToJavaScriptWindowObject("rectf", r, QScriptEngine::ScriptOwnership);
       
   321     return r;
       
   322 }
       
   323 
       
   324 QObject *ChromeSnippet::getPosition() const {
       
   325     ScriptPoint *result = new ScriptPoint(pos().toPoint());
       
   326     m_owner->chromePage()->mainFrame()->addToJavaScriptWindowObject("point", result, QScriptEngine::ScriptOwnership);
       
   327     return result;
       
   328 }
       
   329 
       
   330 void ChromeSnippet::resize(qreal width, qreal height) {
       
   331     QRectF r = rect();
       
   332     r.setWidth(width);
       
   333     r.setHeight(height);
       
   334     setRect(r);
       
   335 }
       
   336 
       
   337 void ChromeSnippet::repaint() {
       
   338     //qDebug() << __func__ << "Area: " <<  m_ownerArea  << "Id " <<  m_docElementId;  
       
   339   m_owner->repaintRequested(m_ownerArea.toRect());
       
   340 }
       
   341 
       
   342 void ChromeSnippet::dump() const{
       
   343   qDebug() << "ChromeSnippet::dump: id=" << m_docElementId << " name=" << m_docElementName;
       
   344   qDebug() << "                     this=" << this;
       
   345   qDebug() << "                     pos()=" << pos();
       
   346   qDebug() << "                     rect()=" << rect();
       
   347   qDebug() << "                     m_ownerArea=" << m_ownerArea;
       
   348   qDebug() << "                     visible=" << isVisible();
       
   349   qDebug() << "                     zValue=" << zValue();
       
   350   if(parentObject())
       
   351       qDebug() << "                     parent=" << parentObject();
       
   352   if(parentWidget())
       
   353       qDebug() << "                     parentItem=" << parentWidget();
       
   354 }
       
   355 
       
   356 QObject *ChromeSnippet::getJSObject() { 
       
   357     return static_cast<QObject*>(m_jsObject); 
       
   358 }
       
   359 
       
   360 QString  ChromeSnippet::getDisplayMode()
       
   361 {
       
   362 	return m_owner->getDisplayMode();
       
   363 	
       
   364 	
       
   365 }
       
   366 /*
       
   367 bool ChromeSnippet::sceneEventFilter ( QGraphicsItem * watched, QEvent * event ) {
       
   368     qDebug() << "ChromeSnippet::sceneEventFilter: " << event;
       
   369     return QGraphicsItem::sceneEventFilter(watched, event);
       
   370 }
       
   371 */