browsercore/appfw/Api/Views/HistoryView.cpp
changeset 0 1450b09d0cfd
child 3 0954f5dd2cd0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browsercore/appfw/Api/Views/HistoryView.cpp	Tue May 04 12:39:35 2010 +0300
@@ -0,0 +1,480 @@
+/*
+* Copyright (c) 2009 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 "WrtPageManager.h"
+#include "FlowInterface.h"
+#include "HistoryView_p.h"
+#include "HistoryView.h"
+#include "HistoryViewEventContext.h"
+
+#include "qwebhistory.h"
+#include "qwebframe.h"
+#include "wrtbrowsercontainer.h"
+#include "webpagedata.h"
+#include "scriptobjects.h"
+
+#include <QDebug>
+
+namespace WRT {
+
+HistoryViewPrivate::HistoryViewPrivate(WrtPageManager * pageMgr,
+                                       QWidget* parent) :
+    m_flowInterface(0),
+    m_widgetParent(parent),
+    m_graphicsWidgetParent(0),
+    m_pageManager(pageMgr),
+    m_activePage(0),
+    m_historyIndex(0),
+    m_isActive(false)
+{
+    Q_ASSERT(m_pageManager);
+    init();
+}
+
+HistoryViewPrivate::HistoryViewPrivate(WrtPageManager * pageMgr,
+                                       QGraphicsWidget* parent) :
+    m_flowInterface(0),
+    m_widgetParent(0),
+    m_graphicsWidgetParent(parent),
+    m_pageManager(pageMgr),
+    m_activePage(0),
+    m_historyIndex(0),
+    m_isActive(false)
+{
+    Q_ASSERT(m_pageManager);
+    init();
+}
+
+HistoryViewPrivate::~HistoryViewPrivate()
+{
+    delete m_actionForward;
+    delete m_actionBack;
+    delete m_actionOK;
+    delete m_actionCancel;
+}
+
+void HistoryViewPrivate::init()
+{
+    // create the view's actions
+    m_actionForward = new QAction("Forward",m_widgetParent);
+    m_actionForward->setObjectName("Forward");
+    m_actionBack = new QAction("Back",m_widgetParent);
+    m_actionBack->setObjectName("Back");
+    m_actionOK = new QAction("OK",m_widgetParent);
+    m_actionOK->setObjectName("OK");
+    m_actionCancel = new QAction("Cancel",m_widgetParent);
+    m_actionCancel->setObjectName("Cancel");
+}
+
+/*!
+ * \class HistoryView
+ *
+ * \brief The base class for the HistoryViews
+ *
+ * This class provides the basic routines to enable history navigation.
+ * Derived classes (such as HistoryFlowView, and HistoryLiteView) supply
+ * the exact "FlowInterface" to be used, and rely on much of the base-class functionality
+ * for signal/slots, extracting history items from the current page, etc.
+ */
+
+/*!
+  Basic HistoryView constructor requires a PageManager to manage the pages
+  and a parent QWidget
+*/
+HistoryView::HistoryView(WrtPageManager * pageMgr,
+                         QWidget* parent) :
+    d(new HistoryViewPrivate(pageMgr, parent))
+{
+}
+
+/*!
+  Basic HistoryView constructor requires a PageManager to manage the pages
+  and a parent QGraphicsWidget
+*/
+HistoryView::HistoryView(WrtPageManager * pageMgr,
+                         QGraphicsWidget* parent) :
+    d(new HistoryViewPrivate(pageMgr, parent))
+{
+}
+
+
+HistoryView::~HistoryView()
+{
+    delete d;
+}
+
+/*!
+  Retrieve the WrtPageManager assigned to this view
+*/
+WrtPageManager* HistoryView::wrtPageManager()
+{
+    return d->m_pageManager;
+}
+
+/*!
+  Return the view's Forward QAction
+  For scrolling the history view forwards
+*/
+QAction * HistoryView::getActionForward()
+{
+    return d->m_actionForward;
+}
+
+/*!
+  Return the view's Back QAction
+  For scrolling the history view backwards
+*/
+QAction * HistoryView::getActionBack()
+{
+    return d->m_actionBack;
+}
+
+/*!
+  Return the view's OK QAction
+  For invoking the view's OK
+*/
+QAction * HistoryView::getActionOK()
+{
+    return d->m_actionOK;
+}
+
+/*!
+  Return the view's Cancel QAction
+  For invoking the view's Cancel
+*/
+QAction * HistoryView::getActionCancel()
+{
+    return d->m_actionCancel;
+}
+
+/*!
+  Return the widget handle of this view
+*/
+QGraphicsWidget* HistoryView::widget() const
+{
+    return d->m_flowInterface;
+}
+
+/*!
+  Return the title of this view for display
+*/
+QString HistoryView::title() const
+{
+    return QString("History");
+}
+
+/*!
+  Return whether this view is active or not
+*/
+bool HistoryView::isActive()
+{
+    return d->m_isActive;
+}
+
+
+/*!
+  Return the list of public QActions most relevant to the view's current context
+  (most approptiate for contextual menus, etc.
+*/
+QList<QAction*> HistoryView::getContext()
+{
+    // for now, all actions valid at all times
+    // but there may be some logic here to determine context
+    QList<QAction*> contextList;
+    contextList <<
+        d->m_actionForward <<
+        d->m_actionBack <<
+        d->m_actionOK <<
+        d->m_actionCancel;
+    return contextList;
+}
+
+
+
+/*!
+  activate the view's resources. Could be connected by client to view visibility
+*/
+void HistoryView::activate()
+{
+    Q_ASSERT(!d->m_isActive);
+
+    if(!d->m_flowInterface)
+        return;
+
+    d->m_flowInterface->init();
+    updateHistory(true);
+    
+    // now forward visual flow lite's signals
+    connect(d->m_flowInterface, SIGNAL(centerIndexChanged(int)), SIGNAL(centerIndexChanged(int)));
+    connect(d->m_flowInterface, SIGNAL(ok(int)), this, SIGNAL(ok(int)));
+    connect(d->m_flowInterface, SIGNAL(cancel()), this, SIGNAL(cancel()));
+
+    // internally process the index change signal as well, and page load complete
+    connect(d->m_flowInterface, SIGNAL(centerIndexChanged(int)), this, SLOT(updateActions(int)));
+    connect(d->m_pageManager,SIGNAL(loadFinished(bool)),this,SLOT(updateHistory(bool)));
+
+    // auto-link relevant actions to slots
+    connect(d->m_actionForward, SIGNAL(triggered()), this, SLOT(forward()));
+    connect(d->m_actionBack, SIGNAL(triggered()), this, SLOT(back()));
+
+    widget()->installEventFilter(this);
+    connect(this, SIGNAL(contextEvent(QObject *)), jsObject(), SLOT(onContextEvent(QObject *)));
+
+    // show and set index
+    d->m_flowInterface->show();
+    d->m_historyIndex = 0;
+    d->m_isActive = true;
+    
+    emit activated();
+}
+
+/*!
+  deactivate the view's resources. Could be connected by client to view visibility
+*/
+void HistoryView::deactivate()
+{
+    Q_ASSERT(d->m_isActive);
+
+    if(!d->m_flowInterface)
+        return;
+
+    // disconnect signals
+    disconnect(d->m_flowInterface, SIGNAL(centerIndexChanged(int)), this, SIGNAL(centerIndexChanged(int)));
+    disconnect(d->m_flowInterface, SIGNAL(ok(int)), this, SIGNAL(ok(int)));
+    disconnect(d->m_flowInterface, SIGNAL(cancel()), this, SIGNAL(cancel()));
+
+    // internally process the index change signal as well
+    disconnect(d->m_flowInterface, SIGNAL(centerIndexChanged(int)), this, SLOT(updateActions(int)));
+    disconnect(d->m_pageManager,SIGNAL(loadFinished(bool)),this,SLOT(updateHistory(bool)));
+
+    // auto-link relevant actions to slots
+    disconnect(d->m_actionForward, SIGNAL(triggered()), this, SLOT(forward()));
+    disconnect(d->m_actionBack, SIGNAL(triggered()), this, SLOT(back()));
+
+    widget()->removeEventFilter(this);
+    disconnect(this, SIGNAL(contextEvent(QObject *)), jsObject(), SLOT(onContextEvent(QObject *)));
+    
+    // cleanup
+    d->m_flowInterface->deleteLater();
+    d->m_flowInterface = NULL;
+    d->m_isActive = false;
+    
+    emit deactivated();
+}
+
+void HistoryView::updateHistory(bool status)
+{
+    if (!status) {
+        return;
+    }
+
+    if (!d->m_flowInterface) {
+        return;
+    }
+
+    // clear PictureFlow
+    d->m_flowInterface->clear();
+
+    d->m_activePage = d->m_pageManager->currentPage();
+
+    if (d->m_activePage->history()->count() < 0) {
+        return;
+    }
+
+    QWebHistoryItem item = d->m_activePage->history()->currentItem();
+    d->m_activePage->savePageDataToHistoryItem(d->m_activePage->mainFrame(), &item);
+
+    QList<QWebHistoryItem> items = d->m_activePage->history()->items();
+    for (int i = 0; i < d->m_activePage->history()->count(); i++) {
+        QWebHistoryItem item = items.at(i);
+        WebPageData data = item.userData().value<WebPageData>();
+        QImage img = data.m_thumbnail;
+        d->m_flowInterface->addSlide(img);
+    }
+
+    int currentItemIndex(d->m_activePage->history()->currentItemIndex());
+    d->m_flowInterface->setCenterIndex(currentItemIndex);
+    updateActions(currentItemIndex);
+}
+
+int HistoryView::currentIndex() {
+
+    return (d->m_activePage->history()->currentItemIndex());
+}
+
+/*!
+  set the history view's center index
+*/
+void HistoryView::setCenterIndex(int index)
+{
+    // first emit center index change
+    emit centerIndexChanged(index);
+
+    d->m_historyIndex = index - d->m_activePage->history()->currentItemIndex();
+
+    emit titleChanged(itemTitle(d->m_historyIndex));
+
+    //if(d->m_flowInterface)
+    //{
+    //   qDebug() << "Setting center index " << index;
+        //d->m_flowInterface->setCurentIndex(index);
+    //}
+
+}
+
+/*!
+  scroll forward in the history view
+*/
+void HistoryView::forward()
+{
+    if(!d->m_flowInterface)
+        return;
+
+    d->m_flowInterface->showNext();
+}
+
+/*!
+  scroll back in the history view
+*/
+void HistoryView::back()
+{
+    if(!d->m_flowInterface)
+        return;
+
+    d->m_flowInterface->showPrevious();
+}
+
+void HistoryView::updateActions(int centerIndex)
+{
+    d->m_actionBack->setEnabled(centerIndex != 0);
+    d->m_actionForward->setEnabled(centerIndex < (d->m_activePage->history()->count() - 1));
+}
+
+QRect HistoryView::centralRect()
+{
+    if(!d->m_flowInterface)
+        return QRect();
+
+    return d->m_flowInterface->centralRect();
+}
+
+bool HistoryView::eventFilter(QObject *obj, QEvent *event)
+{
+    if (event->type() == QEvent::ContextMenu && obj == widget()) {
+        return handleWidgetContextMenuEvent(static_cast<QContextMenuEvent *>(event));
+    }
+
+    // standard event processing
+    return ControllableViewBase::eventFilter(obj, event);
+}
+
+bool HistoryView::handleWidgetContextMenuEvent(QContextMenuEvent *event)
+{
+//        WRT::HistoryViewEventContext *context = 
+//            new WRT::HistoryViewEventContext(type(), 
+//                                             cmEvent->pos(), 
+//                                             d->m_flowInterface->centerIndex(), 
+//                                             itemTitle(d->m_flowInterface->centerIndex()));
+
+    // Create a javascript-accessible object with properties containing the required info.
+    QObject *context = new QObject();
+    context->setObjectName("historyContextEvent");
+    context->setProperty("viewType", type());
+    context->setProperty("itemIndex", d->m_flowInterface->centerIndex());
+    context->setProperty("itemTitle", itemTitle(d->m_flowInterface->centerIndex()));
+
+    // Create an object representing the position of the event.  Make it a child of the context object
+    // so it can be accessed from javascript.
+    new ScriptPoint(context, event->pos(), "pos");
+    
+    // Pass ownership to the javascript engine.
+    QWebFrame *chrome = chromeFrame();
+    if(chrome) {
+        chrome->addToJavaScriptWindowObject(context->objectName(), context, QScriptEngine::ScriptOwnership);
+    }
+
+    emit contextEvent(context);
+            
+    return true;
+}
+
+QString HistoryView::itemTitle(int index) const
+{
+    QWebHistoryItem item = d->m_activePage->history()->itemAt(d->m_flowInterface->centerIndex());
+    QString title;
+    if (item.isValid()) {
+        title = item.title();
+        if (title.isNull() || title.isEmpty()) {
+            title = item.url().toString();
+        }
+    }
+    return title;
+}
+
+// -------------------------------------------
+
+HistoryViewJSObject::HistoryViewJSObject(HistoryView* view, QWebFrame* webFrame, const QString& objectName)
+  : ControllableViewJSObject(view, webFrame, objectName)
+{
+    connect(view,SIGNAL(ok(int)),this,SLOT(ok(int)));
+    connect(view,SIGNAL(cancel()),this,SLOT(cancel()));
+    
+    connect(view,SIGNAL(activated()),this,SIGNAL(activated()));
+    connect(view,SIGNAL(deactivated()),this,SIGNAL(deactivated()));
+}
+
+HistoryViewJSObject::~HistoryViewJSObject()
+{
+    disconnect(static_cast<HistoryView*>(m_contentView),SIGNAL(ok(int)),this,SLOT(ok(int)));
+    disconnect(static_cast<HistoryView*>(m_contentView),SIGNAL(cancel()),this,SLOT(cancel()));
+    
+    disconnect(static_cast<HistoryView*>(m_contentView),SIGNAL(activated()),this,SIGNAL(activated()));
+    disconnect(static_cast<HistoryView*>(m_contentView),SIGNAL(deactivated()),this,SIGNAL(deactivated()));
+}
+
+void HistoryViewJSObject::ok(int item)
+{
+    emit done(item);
+}
+
+void HistoryViewJSObject::cancel()
+{
+    emit done(historyView()->currentIndex());
+}
+
+void HistoryViewJSObject::onContextEvent(QObject *context){
+    emit contextEvent(context);
+}
+
+/*!
+  \fn void HistoryView::centerIndexChanged(int index);
+  emitted when the center index changed
+*/
+
+/*!
+  \fn void HistoryView::ok(int item);
+  emitted when the ok action has occured, contains history index at the time of close
+*/
+
+/*!
+  \fn void HistoryView::cancel();
+  emitted when the cancel action has occured
+*/
+
+} // namespace WRT