diff -r 000000000000 -r 1450b09d0cfd browsercore/appfw/Api/Views/HistoryView.cpp --- /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 + +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 HistoryView::getContext() +{ + // for now, all actions valid at all times + // but there may be some logic here to determine context + QList 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 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(); + 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(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(m_contentView),SIGNAL(ok(int)),this,SLOT(ok(int))); + disconnect(static_cast(m_contentView),SIGNAL(cancel()),this,SLOT(cancel())); + + disconnect(static_cast(m_contentView),SIGNAL(activated()),this,SIGNAL(activated())); + disconnect(static_cast(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