videocollection/videocollectionwrapper/src/videosortfilterproxymodel.cpp
author hgs
Thu, 01 Apr 2010 22:38:49 +0300
changeset 30 4f111d64a341
child 34 bbb98528c666
permissions -rw-r--r--
201005

/*
* 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:   Videosortfilterproxymodel implementation
*
*/

#include <qstringlist.h>
#include <qtimer.h>
#include <qdatetime.h>

#include "videothumbnaildata.h"
#include "videocollectioncommon.h"
#include "videosortfilterproxymodel.h"
#include "videolistdatamodel.h"
#include "videocollectionclient.h"

// -----------------------------------------------------------------------------
// VideoSortFilterProxyModel::VideoSortFilterProxyModel
// -----------------------------------------------------------------------------
//
VideoSortFilterProxyModel::VideoSortFilterProxyModel(QObject *parent) :
 QSortFilterProxyModel(parent),
 mModel(0),
 mCollectionClient(0),
 mLevel(-1),
 mIdleSortTimer(0),
 mWantedSortRole(VideoCollectionCommon::KeyDateTime)
{
    // NOP
}

// -----------------------------------------------------------------------------
// VideoSortFilterProxyModel::~VideoSortFilterProxyModel
// -----------------------------------------------------------------------------
//
VideoSortFilterProxyModel::~VideoSortFilterProxyModel()
{
    delete mCollectionClient;
}

// -----------------------------------------------------------------------------
// VideoSortFilterProxyModel::initialize
// -----------------------------------------------------------------------------
//
int VideoSortFilterProxyModel::initialize(VideoListDataModel *sourceModel)
{
    if(!mCollectionClient) {
        if(!connect(sourceModel, SIGNAL(fullVideoDetailsReady(int)),
                this, SIGNAL(fullDetailsReady(int)))) {
            return -1;
        }
        
        if(!connect(sourceModel, SIGNAL(modelReady()),
                this, SIGNAL(modelReady()))) {
            return -1;
        }

        mCollectionClient = new VideoCollectionClient();
        if(!mCollectionClient ||
           mCollectionClient->initialize() < 0 ||
           sourceModel->initialize(mCollectionClient) < 0) {
            delete mCollectionClient;
            mCollectionClient = 0;
            disconnect(sourceModel, SIGNAL(fullVideoDetailsReady(int)),
                this, SIGNAL(fullDetailsReady(int)));
            return -1;
        }

    } else {
        if(sourceModel->initialize(mCollectionClient) < 0) {
            return -1;
        }
    }

    mModel = sourceModel;
    setSourceModel(sourceModel);
    return 0;
}

// -----------------------------------------------------------------------------
// VideoSortFilterProxyModel::open
// -----------------------------------------------------------------------------
//
int VideoSortFilterProxyModel::open(int level)
{
    if(mLevel != level) {
        mLevel = level;
        return mCollectionClient->startOpenCollection(level);
    }

    return 0;
}

// -----------------------------------------------------------------------------
// VideoSortFilterProxyModel::doSorting
// -----------------------------------------------------------------------------
//
void VideoSortFilterProxyModel::doSorting(int sortingRole, Qt::SortOrder order, 
        bool async)
{
    if((sortingRole != Qt::DisplayRole) &&
       (sortingRole != VideoCollectionCommon::KeySizeValue) &&
       (sortingRole != VideoCollectionCommon::KeyDateTime))
    {
        // default sorting order is by date
        mWantedSortRole = VideoCollectionCommon::KeyDateTime;
    }
    else
    {
        mWantedSortRole = sortingRole;
    }
    
    mWantedSortOrder = order;
    
    if(async)
    {
        if(mIdleSortTimer)
        {
            if(mIdleSortTimer->isActive())
            {
                mIdleSortTimer->stop();
            }
        }
        else
        {
            mIdleSortTimer = new QTimer(this);
            connect(mIdleSortTimer, SIGNAL(timeout()), this, SLOT(processSorting()));
        }
        mIdleSortTimer->start(0);
    } else {
        processSorting();
    }
}

// -----------------------------------------------------------------------------
// VideoSortFilterProxyModel::deleteItems
// -----------------------------------------------------------------------------
//
int VideoSortFilterProxyModel::deleteItems(const QModelIndexList &indexList)
{
    if(mModel)
    {
        QModelIndexList mappedList;
        for(int i = 0; i < indexList.count(); ++i)
        {
            mappedList.append(mapToSource(indexList.at(i)));
        }
        
        if(mModel->removeRows(mappedList))
        {
            // Start fetching thumbnails at start of the model.
            VideoThumbnailData::instance().startBackgroundFetching(0);
            
            return 0;
        }
    }
    return -1;
}

// -----------------------------------------------------------------------------
// VideoSortFilterProxyModel::openItem
// -----------------------------------------------------------------------------
//
int VideoSortFilterProxyModel::openItem(const QModelIndex &index)
{
    // getMediaIdAtIndex maps index to source
    TMPXItemId mpxId1 = getMediaIdAtIndex(index);
    if(mpxId1 != TMPXItemId::InvalidId() && mCollectionClient)
    {
        return mCollectionClient->openVideo(mpxId1);
    }
    return -1;
}

// -----------------------------------------------------------------------------
// VideoSortFilterProxyModel::back
// -----------------------------------------------------------------------------
//
int VideoSortFilterProxyModel::back()
{
    if(mCollectionClient)
    {
        return mCollectionClient->back();
    }
    return -1;
}

// -----------------------------------------------------------------------------
// VideoSortFilterProxyModel::fetchItemDetails
// -----------------------------------------------------------------------------
//
int VideoSortFilterProxyModel::fetchItemDetails(const QModelIndex &index)
{
    // no need to map index beforehand, because 
	// getMediaIdAtIndex maps it
    TMPXItemId mpxId1 = getMediaIdAtIndex(index);
    if(mpxId1 != TMPXItemId::InvalidId() && mCollectionClient)
    {
        if(mCollectionClient->getVideoDetails(mpxId1) == 0)
        {
			// because full details comes from model, map index gotten from UI
			// into sourcemodel index as well for consistency's sake
			QModelIndex sourceIndex = mapToSource(index);
            emit shortDetailsReady(sourceIndex.row());
            return 0;
        }
    }
    return -1;
}

// -----------------------------------------------------------------------------
// VideoSortFilterProxyModel::processSorting
// -----------------------------------------------------------------------------
//
void VideoSortFilterProxyModel::processSorting()
{
    if(mIdleSortTimer)
    {
        mIdleSortTimer->stop();
    }

    if(sortRole() != mWantedSortRole)
    {
        setSortRole(mWantedSortRole);
    }
    
    if(sortColumn() == -1 || sortOrder() != mWantedSortOrder)
    {
        // if sorting column is not yet setted, it indicates
        // that we've setted the sorting order for the first time
        // and sorting has not yet been done. After we have called sort once,
        // the sort columnt gets updated and following sorts gets executed
        // by setSortRole -call as long as role changes.
    
        // Another case is when we need to change the sort order, as there is
        // no other way of setting the sort order than calling sort().
        sort(0, mWantedSortOrder);
    }
    
    // Start fetching thumbnails at start of the model.
    VideoThumbnailData::instance().startBackgroundFetching(0);
}

// -----------------------------------------------------------------------------
// VideoSortFilterProxyModel::lessThan
// -----------------------------------------------------------------------------
//
bool VideoSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
{
    // do comparisation based on the role, if role is different than Qt::DisplayRole,
    // VideoCollectionCommon::KeySizeValue or VideoCollectionCommon::KeyDateValue, method does not sort at all

    int sRole = sortRole();
    QVariant leftData = sourceModel()->data(left, sRole);
    QVariant rightData = sourceModel()->data(right, sRole);

    if(!leftData.isValid() || !rightData.isValid())
    {
        return false;
    }
    if(sRole == Qt::DisplayRole)
    {
        QString leftString = leftData.toStringList().first().toUpper();
        QString rightString = rightData.toStringList().first().toUpper();
        return QString::localeAwareCompare(leftString, rightString) < 0;
    }
    else if(sRole == VideoCollectionCommon::KeySizeValue)
    {
        quint32 leftSize = leftData.toUInt();
        quint32 rightSize = rightData.toUInt();
        return leftSize < rightSize;
    }
    else if(sRole == VideoCollectionCommon::KeyDateTime)
    {
        QDateTime leftDateTime = leftData.toDateTime();
        QDateTime rightDateTime = rightData.toDateTime();
        // datetime sorting role has inverted sorting order compared to other roles 
        return rightDateTime < leftDateTime;
    }
    return false;
}

// -----------------------------------------------------------------------------
// VideoSortFilterProxyModel::filterAcceptsRow
// -----------------------------------------------------------------------------
//
bool VideoSortFilterProxyModel::filterAcceptsRow (int source_row, const QModelIndex &source_parent) const
{
    if(!sourceModel())
        return false;

    QModelIndex index = sourceModel()->index(source_row, 0, source_parent);
    if(index.isValid())
    {
        QVariant data = sourceModel()->data(index, VideoCollectionCommon::KeyStatus);
        if(data.isValid() && data.toInt() == VideoCollectionCommon::StatusDeleted)
        {
            return false;
        }
        return true;
    }
    return false;
}

// -----------------------------------------------------------------------------
// VideoSortFilterProxyModel::getMediaIdAtIndex()
// -----------------------------------------------------------------------------
//
TMPXItemId VideoSortFilterProxyModel::getMediaIdAtIndex(const QModelIndex &index)
{
    QModelIndex sourceIndex = mapToSource(index);
    TMPXItemId mpxId = TMPXItemId::InvalidId();
    if(mModel && sourceIndex.isValid())
    {
        mpxId = mModel->mediaIdAtIndex(sourceIndex.row());
    }
    return mpxId;
}

// -----------------------------------------------------------------------------
// VideoSortFilterProxyModel::getMediaFilePathForId()
// -----------------------------------------------------------------------------
//
QString VideoSortFilterProxyModel::getMediaFilePathForId(TMPXItemId mediaId)
{
    QString filePath;
    if(mModel)
    {
        filePath = mModel->mediaFilePathForId(mediaId);
    }
    return filePath;
}

// -----------------------------------------------------------------------------
// VideoSortFilterProxyModel::addNewCollection()
// -----------------------------------------------------------------------------
//
int VideoSortFilterProxyModel::addNewCollection(QString name, QString thumbnail, QList<TMPXItemId> mediaIds)
{
    int error = -1;
    if(mCollectionClient) {
        error = mCollectionClient->addNewCollection(name, thumbnail, mediaIds);
    }
    return error;
}

// end of file