/*
* 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:
*
*/
// Version : %version: 22 %
// INCLUDE FILES
#include <qgraphicswidget.h>
#include <qaction.h>
#include <qactiongroup.h>
#include <hbmenu.h>
#include <hbaction.h>
#include <hbgroupbox.h>
#include <hbpushbutton.h>
#include "videocollectionuiloader.h"
#include "videolistview.h"
#include "videolistselectiondialog.h"
#include "videolistwidget.h"
#include "videohintwidget.h"
#include "videocollectionwrapper.h"
#include "videosortfilterproxymodel.h"
#include "videocollectionviewutils.h"
#include "videoservices.h"
#include "videocollectiontrace.h"
// ---------------------------------------------------------------------------
// VideoCollectionUiLoader
// ---------------------------------------------------------------------------
//
VideoCollectionUiLoader::VideoCollectionUiLoader()
: HbDocumentLoader()
, mTimerId( 0 )
, mSortGroup( 0 )
, mIsService( false )
{
FUNC_LOG;
}
// ---------------------------------------------------------------------------
// VideoCollectionUiLoader
// ---------------------------------------------------------------------------
//
VideoCollectionUiLoader::~VideoCollectionUiLoader()
{
FUNC_LOG;
// delete objects without a parent
while (!mOrphans.isEmpty())
{
delete mOrphans.takeFirst();
}
// kill timer if running
if (mTimerId)
{
killTimer(mTimerId);
mTimerId = 0;
}
// clear queue and hash tables
mQueue.clear();
mDocmls.clear();
mSections.clear();
mObjects.clear();
mPhases.clear();
}
// ---------------------------------------------------------------------------
// load
// ---------------------------------------------------------------------------
//
void VideoCollectionUiLoader::load(const QString &fileName, bool *ok)
{
FUNC_LOG;
if (!mDocmls.contains(fileName))
{
QObjectList list = HbDocumentLoader::load(fileName, ok);
if (ok && *ok)
{
mDocmls.insert(fileName);
}
// add objects without a parent to orphan list
storeOrphans(list);
}
else
{
*ok = true;
}
}
// ---------------------------------------------------------------------------
// load
// ---------------------------------------------------------------------------
//
void VideoCollectionUiLoader::load(const QString &fileName,
const QString §ion,
bool *ok)
{
FUNC_LOG;
if (!mSections.contains(section))
{
QObjectList list = HbDocumentLoader::load(fileName, section, ok);
if (ok && *ok)
{
mSections.insert(section);
}
// add objects without a parent to orphan list
storeOrphans(list);
}
else
{
*ok = true;
}
}
// ---------------------------------------------------------------------------
// addData
// ---------------------------------------------------------------------------
//
void VideoCollectionUiLoader::addData(
QList<VideoCollectionUiLoaderParam> params,
QObject *receiver,
const char *slot)
{
FUNC_LOG;
// go through all parameters and add then in to the queue
foreach (VideoCollectionUiLoaderParam param, params)
{
addToQueue(param, receiver, slot);
}
}
// ---------------------------------------------------------------------------
// loadPhase
// ---------------------------------------------------------------------------
//
void VideoCollectionUiLoader::loadPhase(int loadPhase)
{
FUNC_LOG;
if (!mPhases.contains(loadPhase))
{
mPhases.insert(loadPhase);
if (!mTimerId)
{
runNext();
}
}
}
// ---------------------------------------------------------------------------
// removeOrphanFromList
// ---------------------------------------------------------------------------
//
void VideoCollectionUiLoader::removeOrphanFromList(QObject *object)
{
FUNC_LOG;
// remove from orphan list
if (mOrphans.contains(object))
{
mOrphans.removeOne(object);
}
// remove from initialized objects list
const QString &name = mObjects.key(object);
if (!name.isEmpty())
{
// found from list, remove
mObjects.remove(name);
}
}
// ---------------------------------------------------------------------------
// setIsService
// ---------------------------------------------------------------------------
//
void VideoCollectionUiLoader::setIsService(bool isService)
{
FUNC_LOG;
mIsService = isService;
}
// ---------------------------------------------------------------------------
// doFindWidget
// ---------------------------------------------------------------------------
//
QGraphicsWidget* VideoCollectionUiLoader::doFindWidget(const QString &name, bool loadIfNotFound)
{
FUNC_LOG;
QGraphicsWidget *widget = 0;
// 1. check from hash
if (mObjects.contains(name))
{
widget = qobject_cast<QGraphicsWidget*>(mObjects.value(name));
}
// 2. load from document and initialize
else if (loadIfNotFound)
{
// find object from queue
int index = indexInQueue(name);
if (index != -1)
{
// object found from queue, load and initialize object
const VideoCollectionUiLoaderParam ¶m = mQueue.at(index);
widget = qobject_cast<QGraphicsWidget*>(executeRequest(param));
// object in loading queue, remove it
removeFromQueue(name);
}
else
{
// assuming that docml and section has already been loaded
widget = HbDocumentLoader::findWidget(name);
}
}
return widget;
}
// ---------------------------------------------------------------------------
// doFindObject
// ---------------------------------------------------------------------------
//
QObject* VideoCollectionUiLoader::doFindObject(const QString &name, bool loadIfNotFound)
{
FUNC_LOG;
QObject *object = 0;
// 1. check from hash
if (mObjects.contains(name))
{
object = mObjects.value(name);
}
// 2. load from document and initialize
else if (loadIfNotFound)
{
// find object from queue
int index = indexInQueue(name);
if (index != -1)
{
// object found from queue, load and initialize object
const VideoCollectionUiLoaderParam ¶m = mQueue.at(index);
object = executeRequest(param);
// object in loading queue, remove it
removeFromQueue(name);
}
else
{
// assuming that docml and section has already been loaded
object = HbDocumentLoader::findObject(name);
}
}
return object;
}
// ---------------------------------------------------------------------------
// addToQueue
// ---------------------------------------------------------------------------
//
void VideoCollectionUiLoader::addToQueue(VideoCollectionUiLoaderParam ¶m,
QObject *receiver,
const char *slot)
{
FUNC_LOG;
INFOQSTR_1("VideoCollectionUiLoader::addToQueue() name: %S", param.mName);
// set receiver if not already set
if (!param.mReceiver)
{
param.mReceiver = receiver;
}
// set slot if not already set
if (!param.mMember)
{
param.mMember = slot;
}
// check validity and hit it
if (isValid(param))
{
// add the params in async queue
mQueue.append(param);
}
}
// ---------------------------------------------------------------------------
// getObject
// ---------------------------------------------------------------------------
//
QObject* VideoCollectionUiLoader::getObject(
const VideoCollectionUiLoaderParam ¶m)
{
FUNC_LOG;
QObject *object = 0;
if (param.mIsWidget)
{
object = HbDocumentLoader::findWidget(param.mName);
}
else
{
object = HbDocumentLoader::findObject(param.mName);
}
return object;
}
// ---------------------------------------------------------------------------
// prepareDocmlAndSection
// ---------------------------------------------------------------------------
//
bool VideoCollectionUiLoader::prepareDocmlAndSection(const char *docml,
const char *section)
{
FUNC_LOG;
bool ok = true;
// prepare docml
if (docml && !mDocmls.contains(docml))
{
load(docml, &ok);
}
// prepare section
if (ok && section && !mSections.contains(section))
{
load(docml, section, &ok);
}
return ok;
}
// ---------------------------------------------------------------------------
// initObject
// ---------------------------------------------------------------------------
//
void VideoCollectionUiLoader::initObject(QObject *object,
const QString &name)
{
FUNC_LOG;
if (object)
{
INFOQSTR_1("VideoCollectionUiLoader::initObject() name: %S", name);
VideoCollectionWrapper &wrapper = VideoCollectionWrapper::instance();
if (name.compare(DOCML_NAME_VC_VIDEOLISTWIDGET) == 0)
{
VideoListWidget *videoList = qobject_cast<VideoListWidget*>(object);
if (videoList)
{
VideoSortFilterProxyModel *model =
wrapper.getModel(VideoCollectionCommon::EModelTypeAllVideos);
if(model)
{
VideoCollectionViewUtils::sortModel(model, true, VideoCollectionCommon::ELevelVideos);
// init widget
VideoServices *videoServices = 0;
if (mIsService)
{
videoServices = VideoServices::instance();
}
videoList->initialize(*model, videoServices, VideoCollectionCommon::ELevelVideos);
}
}
}
else if (name.compare(DOCML_NAME_VC_COLLECTIONWIDGET) == 0)
{
VideoSortFilterProxyModel *model = wrapper.getModel(
VideoCollectionCommon::EModelTypeCollections);
if (model)
{
VideoCollectionViewUtils::sortModel(model, true, VideoCollectionCommon::ELevelCategory);
// initialize video collection widget
VideoListWidget *videoList =
qobject_cast<VideoListWidget*>(object);
if (videoList)
{
// init widget
VideoServices *videoServices = 0;
if (mIsService)
{
videoServices = VideoServices::instance();
}
videoList->initialize(*model, videoServices, VideoCollectionCommon::ELevelCategory);
}
}
}
else if (name.compare(DOCML_NAME_VC_COLLECTIONCONTENTWIDGET) == 0)
{
VideoSortFilterProxyModel *model = wrapper.getModel(
VideoCollectionCommon::EModelTypeCollectionContent);
if (model)
{
// collection content contains always a list of videos so we use
// ELevelVideos as target for sorting
VideoCollectionViewUtils::sortModel(model, false, VideoCollectionCommon::ELevelVideos);
VideoListWidget *videoList = qobject_cast<VideoListWidget*>(object);
if (videoList)
{
// init widget
VideoServices *videoServices = 0;
if (mIsService)
{
videoServices = VideoServices::instance();
}
// cannot set level at this point yet: it can be either default or user defined collection
videoList->initialize(*model, videoServices);
}
}
}
else if (name.compare(DOCML_NAME_DIALOG) == 0)
{
// by default, initialize the selection dialog to delete mode
VideoListSelectionDialog *dialog =
qobject_cast<VideoListSelectionDialog*>(object);
if (dialog)
{
dialog->setupContent(VideoListSelectionDialog::EDeleteVideos,
TMPXItemId::InvalidId());
}
}
else if (name.compare(DOCML_NAME_SORT_MENU) == 0)
{
HbMenu *menu = qobject_cast<HbMenu*>(object);
if (menu)
{
// create sort by menu action
mMenuActions[EActionSortBy] = menu->menuAction();
// ensure that all the actions related to sort menu are loaded
// when sort menu is loaded
findObject<HbAction>(DOCML_NAME_SORT_BY_DATE);
findObject<HbAction>(DOCML_NAME_SORT_BY_NAME);
findObject<HbAction>(DOCML_NAME_SORT_BY_NUMBER_OF_ITEMS);
findObject<HbAction>(DOCML_NAME_SORT_BY_SIZE);
// add sub menu actions
if (!mSortGroup)
{
mSortGroup = new QActionGroup(menu);
mSortGroup->addAction(mMenuActions[EActionSortByDate]);
mSortGroup->addAction(mMenuActions[EActionSortByName]);
mSortGroup->addAction(mMenuActions[EACtionSortByItemCount]);
mSortGroup->addAction(mMenuActions[EActionSortBySize]);
// set all sub menu items checkable
foreach (QAction *action, menu->actions())
{
action->setCheckable(true);
}
}
}
}
else if (name.compare(DOCML_NAME_VC_VIDEOHINTWIDGET) == 0)
{
VideoHintWidget *hintWidget = qobject_cast<VideoHintWidget*>(object);
if (hintWidget)
{
hintWidget->initialize();
}
}
else if (name.compare(DOCML_NAME_OPTIONS_MENU) == 0)
{
// ensure that all the actions related to options menu are loaded
// when options menu is loaded
// when applicaton has been launched as a service,
// do not load components which are not required
if(!mIsService)
{
findObject<HbAction>(DOCML_NAME_ADD_TO_COLLECTION);
findObject<HbAction>(DOCML_NAME_CREATE_COLLECTION);
findObject<HbAction>(DOCML_NAME_DELETE_MULTIPLE);
}
}
else if (name.compare(DOCML_NAME_ADD_TO_COLLECTION) == 0)
{
HbAction *action = qobject_cast<HbAction*>(object);
if (action)
{
mMenuActions[EActionAddToCollection] = action;
}
}
else if (name.compare(DOCML_NAME_CREATE_COLLECTION) == 0)
{
HbAction *action = qobject_cast<HbAction*>(object);
if (action)
{
mMenuActions[EActionNewCollection] = action;
}
}
else if (name.compare(DOCML_NAME_DELETE_MULTIPLE) == 0)
{
HbAction *action = qobject_cast<HbAction*>(object);
if (action)
{
mMenuActions[EActionDelete] = action;
}
}
else if (name.compare(DOCML_NAME_SORT_BY_DATE) == 0)
{
HbAction *action = qobject_cast<HbAction*>(object);
if (action)
{
mMenuActions[EActionSortByDate] = action;
}
}
else if (name.compare(DOCML_NAME_SORT_BY_NAME) == 0)
{
HbAction *action = qobject_cast<HbAction*>(object);
if (action)
{
mMenuActions[EActionSortByName] = action;
}
}
else if (name.compare(DOCML_NAME_SORT_BY_NUMBER_OF_ITEMS) == 0)
{
HbAction *action = qobject_cast<HbAction*>(object);
if (action)
{
mMenuActions[EACtionSortByItemCount] = action;
}
}
else if (name.compare(DOCML_NAME_SORT_BY_SIZE) == 0)
{
HbAction *action = qobject_cast<HbAction*>(object);
if (action)
{
mMenuActions[EActionSortBySize] = action;
}
}
}
}
// ---------------------------------------------------------------------------
// executeRequest
// ---------------------------------------------------------------------------
//
QObject* VideoCollectionUiLoader::executeRequest(
const VideoCollectionUiLoaderParam ¶m)
{
FUNC_LOG;
QObject *object = getObject(param);
if (!object)
{
// object was not found, try preparing docml and section
bool ok = prepareDocmlAndSection(param.mDocml, param.mSection);
if (ok)
{
// try to get the object again
object = getObject(param);
}
}
// initialize object if it was found from docml
if (object)
{
if (!mObjects.contains(param.mName))
{
// initialize object
initObject(object, param.mName);
// insert object in hash table
mObjects.insert(param.mName, object);
}
bool ok = connect(
this, SIGNAL(objectReady(QObject*, const QString&)),
param.mReceiver, param.mMember);
if (ok)
{
// signal client and disconnect
emit objectReady(object, param.mName);
disconnect(
this, SIGNAL(objectReady(QObject*, const QString&)),
param.mReceiver, param.mMember);
}
}
return object;
}
// ---------------------------------------------------------------------------
// indexInQueue
// ---------------------------------------------------------------------------
//
int VideoCollectionUiLoader::indexInQueue(const QString &name)
{
FUNC_LOG;
int index = -1;
int count = mQueue.count();
for (int i = 0; i < count; i++)
{
const VideoCollectionUiLoaderParam ¶m = mQueue.at(i);
if (param.mName == name)
{
// found from queue
index = i;
break;
}
}
return index;
}
// ---------------------------------------------------------------------------
// removeFromQueue
// ---------------------------------------------------------------------------
//
void VideoCollectionUiLoader::removeFromQueue(const QString &name)
{
FUNC_LOG;
int count = mQueue.count();
for (int i = 0; i < count; i++)
{
const VideoCollectionUiLoaderParam ¶m = mQueue.at(i);
if (param.mName == name)
{
mQueue.removeAt(i);
break;
}
}
}
// ---------------------------------------------------------------------------
// timerEvent
// ---------------------------------------------------------------------------
//
void VideoCollectionUiLoader::timerEvent(QTimerEvent *event)
{
FUNC_LOG;
if (event)
{
if (event->timerId() == mTimerId)
{
// get current request from queue and execute it
int count = mQueue.count();
for (int i = 0; i < count; i++)
{
const VideoCollectionUiLoaderParam ¶m = mQueue.at(i);
if (mPhases.contains(param.mPhase))
{
// load and initialize
executeRequest(param);
// remove the current request from queue and run next
removeFromQueue(param.mName);
break;
}
}
runNext();
}
}
}
// ---------------------------------------------------------------------------
// createObject
// ---------------------------------------------------------------------------
//
QObject* VideoCollectionUiLoader::createObject( const QString& type, const QString &name )
{
FUNC_LOG;
QObject* object = 0;
if ( type == VideoListView::staticMetaObject.className() )
{
object = new VideoListView(this);
}
else if ( type == VideoListSelectionDialog::staticMetaObject.className() )
{
object = new VideoListSelectionDialog(this);
}
else if ( type == VideoListWidget::staticMetaObject.className() )
{
object = new VideoListWidget(this);
}
else if ( type == VideoHintWidget::staticMetaObject.className() )
{
object = new VideoHintWidget(this);
}
if ( object )
{
object->setObjectName( name );
return object;
}
return HbDocumentLoader::createObject( type, name );
}
// ---------------------------------------------------------------------------
// runNext
// ---------------------------------------------------------------------------
//
void VideoCollectionUiLoader::runNext()
{
FUNC_LOG;
bool runNext = false;
int count = mQueue.count();
for (int i = 0; i < count; i++)
{
const VideoCollectionUiLoaderParam ¶m = mQueue.at(i);
if (mPhases.contains(param.mPhase))
{
runNext = true;
break;
}
}
if (runNext)
{
if (!mTimerId)
{
// timer not running, start it
mTimerId = startTimer(ASYNC_FIND_TIMEOUT);
}
}
else
{
// no new requests, kill timer
if (mTimerId)
{
killTimer(mTimerId);
mTimerId = 0;
}
}
}
// ---------------------------------------------------------------------------
// isValid
// ---------------------------------------------------------------------------
//
bool VideoCollectionUiLoader::isValid(const VideoCollectionUiLoaderParam ¶m)
{
bool valid = true;
if (param.mName.length() &&
param.mDocml &&
param.mMember &&
param.mReceiver)
{
// check if the param is already in the queue
int count = mQueue.count();
for (int i = 0; i < count; i++)
{
if (mQueue.at(i) == param)
{
INFO("VideoCollectionUiLoader::isValid() already in queue.");
valid = false;
break;
}
}
// check that the item has not already been loaded
if (valid)
{
valid = !mObjects.contains(param.mName);
}
}
else
{
INFO("VideoCollectionUiLoader::isValid() params missing.");
valid = false;
}
return valid;
}
// ---------------------------------------------------------------------------
// storeOrphans
// ---------------------------------------------------------------------------
//
void VideoCollectionUiLoader::storeOrphans(const QObjectList &list)
{
FUNC_LOG;
foreach (QObject *object, list)
{
if (!mOrphans.contains(object))
{
// add to list
mOrphans.append(object);
// connect to "destroyed" signal
connect(
object, SIGNAL(destroyed(QObject*)),
this, SLOT(removeOrphanFromList(QObject*)));
}
}
}
// end of file