ginebra2/ContentViews/WebContentAnimationItem.cpp
changeset 16 3c88a81ff781
parent 14 6aeb7a756187
equal deleted inserted replaced
14:6aeb7a756187 16:3c88a81ff781
     1 /*
       
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 *
       
     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
       
     7 * the Free Software Foundation, version 2.1 of the License.
       
     8 *
       
     9 * This program is distributed in the hope that it will be useful,
       
    10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    12 * GNU Lesser General Public License for more details.
       
    13 *
       
    14 * You should have received a copy of the GNU Lesser General Public License
       
    15 * along with this program.  If not,
       
    16 * see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/".
       
    17 *
       
    18 * Description:
       
    19 *
       
    20 */
       
    21 
       
    22 #include "WebContentAnimationItem.h"
       
    23 
       
    24 #include <QGraphicsWebView>
       
    25 #include <QtGlobal>
       
    26 #include <QWebElement>
       
    27 #include <QWebFrame>
       
    28 
       
    29 static const int MinDoubleClickZoomTargetWidth = 100;     //Target block width for applying double tap zoom
       
    30 static const int ZoomCommitDuration = 50;                 //Timeout before commiting zoom
       
    31 static const qreal ZoomableContentMinWidth = 300.;
       
    32 
       
    33 namespace GVA {
       
    34 
       
    35 WebContentAnimationItem::WebContentAnimationItem(QGraphicsWidget* parent, Qt::WindowFlags wFlags)
       
    36     : QGraphicsWidget(parent, wFlags)
       
    37     , m_zoomCommitTimer(this)
       
    38     , m_viewportMetaData(0)
       
    39 {
       
    40     setFlag(QGraphicsItem::ItemHasNoContents, true);
       
    41     setFlag(QGraphicsItem::ItemClipsChildrenToShape, true);
       
    42     setFlag(QGraphicsItem::ItemClipsToShape, true);
       
    43 
       
    44     setFiltersChildEvents(true);
       
    45 
       
    46     connect(&m_zoomCommitTimer, SIGNAL(timeout()), this, SLOT(commitZoom()));
       
    47     m_zoomCommitTimer.setSingleShot(true);
       
    48 }
       
    49 
       
    50 WebContentAnimationItem::~WebContentAnimationItem()
       
    51 {}
       
    52 
       
    53 void WebContentAnimationItem::setWebView(QGraphicsWebView* webView)
       
    54 {
       
    55     Q_ASSERT(m_webView);
       
    56     m_webView = webView;
       
    57 
       
    58     //Enabling resize to contents avoids scrollbars in mainframe
       
    59     m_webView->setResizesToContents(true);
       
    60     m_webView->setParentItem(this);
       
    61     m_webView->setAttribute(Qt::WA_OpaquePaintEvent, true);
       
    62 }
       
    63 
       
    64 void WebContentAnimationItem::updatePreferredContentSize(const QSize& size)
       
    65 {
       
    66     // FIXME: we have bug in QtWebKit API when tileCacheEnabled is true.
       
    67     // this causes viewport not to reset between the page loads.
       
    68     // Thus, we need to update viewport manually until we have fix for this.
       
    69 
       
    70     m_webView->page()->setPreferredContentsSize(size);
       
    71     resize(contentsSize());
       
    72 }
       
    73 
       
    74 QSize WebContentAnimationItem::contentsSize() const
       
    75 {
       
    76     return m_webView->page()->mainFrame()->contentsSize();
       
    77 }
       
    78 
       
    79 void WebContentAnimationItem::setZoomScale(qreal value, bool immediateCommit)
       
    80 {
       
    81     value = qBound(m_viewportMetaData->m_minimumScale, value, m_viewportMetaData->m_maximumScale);
       
    82     qreal curZoomScale = zoomScale();
       
    83 
       
    84     if (qFuzzyCompare(value, curZoomScale)) {
       
    85         notifyZoomActions(curZoomScale);
       
    86         return;
       
    87     }
       
    88 
       
    89     if (!immediateCommit)
       
    90         disableContentUpdates();
       
    91 
       
    92     m_webView->setScale(value);
       
    93 
       
    94     if (immediateCommit)
       
    95         commitZoom();
       
    96     else
       
    97         m_zoomCommitTimer.start(ZoomCommitDuration);
       
    98 }
       
    99 
       
   100 qreal WebContentAnimationItem::zoomScale() const
       
   101 {
       
   102     if (!m_webView)
       
   103         return 1.;
       
   104 
       
   105     return m_webView->scale();
       
   106 }
       
   107 
       
   108 QRectF WebContentAnimationItem::findZoomableRectForPoint(const QPointF& point)
       
   109 {
       
   110     QPointF zoomPoint = m_webView->mapFromParent(point);
       
   111 
       
   112     QWebHitTestResult hitResult = m_webView->page()->mainFrame()->hitTestContent(zoomPoint.toPoint());
       
   113     QWebElement targetElement = hitResult.enclosingBlockElement();
       
   114 
       
   115     while (!targetElement.isNull() && targetElement.geometry().width() < MinDoubleClickZoomTargetWidth)
       
   116         targetElement = targetElement.parent();
       
   117 
       
   118     if (!targetElement.isNull()) {
       
   119         QRectF elementRect = targetElement.geometry();
       
   120         qreal overMinWidth = elementRect.width() - ZoomableContentMinWidth;
       
   121         if (overMinWidth < 0)
       
   122             elementRect.adjust(overMinWidth / 2, 0, -overMinWidth / 2, 0);
       
   123         zoomPoint.setX(elementRect.x());
       
   124         QRectF resultRect(zoomPoint, elementRect.size());
       
   125         return QRectF(m_webView->mapToParent(resultRect.topLeft()),
       
   126                       m_webView->mapToParent(resultRect.bottomRight()));
       
   127     }
       
   128     return QRectF();
       
   129 }
       
   130 
       
   131 void WebContentAnimationItem::disableContentUpdates()
       
   132 {
       
   133     //Disable tiling updates
       
   134     m_webView->setTiledBackingStoreFrozen(true);
       
   135 }
       
   136 
       
   137 void WebContentAnimationItem::enableContentUpdates()
       
   138 {
       
   139     //Enable tiling updates
       
   140     m_webView->setTiledBackingStoreFrozen(false);
       
   141 }
       
   142 
       
   143 void WebContentAnimationItem::commitZoom()
       
   144 {
       
   145     m_zoomCommitTimer.stop();
       
   146     notifyZoomActions(zoomScale());
       
   147     enableContentUpdates();
       
   148 }
       
   149 
       
   150 void WebContentAnimationItem::resizeEvent(QGraphicsSceneResizeEvent* event)
       
   151 {
       
   152     QGraphicsWidget::resizeEvent(event);
       
   153     setZoomScale(size().width() / contentsSize().width());
       
   154 }
       
   155 
       
   156 void WebContentAnimationItem::notifyZoomActions(qreal newScale)
       
   157 {
       
   158     bool enableZoomIn = false;
       
   159     bool enableZoomOut = false;
       
   160 
       
   161     if (m_viewportMetaData->m_userScalable) {
       
   162 
       
   163         if (newScale > m_viewportMetaData->m_minimumScale)
       
   164             enableZoomOut = true;
       
   165         else
       
   166             enableZoomOut = false;
       
   167 
       
   168         if (newScale < m_viewportMetaData->m_maximumScale)
       
   169             enableZoomIn = true;
       
   170         else
       
   171             enableZoomIn = false;
       
   172 	} 
       
   173 
       
   174     emit updateZoomActions(enableZoomIn, enableZoomOut);
       
   175 }
       
   176 
       
   177 } //namespace GVA