videocollection/videocollectionview/src/videolistselectiondialog.cpp
changeset 15 cf5481c2bc0b
child 17 69946d1824c4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/videocollection/videocollectionview/src/videolistselectiondialog.cpp	Fri Apr 16 14:59:52 2010 +0300
@@ -0,0 +1,619 @@
+/*
+* 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 selection dialog implementation
+* 
+*/
+
+#include <QGraphicsItem>
+#include <hblabel.h>
+#include <hbcheckbox.h>
+#include <hbaction.h>
+#include <hbstackedwidget.h>
+#include <hbabstractitemview.h>
+#include <hbinputdialog.h>
+#include <vcxmyvideosdefs.h>
+
+#include "videocollectionuiloader.h"
+#include "videolistwidget.h"
+#include "videosortfilterproxymodel.h"
+#include "videolistselectiondialog.h"
+#include "videocollectionwrapper.h"
+#include "videocollectionviewutils.h"
+#include "videocollectionclient.h"
+
+/**
+ * global qHash function required fo creating hash values for TMPXItemId -keys
+ */
+inline uint qHash(TMPXItemId key) 
+{ 
+    QPair<uint, uint> keyPair(key.iId1, key.iId2); 
+
+    return qHash(keyPair);
+}
+
+// ---------------------------------------------------------------------------
+// VideoListSelectionDialog
+// ---------------------------------------------------------------------------
+//
+VideoListSelectionDialog::VideoListSelectionDialog(VideoCollectionUiLoader *uiLoader,
+                                                   QGraphicsItem *parent) : 
+HbDialog(parent),
+mUiLoader(uiLoader),
+mTypeOfSelection(-1),
+mHeading(0),
+mCheckboxContainer(0),
+mItemCount(0),
+mCheckBox(0),
+mListContainer(0),
+mForcedCheck(false),
+mModel(0),
+mListWidget(0)
+{
+    setDismissPolicy(HbDialog::NoDismiss);
+    setTimeout(HbDialog::NoTimeout);    
+
+    // create model for list widget
+    mModel =
+        VideoCollectionWrapper::instance().getModel(
+            VideoCollectionWrapper::EGeneric);
+    if (mModel)
+    {
+        // create list widget
+        mListWidget = new VideoListWidget(mUiLoader);
+        if (mListWidget)
+        {
+            if(mListWidget->initialize(*mModel) < 0)
+            {
+                delete mListWidget;
+                mListWidget = 0;
+            }
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+// ~VideoListSelectionDialog
+// ---------------------------------------------------------------------------
+//
+VideoListSelectionDialog::~VideoListSelectionDialog() 
+{
+    delete mListWidget;
+}
+
+// ---------------------------------------------------------------------------
+// setupContent
+// ---------------------------------------------------------------------------
+//
+void VideoListSelectionDialog::setupContent(int type, TMPXItemId activeItem)
+{
+    if(type < EDeleteVideos || type > ESelectCollection)
+    {
+        return;
+    }
+   
+    mTypeOfSelection = type; 
+    if(!initDialog())
+    {
+        return;
+    }
+    mSelection.clear();
+    mSelectedVideos.clear();
+    mSelectedAlbumId = TMPXItemId::InvalidId();
+    
+    // if provided "owner" is album or category    
+    if(activeItem != TMPXItemId::InvalidId())
+    {
+        // if album, set as "selected"
+        if(activeItem.iId2 == KVcxMvcMediaTypeAlbum)
+        {
+            mSelectedAlbumId = activeItem;
+        }
+        else if(activeItem.iId2 == KVcxMvcMediaTypeVideo)
+        {
+            mSelectedVideos.insert(activeItem);
+        }
+    }
+    // set (or reset) generic id filter
+    bool filterValue = true;
+    if(mTypeOfSelection == EAddToCollection || mTypeOfSelection == ESelectCollection)
+    {
+        filterValue = false;
+    }
+    mModel->setGenericIdFilter(activeItem, filterValue);    
+    activateSelection();
+}
+
+// ---------------------------------------------------------------------------
+// initDialog
+// ---------------------------------------------------------------------------
+//
+bool VideoListSelectionDialog::initDialog()
+{
+    if(!mModel)
+    {
+        mModel = VideoCollectionWrapper::instance().getModel(VideoCollectionWrapper::EGeneric);
+        if (!mModel)
+        {
+           return false;
+        }
+    }  
+    if (!mListContainer)
+    {
+        mListContainer =
+                   mUiLoader->findWidget<HbStackedWidget>(DOCML_NAME_LIST_CONTAINER);
+    
+        if(!mListWidget)
+        {
+            mListWidget = new VideoListWidget(mUiLoader);
+            if(mListWidget->initialize(*mModel) < 0)
+            {
+                delete mListWidget;
+                mListWidget = 0;
+                mListContainer = 0;
+                return false;
+            }
+        }
+        if(mListContainer)
+        {
+            mListContainer->addWidget(mListWidget);
+        }
+    }
+
+    if(!mHeading)
+    {
+        mHeading = mUiLoader->findWidget<HbLabel>(DOCML_NAME_DLG_HEADINGLBL);
+    }
+    if(!mCheckboxContainer)
+    {
+        mCheckboxContainer = mUiLoader->findWidget<HbWidget>(DOCML_NAME_CHECK_CONTAINER);
+    }
+
+    if(!mItemCount)
+    {
+        mItemCount = mUiLoader->findWidget<HbLabel>(DOCML_NAME_LBL_SELECTION);
+        mItemCount->setAlignment(Qt::AlignRight);
+    }        
+    if(!mCheckBox)
+    {
+        mCheckBox = mUiLoader->findWidget<HbCheckBox >(DOCML_NAME_MARKALL);
+    }
+    if(!primaryAction())
+    {
+        setPrimaryAction(new HbAction(hbTrId("txt_common_button_ok"), this));
+    }
+    if(!secondaryAction())
+    {
+        setSecondaryAction(new HbAction(hbTrId("txt_common_button_cancel"), this));
+    }
+    if(!mListWidget || !mListContainer || !mHeading || !mCheckBox || !primaryAction() || !secondaryAction())
+    {
+        return false;
+    }
+    return true;  
+}
+
+// ---------------------------------------------------------------------------
+// activateSelection
+// ---------------------------------------------------------------------------
+//
+void VideoListSelectionDialog::activateSelection()
+{
+    // "add to collection" and "remove from collection -selections needs 
+    // additional functionality for primary key
+    if(mTypeOfSelection == EAddToCollection ||
+       mTypeOfSelection == ERemoveFromCollection)
+    {
+        primaryAction()->disconnect(SIGNAL(triggered()));
+        connect(primaryAction(), SIGNAL(triggered()), this, SLOT(primaryActionTriggeredSlot()));
+    }
+    QString headingTxt("");
+    QString primaryTxt("");
+    // create texts
+    switch(mTypeOfSelection)
+    {
+    case EDeleteVideos:
+        primaryTxt = hbTrId("txt_common_button_delete");
+    break;
+    case EAddToCollection:
+        primaryTxt = hbTrId("txt_common_button_add");
+    break;
+    case ERemoveFromCollection:
+        primaryTxt = hbTrId("txt_common_button_remove");
+    break;
+    case ESelectCollection:
+        primaryTxt = hbTrId("txt_videos_button_new");
+    break;
+    default:
+    break;
+    }
+
+    HbAction *primary = primaryAction();
+    primary->setText(primaryTxt);
+
+    if(mTypeOfSelection == ESelectCollection)
+    {
+        headingTxt = hbTrId("txt_videos_title_select_collection");
+        mCheckboxContainer->setVisible(false);
+        mListWidget->setSelectionMode(-1);   
+        mListWidget->activate(VideoCollectionCommon::ELevelCategory);
+        // need to set primaryaction disabled here in order for it 
+        // get correctly updated at modelReady(), where it will be enabled
+        // if state would be same, no update will happen
+        primary->setDisabled(true);
+    }
+    else
+    {
+        headingTxt = hbTrId("txt_videos_title_select_videos");
+        mListWidget->setSelectionMode(HbAbstractItemView::MultiSelection);
+        mListWidget->activate(VideoCollectionCommon::ELevelVideos);
+        mCheckboxContainer->setVisible(true);
+        mItemCount->setPlainText(tr("0/%1").arg(mModel->rowCount())); 
+        mCheckBox->setChecked(false);
+        // need to set primaryaction enabled here in order for it 
+        // get correctly updated at modelReady(), where it will be disabled  
+        // if state would be same, no update will happen
+        primary->setDisabled(false);
+    }
+    mHeading->setPlainText(headingTxt);         
+    // sort to make sure dialog has correctly filtered content
+    // at the same order as in view
+    VideoCollectionViewUtils::sortModel(mModel, false);        
+}
+
+// ---------------------------------------------------------------------------
+// exec
+// ---------------------------------------------------------------------------
+//
+void VideoListSelectionDialog::exec()
+{
+    // clear checkbox
+    mCheckBox->setChecked(false);
+    
+    mListWidget->clearSelection(); 
+    
+    // scroll list back to top
+    mListWidget->scrollTo(mModel->index(0, 0));
+
+    if(mModel->rowCount())
+    {
+        connectSignals();
+    
+        // show dialog
+        HbDialog::open();
+    }
+    else
+    {
+        // no items, finish right away
+        finishedSlot(primaryAction());
+    }
+}
+
+// ---------------------------------------------------------------------------
+// finishedSlot
+// ---------------------------------------------------------------------------
+//
+void VideoListSelectionDialog::finishedSlot(HbAction *action)
+{
+    disconnectSignals();
+    if(action == secondaryAction())
+    {
+        return;
+    }
+    QString albumName("");
+    if( mTypeOfSelection == ESelectCollection )
+    {
+        if( mSelectedAlbumId == TMPXItemId::InvalidId())
+        {
+            albumName = queryNewAlbumSelected();
+            if(mSelectedAlbumId == TMPXItemId::InvalidId())
+            {
+                // user cancelled new album creation
+                return;
+            }           
+       }
+       mTypeOfSelection = EAddToCollection;
+
+    }
+
+    if(mTypeOfSelection == EAddToCollection)
+    {  
+        if(mSelectedAlbumId != TMPXItemId::InvalidId() && mSelectedVideos.count())
+        {
+            if(mModel->addItemsInAlbum(mSelectedAlbumId, mSelectedVideos.toList()) == 0)
+            {
+                if(!albumName.length())
+                {
+                    albumName = getSelectedName();
+                }
+                QVariant data = albumName;
+                VideoCollectionViewUtils::instance().showStatusMsgSlot(
+                        VideoCollectionCommon::statusVideosAddedToCollection,
+                        data);
+            }
+        }
+    }
+    else if(mTypeOfSelection == ERemoveFromCollection)
+    {
+        if(mSelectedAlbumId != TMPXItemId::InvalidId() && mSelectedVideos.count())
+        {
+            if(mModel->removeItemsFromAlbum(mSelectedAlbumId, mSelectedVideos.toList()) == 0)
+            {
+                QVariant data = getSelectedName();
+                VideoCollectionViewUtils::instance().showStatusMsgSlot(
+                        VideoCollectionCommon::statusVideosRemovedFromCollection,
+                        data);
+            }
+        }
+    }
+    // user is deleting videos
+    else if(mTypeOfSelection == EDeleteVideos)
+    {
+        QVariant data = mSelection.indexes().count();
+        VideoCollectionViewUtils::instance().showStatusMsgSlot(
+                VideoCollectionCommon::statusDeleteInProgress,
+                data);
+        // delete items            
+        mModel->deleteItems(mSelection.indexes());
+    } 
+}
+
+// ---------------------------------------------------------------------------
+// markAllStateChanged
+// ---------------------------------------------------------------------------
+//
+void VideoListSelectionDialog::markAllStateChangedSlot(int state)
+{ 
+    if(mForcedCheck)
+    {
+        return;
+    }
+    if( state == Qt::Checked)
+    {
+        mListWidget->selectAll();
+    }
+    else
+    {
+        mListWidget->clearSelection();
+    }   
+}
+
+// ---------------------------------------------------------------------------
+// selectionChangedSlot
+// ---------------------------------------------------------------------------
+//
+void VideoListSelectionDialog::selectionChangedSlot(const QItemSelection &selected, const QItemSelection &deselected)
+{  
+    if(!primaryAction() || mTypeOfSelection == ESelectCollection)
+    {
+        return;
+    }
+   
+    if(selected.indexes().count() > 0)
+    {
+        mSelection.merge(selected, QItemSelectionModel::Select);
+    }
+    
+    if(deselected.indexes().count() >  0)
+    {
+        mSelection.merge(deselected, QItemSelectionModel::Deselect);
+    }
+    
+    if(mSelection.indexes().count() > 0)
+    {
+        primaryAction()->setDisabled(false);
+    }
+    else
+    {
+        primaryAction()->setDisabled(true);
+    }    
+
+    updateCounterSlot();
+}
+
+// ---------------------------------------------------------------------------
+// singleItemSelectedSlot
+// ---------------------------------------------------------------------------
+//
+void VideoListSelectionDialog::singleItemSelectedSlot(const QModelIndex &index)
+{
+    if(mTypeOfSelection == ESelectCollection)
+    {
+       if(index.isValid())
+       {           
+           mSelectedAlbumId = mModel->getMediaIdAtIndex(index);            
+           primaryAction()->trigger();
+       }
+    }
+}
+
+// ---------------------------------------------------------------------------
+// modelReadySlot
+// ---------------------------------------------------------------------------
+//
+void VideoListSelectionDialog::modelReadySlot()
+{
+   
+    if(mTypeOfSelection == ESelectCollection)
+    {
+        primaryAction()->setDisabled(false);
+        if(!mModel->rowCount())
+        {
+            // in case there are no user defined albums, 
+            // start input dialog right away by accepting dialog
+            primaryAction()->trigger();
+            return;
+        }
+    }
+    if(mTypeOfSelection != ESelectCollection)
+    {
+        primaryAction()->setDisabled(true);
+    }
+    updateCounterSlot();
+}
+
+// ---------------------------------------------------------------------------
+// updateCounterSlot
+// ---------------------------------------------------------------------------
+//
+void VideoListSelectionDialog::updateCounterSlot()
+{
+    if(!mItemCount)
+    {
+        return;
+    }
+
+    int rowCount = mModel->rowCount();       
+    int selectionCount = mSelection.indexes().count();
+    mItemCount->setPlainText(tr("%1/%2").arg(selectionCount).arg(rowCount));  
+    mForcedCheck = true;
+    if(selectionCount == rowCount && rowCount > 0)
+    {     
+        mCheckBox->setChecked(true);
+    }
+    else
+    {
+        mCheckBox->setChecked(false);
+    }
+    mForcedCheck = false;
+       
+}
+
+// ---------------------------------------------------------------------------
+// primaryActionTriggeredSlot
+// ---------------------------------------------------------------------------
+//
+void VideoListSelectionDialog::primaryActionTriggeredSlot()
+{
+    // reconnect primary action
+    primaryAction()->disconnect(SIGNAL(triggered()));
+    connect(primaryAction(), SIGNAL(triggered()), this, SLOT(close()));
+        
+    // update video items selection here before content changes.
+    int count = mSelection.indexes().count();
+    TMPXItemId id = TMPXItemId::InvalidId();
+    for(int i = 0; i < count; ++i)
+    {
+        id = mModel->getMediaIdAtIndex(mSelection.indexes().at(i));
+        if(id.iId2 == KVcxMvcMediaTypeVideo)
+        {
+            mSelectedVideos.insert(id);
+        }
+    }
+    
+    if(mSelectedAlbumId != TMPXItemId::InvalidId())
+    {
+        primaryAction()->trigger();
+        return;
+    }
+    else if(mTypeOfSelection == EAddToCollection)
+    {
+        // videos for collection selected, but collection 
+        // not yet selected, activate selection for it
+        mTypeOfSelection = ESelectCollection;
+        activateSelection();
+   }   
+}
+
+// ---------------------------------------------------------------------------
+// connectSignals
+// ---------------------------------------------------------------------------
+//
+void VideoListSelectionDialog::connectSignals()
+{   
+    // dialog finished
+    connect(this, SIGNAL(finished(HbAction*)), this, SLOT(finishedSlot(HbAction*)));
+    
+    // selection changes
+    connect(mListWidget, SIGNAL(activated(const QModelIndex&)),
+            this, SLOT(singleItemSelectedSlot(const QModelIndex&)));
+    
+    connect(mListWidget->selectionModel(), SIGNAL(selectionChanged (const QItemSelection&, const QItemSelection&)),
+            this, SLOT(selectionChangedSlot(const QItemSelection&, const QItemSelection &)));
+        
+    // model changes signals
+    connect(mModel->sourceModel(), SIGNAL(modelReady()), this, SLOT(modelReadySlot()));    
+    connect(mModel->sourceModel(), SIGNAL(modelChanged()), this, SLOT(updateCounterSlot()));    
+    
+    // mark all state changes
+    connect(mCheckBox, SIGNAL(stateChanged(int)), this, SLOT(markAllStateChangedSlot(int)));
+}
+ 
+// ---------------------------------------------------------------------------
+// disconnectSignals
+// ---------------------------------------------------------------------------
+//
+void VideoListSelectionDialog::disconnectSignals()
+{   
+    disconnect(this, SIGNAL(finished(HbAction*)), this, SLOT(finishedSlot(HbAction*)));
+    
+    disconnect(mListWidget, SIGNAL(activated(const QModelIndex&)),
+                this, SLOT(singleItemSelectedSlot(const QModelIndex&)));
+    
+    disconnect(mListWidget->selectionModel(), SIGNAL(selectionChanged (const QItemSelection&, const QItemSelection&)),
+                            this, SLOT(selectionChangedSlot(const QItemSelection&, const QItemSelection &)));
+            
+    // model changes signals
+    disconnect(mModel->sourceModel(), SIGNAL(modelReady()), this, SLOT(modelReadySlot()));    
+    disconnect(mModel->sourceModel(), SIGNAL(modelChanged()), this, SLOT(updateCounterSlot()));   
+    
+    // mark all state changes
+    disconnect(mCheckBox, SIGNAL(stateChanged(int)), this, SLOT(markAllStateChangedSlot(int)));   
+}
+
+// ---------------------------------------------------------------------------
+// getSelectedName
+// ---------------------------------------------------------------------------
+//
+QString VideoListSelectionDialog::getSelectedName()
+{
+    QString name;
+    if(mSelectedAlbumId.iId2 > KVcxMvcMediaTypeVideo)
+    {
+        VideoSortFilterProxyModel *model = 
+                VideoCollectionWrapper::instance().getModel(
+                            VideoCollectionWrapper::ECollections);
+        if(!model)
+        {
+            return name;
+        }
+        QModelIndex index = model->indexOfId(mSelectedAlbumId);
+        if(index.isValid())
+        {
+            name = model->data(index, Qt::DisplayRole).toStringList().first();
+        }
+    }
+    
+    return name;
+}
+
+// ---------------------------------------------------------------------------
+// queryNewAlbumSelected
+// ---------------------------------------------------------------------------
+//
+QString VideoListSelectionDialog::queryNewAlbumSelected()
+{
+    mSelectedAlbumId = TMPXItemId::InvalidId();
+    bool ok = false;
+    QString label(hbTrId("txt_videos_title_enter_name"));
+    QString text("");
+    text = HbInputDialog::getText(label, hbTrId("txt_videos_dialog_entry_new_collection"), &ok);
+    if (ok && text.length())
+    {
+       // check for duplicate album name and add new album
+        text = mModel->resolveAlbumName(text);
+        mSelectedAlbumId = mModel->addNewAlbum(text);
+    }
+    return text;
+}
+