videocollection/videocollectionview/src/videolistwidget.cpp
changeset 15 cf5481c2bc0b
child 17 69946d1824c4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/videocollection/videocollectionview/src/videolistwidget.cpp	Fri Apr 16 14:59:52 2010 +0300
@@ -0,0 +1,716 @@
+/*
+* Copyright (c) 2008 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:   Videolist content widget implementation
+*
+*/
+
+#include "videolistwidget.h"
+
+#include <qcoreapplication.h>
+#include <qtimer.h>
+#include <hbscrollbar.h>
+#include <xqserviceutil.h>
+#include <hbmenu.h>
+#include <hbaction.h>
+#include <hbinstance.h>
+#include <hbmainwindow.h>
+#include <hblistviewitem.h>
+#include <hbmessagebox.h>
+#include <vcxmyvideosdefs.h>
+
+#include "videocollectionviewutils.h"
+#include "videocollectionuiloader.h"
+#include "videolistselectiondialog.h"
+#include "videoservices.h"
+#include "videothumbnaildata.h"
+#include "videosortfilterproxymodel.h"
+#include "videocollectioncommon.h"
+#include "mpxhbvideocommondefs.h"
+
+// Interval in ms to report the scroll position.
+const int SCROLL_POSITION_TIMER_TIMEOUT = 100;
+
+// ---------------------------------------------------------------------------
+// Constructor
+// ---------------------------------------------------------------------------
+//
+VideoListWidget::VideoListWidget(VideoCollectionUiLoader *uiLoader, HbView *parent) :
+HbListView(parent),
+mModel(0),
+mVideoServices(0),
+mCurrentLevel(VideoCollectionCommon::ELevelInvalid),
+mSignalsConnected(false),
+mIsService(false),
+mNavKeyBackAction(0),
+mNavKeyQuitAction(0),
+mContextMenu(0),
+mSelectionMode(HbAbstractItemView::NoSelection),
+mScrollPositionTimer(0),
+mUiLoader(uiLoader)
+{
+    // NOP
+}
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+VideoListWidget::~VideoListWidget()
+{
+    delete mScrollPositionTimer;
+    mScrollPositionTimer = 0;
+	mContextMenuActions.clear();
+	disconnect();
+    delete mContextMenu;
+    mContextMenu = 0;
+    delete mNavKeyBackAction;
+    mNavKeyBackAction = 0;
+    delete mNavKeyQuitAction;
+    mNavKeyQuitAction = 0;
+}
+
+// ---------------------------------------------------------------------------
+// initialize
+// ---------------------------------------------------------------------------
+//
+int VideoListWidget::initialize(VideoSortFilterProxyModel &model, VideoServices* videoServices)
+{
+    mModel = &model;
+
+	mVideoServices = videoServices;
+
+	if(mVideoServices)
+	{
+		mIsService = true;
+	}
+
+    // init list view
+    VideoCollectionViewUtils::initListView(this);
+
+    // Navigation keys.
+    mNavKeyBackAction = new HbAction(Hb::BackNaviAction);
+	
+    mNavKeyQuitAction = new HbAction(Hb::QuitNaviAction);
+
+	mScrollPositionTimer = new QTimer();
+	mScrollPositionTimer->setSingleShot(true);
+
+	if (mIsService)
+	{
+		connect(this, SIGNAL(fileUri(const QString&)), mVideoServices, SLOT(itemSelected(const QString&)));
+	}
+
+	setModel(mModel);
+	
+    return 0;
+}
+
+// ---------------------------------------------------------------------------
+// activate
+// ---------------------------------------------------------------------------
+//
+int VideoListWidget::activate()
+{
+    return activate(mCurrentLevel);
+}
+
+// ---------------------------------------------------------------------------
+// activate
+// ---------------------------------------------------------------------------
+//
+int VideoListWidget::activate(VideoCollectionCommon::TCollectionLevels level)
+{
+    if(!mModel)
+    {
+        return -1;
+    }
+    
+	mCurrentLevel = level;
+    setVisible(true);
+
+    if ( connectSignals() < 0)
+    {
+        return -1;
+    }
+
+    HbView *currentView = hbInstance->allMainWindows().value(0)->currentView();
+
+    // Set navigation key only when widget is not in selection mode.
+    if(currentView && mSelectionMode == HbAbstractItemView::NoSelection)
+    {
+        if(level != VideoCollectionCommon::ELevelDefaultColl && 
+           level != VideoCollectionCommon::ELevelAlbum)
+        {
+            if(mNavKeyQuitAction)
+            {
+                currentView->setNavigationAction(mNavKeyQuitAction);
+            }
+        }
+        else if(mNavKeyBackAction)
+        {
+            currentView->setNavigationAction(mNavKeyBackAction);
+        }
+    }
+    // open model to the current level in case not in album or category
+    if(level != VideoCollectionCommon::ELevelAlbum &&
+        level != VideoCollectionCommon::ELevelDefaultColl)
+    {
+         mModel->open(level);
+    }
+    
+    // Enable thumbnail background fetching.
+    VideoThumbnailData &thumbnailData = VideoThumbnailData::instance();
+    thumbnailData.enableBackgroundFetching(true);
+    thumbnailData.startBackgroundFetching(mModel, 0);
+
+    return 0;
+}
+
+// ---------------------------------------------------------------------------
+// deactivate
+// ---------------------------------------------------------------------------
+//
+void VideoListWidget::deactivate()
+{
+    if(mContextMenu) 
+    {
+        mContextMenu->hide();
+    }
+
+    setVisible(false);
+    disConnectSignals();
+    
+    // Free allocated memory for list thumbnails and disable background fetching.
+    VideoThumbnailData &thumbnailData = VideoThumbnailData::instance();
+    thumbnailData.enableBackgroundFetching(false);
+    thumbnailData.freeThumbnailData();
+}
+
+// ---------------------------------------------------------------------------
+// getLevel
+// ---------------------------------------------------------------------------
+//
+VideoCollectionCommon::TCollectionLevels VideoListWidget::getLevel()
+{
+    return mCurrentLevel;
+}
+
+// ---------------------------------------------------------------------------
+// connectSignals
+// ---------------------------------------------------------------------------
+//
+int VideoListWidget::connectSignals()
+{
+    if (!mSignalsConnected)
+    {
+        if(!connect(this, SIGNAL(scrollingStarted()), this, SLOT(scrollingStartedSlot())) ||
+           !connect(this, SIGNAL(scrollingEnded()), this, SLOT(scrollingEndedSlot())) ||
+           !connect(this, SIGNAL(scrollPositionChanged(const QPointF &)), 
+                   this, SLOT(scrollPositionChangedSlot(const QPointF &))) ||
+           !connect(mScrollPositionTimer, SIGNAL(timeout()), this, SLOT(scrollPositionTimerSlot())) || 
+           !connect(mNavKeyBackAction, SIGNAL(triggered()), this, SLOT(back())) ||
+           !connect(mNavKeyQuitAction, SIGNAL(triggered()), qApp, SLOT(quit()))) 
+        {
+            return -1;
+        }
+        mSignalsConnected = true;
+    }
+	return 0;
+}
+
+// ---------------------------------------------------------------------------
+// disConnectSignals
+// ---------------------------------------------------------------------------
+//
+void VideoListWidget::disConnectSignals()
+{
+    disconnect(this, SIGNAL(scrollingStarted()), this, SLOT(scrollingStartedSlot()));
+    disconnect(this, SIGNAL(scrollingEnded()), this, SLOT(scrollingEndedSlot()));
+    disconnect(this, SIGNAL(scrollPositionChanged(const QPointF&)), 
+               this, SLOT(scrollPositionChangedSlot(const QPointF&)));
+    disconnect(mScrollPositionTimer, SIGNAL(timeout()), this, SLOT(scrollPositionTimerSlot()));
+    disconnect(mNavKeyBackAction, SIGNAL(triggered()), this, SLOT(back()));
+    disconnect(mNavKeyQuitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
+
+	mSignalsConnected = false;
+}
+
+// ---------------------------------------------------------------------------
+// deleteItemSlot
+// ---------------------------------------------------------------------------
+//
+void VideoListWidget::deleteItemSlot()
+{
+    if(!mModel)
+    {
+        return;
+    }
+    
+    QVariant variant;
+    QModelIndex index = currentIndex();
+    variant = mModel->data(index, Qt::DisplayRole);
+
+    if (variant.isValid())
+    {
+        QString text = hbTrId("txt_videos_info_do_you_want_to_delete_1").arg(
+                variant.toStringList().first());
+        if(HbMessageBox::question(text))
+        {
+            QModelIndexList list;
+            list.append(index);
+            mModel->deleteItems(list);
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+// createContextMenu
+// ---------------------------------------------------------------------------
+//
+void VideoListWidget::createContextMenu()
+{
+    if(mContextMenu)
+    {
+        return;
+    }
+    
+    mContextMenu = new HbMenu();
+    if (mContextMenu)
+    {
+        mContextMenu->setDismissPolicy(HbPopup::TapAnywhere);
+        if (mIsService)
+        {
+            mContextMenuActions[EActionPlay]    = 
+                    mContextMenu->addAction(hbTrId("txt_videos_menu_play"), this, SLOT(playItemSlot())); 
+            mContextMenuActions[EActionDetails] = 
+                    mContextMenu->addAction(hbTrId("txt_common_menu_details"), this, SLOT(openDetailsSlot()));
+        }
+        else
+        {
+            mContextMenuActions[EActionAddToCollection] = 
+                    mContextMenu->addAction(hbTrId("txt_videos_menu_add_to_collection"), this, SLOT(addToCollectionSlot()));
+            mContextMenuActions[EActionRemove]           = 
+                    mContextMenu->addAction(hbTrId("txt_videos_menu_remove_from_collection"), this, SLOT(removeFromCollectionSlot()));
+            mContextMenuActions[EActionRename]           = 
+                    mContextMenu->addAction(hbTrId("txt_common_menu_rename_item"), this, SLOT(renameSlot()));
+            mContextMenuActions[EActionRemoveCollection] = 
+                    mContextMenu->addAction(hbTrId("txt_videos_menu_remove_collection"), this, SLOT(removeCollectionSlot()));   
+            mContextMenuActions[EActionDelete]           = 
+                    mContextMenu->addAction(hbTrId("txt_common_menu_delete"), this, SLOT(deleteItemSlot()));
+            mContextMenuActions[EActionDetails]          = 
+                    mContextMenu->addAction(hbTrId("txt_common_menu_details"), this, SLOT(openDetailsSlot()));
+        }
+    }
+}
+
+// -------------------------------------------------------------------------------------------------
+// setContextMenu
+// -------------------------------------------------------------------------------------------------
+//
+void VideoListWidget::setContextMenu()
+{
+    if(!mContextMenu)
+    {
+        createContextMenu();
+    }
+    
+    if (!mContextMenu)
+    {
+        // failed to create context menu, return
+        return;
+    }
+    
+	int menuActionCount = 0;
+    HbAction *action = 0;
+    foreach(action, mContextMenuActions.values())
+    {
+        if(action)
+        {
+			++menuActionCount;
+			action->setVisible(false);
+        }
+    }
+    if(menuActionCount != mContextMenuActions.values().count() || mContextMenuActions.values().count() == 0)
+    {
+    	// fatal error, some action(s) was not created before.
+        delete mContextMenu;
+        mContextMenu = 0;
+        mContextMenuActions.clear();
+    	return;
+    }
+
+    HbMainWindow *mainWnd = hbInstance->allMainWindows().value(0);
+
+    if(mCurrentLevel == VideoCollectionCommon::ELevelVideos ||
+       mCurrentLevel == VideoCollectionCommon::ELevelDefaultColl)
+    {
+    	if (!mIsService)
+    	{
+			mContextMenuActions[EActionAddToCollection]->setVisible(true);
+    		mContextMenuActions[EActionDelete]->setVisible(true);
+    	}
+    	else
+    	{
+    		mContextMenuActions[EActionPlay]->setVisible(true);
+    	}
+		mContextMenuActions[EActionDetails]->setVisible(true);
+    }
+    else if(mCurrentLevel == VideoCollectionCommon::ELevelCategory) 
+    {
+		if(!mIsService)
+		{
+            mContextMenuActions[EActionRename]->setVisible(true);
+            mContextMenuActions[EActionRemoveCollection]->setVisible(true);
+		}
+    }
+    else if(mCurrentLevel == VideoCollectionCommon::ELevelAlbum)
+    {
+    	if (!mIsService)
+    	{
+			mContextMenuActions[EActionRemove]->setVisible(true);
+            mContextMenuActions[EActionDelete]->setVisible(true);
+    	}
+    	else
+    	{
+    		mContextMenuActions[EActionPlay]->setVisible(true);
+    	}
+		mContextMenuActions[EActionDetails]->setVisible(true);
+    }
+}
+
+
+// ---------------------------------------------------------------------------
+// getModel
+// ---------------------------------------------------------------------------
+//
+VideoSortFilterProxyModel& VideoListWidget::getModel()
+{ 
+    return *mModel; 
+}
+
+// ---------------------------------------------------------------------------
+// emitActivated
+// This slot is called by the fw when viewitem is activated
+// ---------------------------------------------------------------------------
+//
+void VideoListWidget::emitActivated (const QModelIndex &modelIndex)
+{
+    // surprisingly interenting feature: after long press also single press
+    // is executed. as a workaround the following hack check is needed.
+    // otherwise after the context menu is shown also single press action
+    // is executed.
+    if (mContextMenu &&
+        mContextMenu->isVisible())
+    {
+        // do not activate context menu if it is already visible
+        return;
+    }
+    
+    if(mSelectionMode != HbAbstractItemView::NoSelection)
+    {
+        // no custom functionality defined
+        emit activated(modelIndex);
+        return;
+    }
+
+    if (!mModel || !modelIndex.isValid())
+    {
+        return;
+    }
+    
+    if (mCurrentLevel == VideoCollectionCommon::ELevelCategory)
+    {
+        QVariant variant = mModel->data(modelIndex, Qt::DisplayRole);
+        if (variant.isValid())
+        {
+            // signal view that item has been activated
+            emit(collectionOpened(true,
+                variant.toStringList().first(),
+                modelIndex));                       
+        }
+        return;
+    }
+    if(mIsService && (mCurrentLevel != VideoCollectionCommon::ELevelCategory))
+    {
+    	QVariant variant = mModel->data(modelIndex, VideoCollectionCommon::KeyFilePath);
+		if ( variant.isValid()  )
+		{
+			QString itemPath = variant.value<QString>();
+			emit(fileUri(itemPath));
+		}
+    }
+    else
+    {
+    	mModel->openItem(mModel->getMediaIdAtIndex(modelIndex));
+    }
+}
+
+// ---------------------------------------------------------------------------
+// setSelectionMode
+// called by the fw when user long presses some item
+// ---------------------------------------------------------------------------
+//
+//
+void VideoListWidget::setSelectionMode(int mode)
+{
+    HbAbstractItemView::SelectionMode selMode = HbAbstractItemView::NoSelection;
+    if(mode >= HbAbstractItemView::NoSelection && mode <= HbAbstractItemView::ContiguousSelection)
+    {
+        selMode = HbAbstractItemView::SelectionMode(mode);
+    }
+
+    HbListView::setSelectionMode(selMode);
+    mSelectionMode = mode;
+}
+
+// ---------------------------------------------------------------------------
+// longPressGesture
+// called by the fw when user long presses some item
+// ---------------------------------------------------------------------------
+//
+//
+void VideoListWidget::longPressGesture (const QPointF &point)
+{
+    if(mSelectionMode != HbAbstractItemView::NoSelection)
+    {
+        // do not activate context menu during selection mode
+        return;
+    }
+
+    HbAbstractViewItem *viewItem = itemAtPosition(point);
+    if (viewItem)
+    {
+        QModelIndex index = viewItem->modelIndex();
+        if(mModel && index.isValid())
+        {   
+            TMPXItemId mpxId = mModel->getMediaIdAtIndex(index);
+            // Only videos and user created albums have context menu.
+            if((mpxId.iId2 == KVcxMvcMediaTypeVideo) ||
+               (!mIsService && mpxId.iId2 == KVcxMvcMediaTypeAlbum ))
+            {
+                setContextMenu();
+                // if menu not yet exists, it has been created
+                // setup might fail causing menu to be removed
+                if(mContextMenu)
+                {
+                    mContextMenu->setPreferredPos(point);
+                    mContextMenu->show();
+                }
+            }
+        }
+    }
+	HbListView::longPressGesture(point);
+}
+
+// ---------------------------------------------------------------------------
+// doDelayedsSlot
+// ---------------------------------------------------------------------------
+//
+void VideoListWidget::doDelayedsSlot()
+{
+	if (!mContextMenu)
+	{
+		createContextMenu();
+	}
+}
+
+// ---------------------------------------------------------------------------
+// playItemSlot
+// ---------------------------------------------------------------------------
+//
+void VideoListWidget::playItemSlot()
+{
+    mModel->openItem(mModel->getMediaIdAtIndex(currentIndex()));
+}
+
+// ---------------------------------------------------------------------------
+// openDetailsSlot
+// ---------------------------------------------------------------------------
+//
+void VideoListWidget::openDetailsSlot()
+{   
+    if(mModel && mModel->fetchItemDetails(currentIndex()) == 0 ) 
+    {
+        emit command(MpxHbVideoCommon::ActivateVideoDetailsView);
+    }
+}
+
+// ---------------------------------------------------------------------------
+// renameSlot
+// ---------------------------------------------------------------------------
+//
+void VideoListWidget::renameSlot()
+{
+	debugNotImplementedYet();
+}
+
+// ---------------------------------------------------------------------------
+// addToCollectionSlot
+// ---------------------------------------------------------------------------
+//
+void VideoListWidget::addToCollectionSlot()
+{
+    VideoListSelectionDialog *dialog =
+       mUiLoader->findWidget<VideoListSelectionDialog>(
+           DOCML_NAME_DIALOG);
+    if (!dialog || !mModel)
+    {
+        return;
+    }
+    TMPXItemId itemId = mModel->getMediaIdAtIndex(currentIndex());
+    if(itemId != TMPXItemId::InvalidId())
+    {
+        dialog->setupContent(VideoListSelectionDialog::ESelectCollection, itemId);
+        dialog->exec();
+    }
+}
+
+// ---------------------------------------------------------------------------
+// removeFromCollectionSlot
+// ---------------------------------------------------------------------------
+//
+void VideoListWidget::removeFromCollectionSlot()
+{
+    if(!mModel)
+    {
+        return;
+    }
+    TMPXItemId collectionId = mModel->getOpenItem();
+    TMPXItemId itemId = mModel->getMediaIdAtIndex(currentIndex());
+    if(collectionId != TMPXItemId::InvalidId() && 
+       itemId != TMPXItemId::InvalidId())
+    {
+        QList<TMPXItemId> ids;
+        ids.append(itemId);
+        mModel->removeItemsFromAlbum(collectionId, ids);
+    }
+}
+
+// ---------------------------------------------------------------------------
+// removeCollectionSlot
+// ---------------------------------------------------------------------------
+//
+void VideoListWidget::removeCollectionSlot()
+{
+    if(!mModel)
+    {
+        return;
+    }
+    
+    QVariant variant;
+    QModelIndex index = currentIndex();
+    variant = mModel->data(index, Qt::DisplayRole);
+
+    if (variant.isValid())
+    {
+        QString text = tr("Do you want to remove collection \"%1\"?").arg( //TODO: localisation
+                variant.toStringList().first());
+        if(HbMessageBox::question(text))
+        {
+            QModelIndexList list;
+            list.append(index);
+        	mModel->removeAlbums(list);
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+// playAllSlot
+// ---------------------------------------------------------------------------
+//
+void VideoListWidget::playAllSlot()
+{
+	debugNotImplementedYet();
+}
+
+// ---------------------------------------------------------------------------
+// back
+// ---------------------------------------------------------------------------
+//
+void VideoListWidget::back()
+{
+	// Empty the proxy model causing the items to be removed from list widget.
+    mModel->setAlbumInUse(TMPXItemId::InvalidId());
+    if(mModel)
+    {
+        emit collectionOpened(false, QString(), QModelIndex());
+    }
+}
+
+// ---------------------------------------------------------------------------
+// scrollingStartedSlot
+// ---------------------------------------------------------------------------
+//
+void VideoListWidget::scrollingStartedSlot()
+{
+    VideoThumbnailData::instance().enableThumbnailCreation(false);
+}
+
+// ---------------------------------------------------------------------------
+// scrollingEndedSlot
+// ---------------------------------------------------------------------------
+//
+void VideoListWidget::scrollingEndedSlot()
+{
+    if(mScrollPositionTimer)
+        mScrollPositionTimer->stop();	
+    VideoThumbnailData::instance().enableThumbnailCreation(true);
+    fetchThumbnailsForVisibleItems();
+}
+
+// ---------------------------------------------------------------------------
+// scrollPositionChangedSlot
+// ---------------------------------------------------------------------------
+//
+void VideoListWidget::scrollPositionChangedSlot(const QPointF &newPosition)
+{
+    Q_UNUSED(newPosition);
+	if(mScrollPositionTimer && !mScrollPositionTimer->isActive())
+	    mScrollPositionTimer->start(SCROLL_POSITION_TIMER_TIMEOUT);
+}
+
+// ---------------------------------------------------------------------------
+// scrollPositionTimerSlot
+// ---------------------------------------------------------------------------
+//
+void VideoListWidget::scrollPositionTimerSlot()
+{
+    fetchThumbnailsForVisibleItems();
+}
+
+// ---------------------------------------------------------------------------
+// fetchThumbnailsForVisibleItems
+// ---------------------------------------------------------------------------
+//
+void VideoListWidget::fetchThumbnailsForVisibleItems()
+{
+    const QList<HbAbstractViewItem *> itemsVisible = visibleItems();
+
+    if(itemsVisible.count() > 0)
+    {
+        int row = itemsVisible.value(0)->modelIndex().row();
+        VideoThumbnailData::instance().startBackgroundFetching(mModel, row);
+    }
+}
+
+// ---------------------------------------------------------------------------
+// debugNotImplementedYet
+// ---------------------------------------------------------------------------
+//
+void VideoListWidget::debugNotImplementedYet()
+{
+    HbMessageBox::information(tr("Not implemented yet"));
+}
+
+// end of file