videocollection/videocollectionview/src/videolistselectiondialog.cpp
author hgs
Thu, 01 Apr 2010 23:32:44 +0300
changeset 35 3738fe97f027
parent 34 bbb98528c666
child 36 8aed59de29f9
permissions -rw-r--r--
201011

/*
* 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;
}