videocollection/videocollectionwrapper/src/videosortfilterproxymodel.cpp
changeset 34 bbb98528c666
parent 30 4f111d64a341
child 35 3738fe97f027
--- a/videocollection/videocollectionwrapper/src/videosortfilterproxymodel.cpp	Thu Apr 01 23:13:36 2010 +0300
+++ b/videocollection/videocollectionwrapper/src/videosortfilterproxymodel.cpp	Thu Apr 01 23:22:15 2010 +0300
@@ -16,24 +16,30 @@
 */
 
 #include <qstringlist.h>
+#include <qset.h>
 #include <qtimer.h>
 #include <qdatetime.h>
+#include <vcxmyvideosdefs.h>
 
 #include "videothumbnaildata.h"
 #include "videocollectioncommon.h"
 #include "videosortfilterproxymodel.h"
 #include "videolistdatamodel.h"
 #include "videocollectionclient.h"
+#include "videocollectionwrapper.h"
 
 // -----------------------------------------------------------------------------
 // VideoSortFilterProxyModel::VideoSortFilterProxyModel
 // -----------------------------------------------------------------------------
 //
-VideoSortFilterProxyModel::VideoSortFilterProxyModel(QObject *parent) :
+VideoSortFilterProxyModel::VideoSortFilterProxyModel(int type, QObject *parent) :
  QSortFilterProxyModel(parent),
  mModel(0),
  mCollectionClient(0),
+ mType(type),
  mLevel(-1),
+ mGenericFilterId(TMPXItemId::InvalidId()),
+mGenericFilterValue(false),
  mIdleSortTimer(0),
  mWantedSortRole(VideoCollectionCommon::KeyDateTime)
 {
@@ -46,7 +52,7 @@
 //
 VideoSortFilterProxyModel::~VideoSortFilterProxyModel()
 {
-    delete mCollectionClient;
+    // NOP
 }
 
 // -----------------------------------------------------------------------------
@@ -55,37 +61,67 @@
 //
 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()))) {
+    if(!sourceModel)
+    {
+        return -1;
+    }
+    
+    if(!mModel) 
+    {
+        mModel = sourceModel;
+        if(!connectSignals()) 
+        {
+            disconnectSignals();
+            mModel = 0;
             return -1;
         }
+        mCollectionClient = mModel->getCollectionClient();
+        setSourceModel(sourceModel); 
+    }           
+    return 0;
+}
 
-        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;
-        }
+// -----------------------------------------------------------------------------
+// VideoSortFilterProxyModel::connectSignals
+// -----------------------------------------------------------------------------
+//
+bool VideoSortFilterProxyModel::connectSignals()
+{
+    if(!connect(mModel, SIGNAL(fullVideoDetailsReady(TMPXItemId)),
+                    this, SIGNAL(fullDetailsReady(TMPXItemId)))) 
+    {
+        return false;
+    }
+    
+    if(!connect(mModel, SIGNAL(modelReady()),
+            this, SIGNAL(modelReady()))) 
+    {
+        return false;
     }
-
-    mModel = sourceModel;
-    setSourceModel(sourceModel);
-    return 0;
+    if(!connect(mModel, SIGNAL(modelChanged()),
+                    this, SIGNAL(modelChanged()))) 
+    {
+        return false;
+    }
+    if(!connect(mModel, SIGNAL(albumChanged()),
+                  this, SLOT(albumChangedSlot()))) 
+    {
+        return false;
+    }
+    return true;
+}
+   
+// -----------------------------------------------------------------------------
+// VideoSortFilterProxyModel::disconnectSignals
+// -----------------------------------------------------------------------------
+//
+void VideoSortFilterProxyModel::disconnectSignals()
+{
+    disconnect(mModel, SIGNAL(fullVideoDetailsReady(TMPXItemId)),
+                                this, SIGNAL(fullDetailsReady(TMPXItemId)));
+    disconnect(mModel, SIGNAL(modelReady()), this, SIGNAL(modelReady()));
+    disconnect(mModel, SIGNAL(modelChanged()), this, SIGNAL(modelChanged()));
+    disconnect(mModel, SIGNAL(albumChanged()), this, SLOT(albumChangedSlot())); 
 }
 
 // -----------------------------------------------------------------------------
@@ -94,12 +130,19 @@
 //
 int VideoSortFilterProxyModel::open(int level)
 {
-    if(mLevel != level) {
-        mLevel = level;
-        return mCollectionClient->startOpenCollection(level);
+    if(!mCollectionClient)
+    {
+        return -1;
     }
-
-    return 0;
+    
+    if(mLevel != level) 
+    {
+        mLevel = level;   
+        invalidateFilter();
+    }
+    // need to call open every time to make sure all items are 
+    // inserted to UI ( recent open might have been cancelled)
+    return mCollectionClient->startOpenCollection(level);
 }
 
 // -----------------------------------------------------------------------------
@@ -142,6 +185,15 @@
         processSorting();
     }
 }
+// -----------------------------------------------------------------------------
+// VideoSortFilterProxyModel::getSorting
+// -----------------------------------------------------------------------------
+//
+void VideoSortFilterProxyModel::getSorting(int &sortingRole, Qt::SortOrder &order)
+{
+	sortingRole = mWantedSortRole;
+	order       = mWantedSortOrder;
+}
 
 // -----------------------------------------------------------------------------
 // VideoSortFilterProxyModel::deleteItems
@@ -160,7 +212,7 @@
         if(mModel->removeRows(mappedList))
         {
             // Start fetching thumbnails at start of the model.
-            VideoThumbnailData::instance().startBackgroundFetching(0);
+            VideoThumbnailData::instance().startBackgroundFetching(0, 0);
             
             return 0;
         }
@@ -172,13 +224,22 @@
 // VideoSortFilterProxyModel::openItem
 // -----------------------------------------------------------------------------
 //
-int VideoSortFilterProxyModel::openItem(const QModelIndex &index)
+int VideoSortFilterProxyModel::openItem(TMPXItemId mediaId)
 {
-    // getMediaIdAtIndex maps index to source
-    TMPXItemId mpxId1 = getMediaIdAtIndex(index);
-    if(mpxId1 != TMPXItemId::InvalidId() && mCollectionClient)
+    if(mediaId != TMPXItemId::InvalidId() && mCollectionClient)
     {
-        return mCollectionClient->openVideo(mpxId1);
+        mModel->setAlbumInUse(TMPXItemId::InvalidId());
+        
+        if(mCollectionClient->openItem(mediaId) == 0)
+        {
+            if(mediaId.iId2 != KVcxMvcMediaTypeVideo)
+            { 
+                mLevel = VideoCollectionCommon::ELevelAlbum;
+                mModel->setAlbumInUse(mediaId);
+                invalidateFilter();
+            } 
+            return 0;
+        }
     }
     return -1;
 }
@@ -189,10 +250,21 @@
 //
 int VideoSortFilterProxyModel::back()
 {
-    if(mCollectionClient)
+
+    if(mCollectionClient && mCollectionClient->back() == 0)
     {
-        return mCollectionClient->back();
+
+        if(mLevel == VideoCollectionCommon::ELevelAlbum)
+        {
+            mLevel = VideoCollectionCommon::ELevelCategory;
+        }
+        else
+        {
+            mLevel = VideoCollectionCommon::ELevelVideos;
+        }
+        return 0;
     }
+
     return -1;
 }
 
@@ -209,10 +281,8 @@
     {
         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());
+
+            emit shortDetailsReady(mpxId1);
             return 0;
         }
     }
@@ -249,18 +319,67 @@
     }
     
     // Start fetching thumbnails at start of the model.
-    VideoThumbnailData::instance().startBackgroundFetching(0);
+    VideoThumbnailData::instance().startBackgroundFetching(0, 0);
 }
 
 // -----------------------------------------------------------------------------
 // VideoSortFilterProxyModel::lessThan
 // -----------------------------------------------------------------------------
 //
-bool VideoSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
+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
+    if (!mModel)
+    {
+        return false;
+    }
+    TMPXItemId leftId = mModel->mediaIdAtIndex(left.row());
+    TMPXItemId rightId = mModel->mediaIdAtIndex(right.row());
+    
+    // Default categories are always first in the following order:
+    // Recently played (missing currently
+    // Captured
+    // Downloaded
+    // Podcasts (missing currently)
+    bool lessThan(false);
+    bool proceedDataSorting(false);
+    if(leftId.iId2  == KVcxMvcMediaTypeCategory &&
+       rightId.iId2 == KVcxMvcMediaTypeCategory)
+    {
+        if(leftId.iId1 == KVcxMvcCategoryIdCaptured)
+        {
+            lessThan = true;
+        }
+   
+        else if(leftId.iId1 == KVcxMvcCategoryIdDownloads)
+        {
+            if(rightId.iId1 != KVcxMvcCategoryIdCaptured)
+            {
+                lessThan = true;
+            }
+        }
+    }
+    else if(leftId.iId2 == KVcxMvcMediaTypeCategory ||
+            rightId.iId2 == KVcxMvcMediaTypeCategory)
+    {
+        lessThan = (leftId.iId2 == KVcxMvcMediaTypeCategory);
+    }
+    else
+    {
+        proceedDataSorting = true;
+    }
 
+    if(!proceedDataSorting)
+    {
+        return mWantedSortOrder == Qt::AscendingOrder ? lessThan : !lessThan;
+    }
+    
+    // Do comparisation based on the role:
+    //  Qt::DisplayRole,
+    //  VideoCollectionCommon::KeySizeValue,
+    //  VideoCollectionCommon::KeyDateValue
+    // 
+    // If role does not match, do not sort
     int sRole = sortRole();
     QVariant leftData = sourceModel()->data(left, sRole);
     QVariant rightData = sourceModel()->data(right, sRole);
@@ -297,19 +416,67 @@
 //
 bool VideoSortFilterProxyModel::filterAcceptsRow (int source_row, const QModelIndex &source_parent) const
 {
+    Q_UNUSED(source_parent);
+
     if(!sourceModel())
         return false;
 
-    QModelIndex index = sourceModel()->index(source_row, 0, source_parent);
-    if(index.isValid())
+    if(source_row < 0 || source_row >= sourceModel()->rowCount())
+    {
+        return false;
+    }
+    TMPXItemId id = mModel->mediaIdAtIndex(source_row);
+    if(id == TMPXItemId::InvalidId())
+    {
+        return false;
+    }
+    
+    if (mType == VideoCollectionWrapper::EAllVideos)
+    {
+        if(id.iId2 == KVcxMvcMediaTypeVideo)
+        {
+            return true;
+        }
+    }
+    else if(mType == VideoCollectionWrapper::ECollections)
+    {
+        
+        if(mLevel == VideoCollectionCommon::ELevelCategory && id.iId2 != KVcxMvcMediaTypeVideo)
+        {
+            return true;
+        }       
+    }
+    else if (mType == VideoCollectionWrapper::ECollectionContent)
     {
-        QVariant data = sourceModel()->data(index, VideoCollectionCommon::KeyStatus);
-        if(data.isValid() && data.toInt() == VideoCollectionCommon::StatusDeleted)
+        // if item belongs to the open album, accept it
+        if (mModel->belongsToAlbum(id))
+        {
+            return true;
+        }
+    }
+    else if(mType == VideoCollectionWrapper::EGeneric)
+    {
+
+        if(mLevel == VideoCollectionCommon::ELevelVideos && id.iId2 == KVcxMvcMediaTypeVideo)
         {
-            return false;
+            //  filter items that belong to that album setted as filter id
+            // if there's no filter or setted filter is "all videos", we accept everything
+            if(mGenericFilterId == TMPXItemId::InvalidId() || 
+               (mGenericFilterId.iId1 == KVcxMvcCategoryIdAll && 
+                mGenericFilterId.iId2 == KVcxMvcMediaTypeCategory) ||
+                mGenericFilterValue == mModel->belongsToAlbum(id, mGenericFilterId))
+            {
+                return true;
+            }
+            
         }
-        return true;
+        else if(mLevel == VideoCollectionCommon::ELevelCategory && id.iId2 == KVcxMvcMediaTypeAlbum)    
+        {
+            // we do not filter albums yet
+            return true;
+        }
     }
+    
     return false;
 }
 
@@ -317,7 +484,7 @@
 // VideoSortFilterProxyModel::getMediaIdAtIndex()
 // -----------------------------------------------------------------------------
 //
-TMPXItemId VideoSortFilterProxyModel::getMediaIdAtIndex(const QModelIndex &index)
+TMPXItemId VideoSortFilterProxyModel::getMediaIdAtIndex(const QModelIndex &index) const
 {
     QModelIndex sourceIndex = mapToSource(index);
     TMPXItemId mpxId = TMPXItemId::InvalidId();
@@ -329,6 +496,21 @@
 }
 
 // -----------------------------------------------------------------------------
+//  VideoSortFilterProxyModel::indexOfId()
+// -----------------------------------------------------------------------------
+//
+QModelIndex VideoSortFilterProxyModel::indexOfId(TMPXItemId id)
+{    
+    QModelIndex sourceIndex;
+    if(!mModel || id == TMPXItemId::InvalidId())
+    {
+        return sourceIndex;
+    }
+    sourceIndex = mModel->indexOfId(id);
+    return mapFromSource(sourceIndex);
+}
+
+// -----------------------------------------------------------------------------
 // VideoSortFilterProxyModel::getMediaFilePathForId()
 // -----------------------------------------------------------------------------
 //
@@ -343,16 +525,168 @@
 }
 
 // -----------------------------------------------------------------------------
-// VideoSortFilterProxyModel::addNewCollection()
+// VideoSortFilterProxyModel::addNewAlbum()
+// -----------------------------------------------------------------------------
+//
+TMPXItemId VideoSortFilterProxyModel::addNewAlbum(const QString &title)
+{
+    TMPXItemId id = TMPXItemId::InvalidId();
+    
+    if (mCollectionClient)
+    {
+        id = mCollectionClient->addNewAlbum(title);
+    }
+    
+    return id;
+}
+
+// -----------------------------------------------------------------------------
+// VideoSortFilterProxyModel::removeAlbums()
+// -----------------------------------------------------------------------------
+//
+int VideoSortFilterProxyModel::removeAlbums(const QModelIndexList &indexList)
+{
+	int err(-1);
+    
+	if (mCollectionClient)
+	{
+		TMPXItemId mpxId;
+		QList<TMPXItemId> ids;
+
+		for(int i = 0; i < indexList.count(); ++i)
+		{
+			mpxId = getMediaIdAtIndex(indexList.at(i));
+			if((mpxId != TMPXItemId::InvalidId()) && (mpxId.iId2 == KVcxMvcMediaTypeAlbum))
+			{
+				ids.append(getMediaIdAtIndex(indexList.at(i)));
+			}
+		}
+		
+		if (ids.count())
+		{
+			err = mCollectionClient->removeAlbums(ids);
+		}
+	}
+
+    return err;
+}
+
+// -----------------------------------------------------------------------------
+// VideoSortFilterProxyModel::resolveAlbumName()
 // -----------------------------------------------------------------------------
 //
-int VideoSortFilterProxyModel::addNewCollection(QString name, QString thumbnail, QList<TMPXItemId> mediaIds)
+QString VideoSortFilterProxyModel::resolveAlbumName(
+    const QString& albumName) const
+{
+    QString resolvedName = albumName.trimmed();
+
+    // for checking names, we need to use collection list proxy model 
+    // to get all existing album names including default ones
+    VideoSortFilterProxyModel *collectionModel = 
+                       VideoCollectionWrapper::instance().getModel(
+                                   VideoCollectionWrapper::ECollections);
+    if(!collectionModel || !mModel)
+    {
+        return resolvedName;
+    }    
+    
+    int i(0);
+    QModelIndex proxyIndex = collectionModel->index(i, 0);
+    QSet<QString> names;
+    QVariant data;
+    // create set of existing names
+    while (proxyIndex.isValid())
+    {
+        data = mModel->data(collectionModel->mapToSource(proxyIndex), Qt::DisplayRole);
+        if (data.isValid())
+        {
+            QStringList stringList = data.toStringList();
+            names.insert(stringList.at(0));
+        }
+        proxyIndex = collectionModel->index(++i, 0, QModelIndex());
+    }
+    i = 0;
+    QString firstMatch("");
+    // find a name that does not yet exists
+    while(names.contains(resolvedName))
+    {
+        if (!firstMatch.length())
+        {
+            firstMatch = resolvedName;
+        }
+        ++i;
+        resolvedName = tr("%1 (%2)").arg(firstMatch).arg(i);
+    }
+    return resolvedName;
+}
+
+// -----------------------------------------------------------------------------
+// VideoSortFilterProxyModel::addItemsInAlbum()
+// -----------------------------------------------------------------------------
+//
+int VideoSortFilterProxyModel::addItemsInAlbum(TMPXItemId albumId,
+        const QList<TMPXItemId> &mediaIds)
 {
-    int error = -1;
-    if(mCollectionClient) {
-        error = mCollectionClient->addNewCollection(name, thumbnail, mediaIds);
+    int err(-1);
+    
+    if (mCollectionClient)
+    {        
+        // add items in album
+        err = mCollectionClient->addItemsInAlbum(albumId, mediaIds);
     }
-    return error;
+    
+    return err;
+}
+
+// -----------------------------------------------------------------------------
+// VideoSortFilterProxyModel::getOpenItem()
+// -----------------------------------------------------------------------------
+//
+TMPXItemId VideoSortFilterProxyModel::getOpenItem() const
+{
+    TMPXItemId itemId = TMPXItemId::InvalidId();
+    
+    if(mModel && mCollectionClient)
+    {
+        if(mType == VideoCollectionWrapper::EAllVideos)
+        {
+            itemId.iId1 = KVcxMvcCategoryIdAll;
+            itemId.iId2 = KVcxMvcMediaTypeCategory;        
+        }
+        else if(mType == VideoCollectionWrapper::ECollectionContent)
+        {
+            itemId = mModel->albumInUse();
+        }
+    }
+
+    return itemId;
+}
+
+// -----------------------------------------------------------------------------
+// VideoSortFilterProxyModel::setGenericIdFilter()
+// -----------------------------------------------------------------------------
+//
+void VideoSortFilterProxyModel::setGenericIdFilter(TMPXItemId itemId, bool filterValue)
+{
+    if(mType == VideoCollectionWrapper::EGeneric)
+    {
+        mGenericFilterId = itemId;
+        mGenericFilterValue = filterValue;
+        invalidateFilter();
+    }
+}
+
+// -----------------------------------------------------------------------------
+// VideoSortFilterProxyModel::albumChangedSlot()
+// -----------------------------------------------------------------------------
+//
+void VideoSortFilterProxyModel::albumChangedSlot()
+{
+    // ignore if not collection content model
+    if (mType == VideoCollectionWrapper::ECollectionContent)
+    {
+        invalidateFilter();
+    }
 }
 
 // end of file