videocollection/videocollectionwrapper/src/videosortfilterproxymodel.cpp
changeset 62 0e1e938beb1a
parent 59 a76e86df7ccd
child 65 a9d57bd8d7b7
equal deleted inserted replaced
59:a76e86df7ccd 62:0e1e938beb1a
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:   Videosortfilterproxymodel implementation
       
    15 *
       
    16 */
       
    17 
       
    18 // Version : %version: 66.1.9 %
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include <qstringlist.h>
       
    22 #include <qset.h>
       
    23 #include <qtimer.h>
       
    24 #include <qdatetime.h>
       
    25 #include <vcxmyvideosdefs.h>
       
    26 
       
    27 #include "videothumbnaildata.h"
       
    28 #include "videocollectioncommon.h"
       
    29 #include "videosortfilterproxymodel.h"
       
    30 #include "videolistdatamodel.h"
       
    31 #include "videocollectionclient.h"
       
    32 #include "videocollectionwrapper.h"
       
    33 #include "videocollectiontrace.h"
       
    34 
       
    35 const TMPXItemId INVALID_ID = TMPXItemId::InvalidId();
       
    36 
       
    37 // -----------------------------------------------------------------------------
       
    38 // VideoSortFilterProxyModel::VideoSortFilterProxyModel
       
    39 // -----------------------------------------------------------------------------
       
    40 //
       
    41 VideoSortFilterProxyModel::VideoSortFilterProxyModel(VideoCollectionCommon::TModelType type, QObject *parent) :
       
    42 QSortFilterProxyModel(parent),
       
    43 mModel(0),
       
    44 mCollectionClient(0),
       
    45 mType(type),
       
    46 mLevel(VideoCollectionCommon::ELevelInvalid),
       
    47 mGenericFilterId(TMPXItemId::InvalidId()),
       
    48 mGenericFilterValue(false),
       
    49 mIdleSortTimer(0),
       
    50 mWantedSortRole(VideoCollectionCommon::KeyDateTime),
       
    51 mWantedSortOrder(Qt::AscendingOrder)
       
    52 {
       
    53 	FUNC_LOG_ADDR(this);
       
    54 	INFO_2("VideoSortFilterProxyModel::VideoSortFilterProxyModel() [0x%x]: type: %d", this, type);
       
    55 }
       
    56 
       
    57 // -----------------------------------------------------------------------------
       
    58 // VideoSortFilterProxyModel::~VideoSortFilterProxyModel
       
    59 // -----------------------------------------------------------------------------
       
    60 //
       
    61 VideoSortFilterProxyModel::~VideoSortFilterProxyModel()
       
    62 {
       
    63 	FUNC_LOG_ADDR(this);
       
    64 }
       
    65 
       
    66 // -----------------------------------------------------------------------------
       
    67 // VideoSortFilterProxyModel::initialize
       
    68 // -----------------------------------------------------------------------------
       
    69 //
       
    70 int VideoSortFilterProxyModel::initialize(VideoListDataModel *sourceModel)
       
    71 {
       
    72 	FUNC_LOG_ADDR(this);
       
    73     if(!sourceModel)
       
    74     {
       
    75         return -1;
       
    76     }
       
    77     
       
    78     if(!mModel) 
       
    79     {
       
    80         mModel = sourceModel;
       
    81         if(!connectSignals()) 
       
    82         {
       
    83             ERROR_1(-1, "VideoSortFilterProxyModel::initialize() [0x%x] failed to connect signals.", this);
       
    84             disconnectSignals();
       
    85             mModel = 0;
       
    86             return -1;
       
    87         }
       
    88         mCollectionClient = mModel->getCollectionClient();
       
    89         setSourceModel(sourceModel); 
       
    90     }           
       
    91     return 0;
       
    92 }
       
    93 
       
    94 // -----------------------------------------------------------------------------
       
    95 // VideoSortFilterProxyModel::connectSignals
       
    96 // -----------------------------------------------------------------------------
       
    97 //
       
    98 bool VideoSortFilterProxyModel::connectSignals()
       
    99 {
       
   100 	FUNC_LOG_ADDR(this);
       
   101 
       
   102     if(!connect(mModel, SIGNAL(modelChanged()),
       
   103                     this, SLOT(invalidate()))) 
       
   104     {
       
   105         return false;
       
   106     }
       
   107     if(mType == VideoCollectionCommon::EModelTypeCollectionContent)
       
   108     {
       
   109         if(!connect(mModel, SIGNAL(albumChanged()),
       
   110                     this, SLOT(albumChangedSlot()))) 
       
   111         {
       
   112             return false;
       
   113         }
       
   114     }
       
   115 
       
   116     return true;
       
   117 }
       
   118    
       
   119 // -----------------------------------------------------------------------------
       
   120 // VideoSortFilterProxyModel::disconnectSignals
       
   121 // -----------------------------------------------------------------------------
       
   122 //
       
   123 void VideoSortFilterProxyModel::disconnectSignals()
       
   124 {
       
   125 	FUNC_LOG_ADDR(this);
       
   126     disconnect(mModel, SIGNAL(modelChanged()), this, SLOT(invalidate()));
       
   127     if(mType == VideoCollectionCommon::EModelTypeCollectionContent)
       
   128     {
       
   129         disconnect(mModel, SIGNAL(albumChanged()), this, SLOT(albumChangedSlot()));
       
   130     }
       
   131     if(mType == VideoCollectionCommon::EModelTypeCollections)
       
   132     {
       
   133         disconnect(mModel, SIGNAL(itemModified(const TMPXItemId &)), 
       
   134                    this, SLOT(itemModifiedSlot(const TMPXItemId &)));
       
   135     }
       
   136 }
       
   137 
       
   138 // -----------------------------------------------------------------------------
       
   139 // VideoSortFilterProxyModel::open
       
   140 // -----------------------------------------------------------------------------
       
   141 //
       
   142 int VideoSortFilterProxyModel::open(VideoCollectionCommon::TCollectionLevels level)
       
   143 {
       
   144 	FUNC_LOG_ADDR(this);
       
   145 	INFO_2("VideoSortFilterProxyModel::open() [0x%x] level: %d", this, level);
       
   146 	
       
   147     if(!mCollectionClient)
       
   148     {
       
   149         return -1;
       
   150     }
       
   151 
       
   152     if(mLevel != level) 
       
   153     {
       
   154        INFO_1("VideoSortFilterProxyModel::open() [0x%x] opening different level, invalidating.", this);
       
   155        mLevel = level;
       
   156        invalidateFilter();
       
   157        // sorting call required here to setup correct sort order in cases where source model allready 
       
   158        // contains items but proxy is not yet updated. (invalidate -call does not work since it updates proxy and
       
   159        // calls sort in different order for us to use)
       
   160        sort(0, mWantedSortOrder);
       
   161     }
       
   162     // need to call open every time to make sure all items are 
       
   163     // inserted to UI ( recent open might have been cancelled)
       
   164     return mCollectionClient->startOpenCollection(level);
       
   165 }
       
   166 
       
   167 // -----------------------------------------------------------------------------
       
   168 // VideoSortFilterProxyModel::doSorting
       
   169 // -----------------------------------------------------------------------------
       
   170 //
       
   171 void VideoSortFilterProxyModel::doSorting(int sortingRole, Qt::SortOrder order, 
       
   172         bool async)
       
   173 {
       
   174 	FUNC_LOG_ADDR(this);
       
   175 	INFO_3("VideoSortFilterProxyModel::doSorting() [0x%x] sortingRole: %d, order: %d", this, sortingRole, order);
       
   176 	
       
   177     if(sortingRole != VideoCollectionCommon::KeyTitle &&
       
   178        sortingRole != VideoCollectionCommon::KeySizeValue &&
       
   179        sortingRole != VideoCollectionCommon::KeyDateTime &&
       
   180        sortingRole != VideoCollectionCommon::KeyNumberOfItems)
       
   181     {
       
   182         // default sorting order is by date for other models but collections.
       
   183         if(mType != VideoCollectionCommon::EModelTypeCollections)
       
   184         {   
       
   185             mWantedSortRole = VideoCollectionCommon::KeyDateTime;
       
   186         }
       
   187         else
       
   188         {
       
   189             mWantedSortRole = VideoCollectionCommon::KeyTitle;
       
   190         }
       
   191     }
       
   192     else
       
   193     {
       
   194         mWantedSortRole = sortingRole;
       
   195     }
       
   196     
       
   197     mWantedSortOrder = order;
       
   198     
       
   199     if(async)
       
   200     {
       
   201         if(mIdleSortTimer)
       
   202         {
       
   203             if(mIdleSortTimer->isActive())
       
   204             {
       
   205                 mIdleSortTimer->stop();
       
   206             }
       
   207         }
       
   208         else
       
   209         {
       
   210             mIdleSortTimer = new QTimer(this);
       
   211             connect(mIdleSortTimer, SIGNAL(timeout()), this, SLOT(processSorting()));
       
   212         }
       
   213         mIdleSortTimer->start(0);
       
   214     }
       
   215     else
       
   216     {
       
   217         processSorting();
       
   218     }
       
   219 }
       
   220 // -----------------------------------------------------------------------------
       
   221 // VideoSortFilterProxyModel::getSorting
       
   222 // -----------------------------------------------------------------------------
       
   223 //
       
   224 void VideoSortFilterProxyModel::getSorting(int &sortingRole, Qt::SortOrder &order)
       
   225 {
       
   226 	FUNC_LOG_ADDR(this);
       
   227 	sortingRole = mWantedSortRole;
       
   228 	order       = mWantedSortOrder;
       
   229 }
       
   230 
       
   231 // -----------------------------------------------------------------------------
       
   232 // VideoSortFilterProxyModel::deleteItems
       
   233 // -----------------------------------------------------------------------------
       
   234 //
       
   235 int VideoSortFilterProxyModel::deleteItems(const QModelIndexList &indexList)
       
   236 {
       
   237 	FUNC_LOG_ADDR(this);
       
   238 	
       
   239 	// Disable thumbnail fetching while items are removed from the model. 
       
   240 	VideoThumbnailData::instance().enableBackgroundFetching(false);
       
   241 	
       
   242     if(mModel)
       
   243     {
       
   244         QModelIndexList mappedList;
       
   245         for(int i = 0; i < indexList.count(); ++i)
       
   246         {
       
   247             mappedList.append(mapToSource(indexList.at(i)));
       
   248         }
       
   249         
       
   250         if(mModel->removeRows(mappedList))
       
   251         {
       
   252             // Start fetching thumbnails at start of the model.
       
   253             VideoThumbnailData::instance().enableBackgroundFetching(true);
       
   254             VideoThumbnailData::instance().startBackgroundFetching(0, 0);
       
   255             return 0;
       
   256         }
       
   257     }
       
   258     
       
   259     VideoThumbnailData::instance().enableBackgroundFetching(true);
       
   260     return -1;
       
   261 }
       
   262 
       
   263 // -----------------------------------------------------------------------------
       
   264 // VideoSortFilterProxyModel::openItem
       
   265 // -----------------------------------------------------------------------------
       
   266 //
       
   267 int VideoSortFilterProxyModel::openItem(TMPXItemId mediaId)
       
   268 {
       
   269 	FUNC_LOG_ADDR(this);
       
   270     if(mediaId != TMPXItemId::InvalidId() && mCollectionClient)
       
   271     {
       
   272         if(mCollectionClient->openItem(mediaId) == 0)
       
   273         {
       
   274             if(mediaId.iId2 != KVcxMvcMediaTypeVideo)
       
   275             { 
       
   276                 mLevel = VideoCollectionCommon::ELevelAlbum;
       
   277                 mModel->setAlbumInUse(mediaId);
       
   278                 INFO_1("VideoSortFilterProxyModel::open() [0x%x] opening album or category, invalidating.", this);
       
   279                 invalidateFilter();
       
   280                 // sorting call required here to setup correct sort order in cases where source model allready 
       
   281                 // contains items but proxy is not yet updated. (invalidate -call does not work since it updates proxy and
       
   282                 // calls sort in different order for us to use)
       
   283                 sort(0, mWantedSortOrder);
       
   284             } 
       
   285             return 0;
       
   286         }
       
   287     }
       
   288     return -1;
       
   289 }
       
   290 
       
   291 // -----------------------------------------------------------------------------
       
   292 // VideoSortFilterProxyModel::back
       
   293 // -----------------------------------------------------------------------------
       
   294 //
       
   295 int VideoSortFilterProxyModel::back()
       
   296 {
       
   297 	FUNC_LOG_ADDR(this);
       
   298     if(mCollectionClient && mCollectionClient->back() == 0)
       
   299     {
       
   300         if(mLevel == VideoCollectionCommon::ELevelAlbum)
       
   301         {
       
   302             mLevel = VideoCollectionCommon::ELevelCategory;
       
   303         }
       
   304         else
       
   305         {
       
   306             mLevel = VideoCollectionCommon::ELevelVideos;
       
   307         }
       
   308         return 0;
       
   309     }
       
   310     return -1;
       
   311 }
       
   312 
       
   313 // -----------------------------------------------------------------------------
       
   314 // VideoSortFilterProxyModel::fetchItemDetails
       
   315 // -----------------------------------------------------------------------------
       
   316 //
       
   317 int VideoSortFilterProxyModel::fetchItemDetails(const QModelIndex &index)
       
   318 {
       
   319 	FUNC_LOG_ADDR(this);
       
   320     // no need to map index beforehand, because 
       
   321 	// getMediaIdAtIndex maps it
       
   322     TMPXItemId mpxId1 = getMediaIdAtIndex(index);
       
   323     if(mpxId1 != TMPXItemId::InvalidId() && mCollectionClient)
       
   324     {
       
   325         if(mCollectionClient->getVideoDetails(mpxId1) == 0)
       
   326         {
       
   327             emit shortDetailsReady(mpxId1);
       
   328             return 0;
       
   329         }
       
   330     }
       
   331     return -1;
       
   332 }
       
   333 
       
   334 // -----------------------------------------------------------------------------
       
   335 // VideoSortFilterProxyModel::processSorting
       
   336 // -----------------------------------------------------------------------------
       
   337 //
       
   338 void VideoSortFilterProxyModel::processSorting()
       
   339 {
       
   340 	FUNC_LOG_ADDR(this);
       
   341     if(mIdleSortTimer)
       
   342     {
       
   343         mIdleSortTimer->stop();
       
   344     }
       
   345 
       
   346     if(sortRole() != mWantedSortRole)
       
   347     {
       
   348         setSortRole(mWantedSortRole);
       
   349     }
       
   350     
       
   351     if(sortColumn() == -1 || sortOrder() != mWantedSortOrder)
       
   352     {
       
   353         // if sorting column is not yet setted, it indicates
       
   354         // that we've setted the sorting order for the first time
       
   355         // and sorting has not yet been done. After we have called sort once,
       
   356         // the sort columnt gets updated and following sorts gets executed
       
   357         // by setSortRole -call as long as role changes.
       
   358     
       
   359         // Another case is when we need to change the sort order, as there is
       
   360         // no other way of setting the sort order than calling sort().
       
   361         sort(0, mWantedSortOrder);
       
   362     }
       
   363 
       
   364     emit modelSorted();
       
   365 }
       
   366 
       
   367 // -----------------------------------------------------------------------------
       
   368 // VideoSortFilterProxyModel::lessThan
       
   369 // -----------------------------------------------------------------------------
       
   370 //
       
   371 bool VideoSortFilterProxyModel::lessThan(const QModelIndex &left,
       
   372     const QModelIndex &right) const
       
   373 {
       
   374     if (!mModel)
       
   375     {
       
   376         return false;
       
   377     }
       
   378     int index = left.row();
       
   379     TMPXItemId leftId = mModel->mediaIdAtIndex(index);
       
   380     index = right.row();
       
   381     TMPXItemId rightId = mModel->mediaIdAtIndex(index);
       
   382     
       
   383     // Default categories are always first in the following order:
       
   384     // Recently played (missing currently)
       
   385     // Captured
       
   386     // Downloaded
       
   387     // Podcasts (missing currently)
       
   388     bool lessThan(false);
       
   389     bool proceedDataSorting(false);
       
   390     if(leftId.iId2  == KVcxMvcMediaTypeCategory &&
       
   391        rightId.iId2 == KVcxMvcMediaTypeCategory)
       
   392     {
       
   393         if(leftId.iId1 == KVcxMvcCategoryIdCaptured)
       
   394         {
       
   395             lessThan = true;
       
   396         }
       
   397    
       
   398         else if(leftId.iId1 == KVcxMvcCategoryIdDownloads)
       
   399         {
       
   400             if(rightId.iId1 != KVcxMvcCategoryIdCaptured)
       
   401             {
       
   402                 lessThan = true;
       
   403             }
       
   404         }
       
   405     }
       
   406     else if(leftId.iId2 == KVcxMvcMediaTypeCategory ||
       
   407             rightId.iId2 == KVcxMvcMediaTypeCategory)
       
   408     {
       
   409         lessThan = (leftId.iId2 == KVcxMvcMediaTypeCategory);
       
   410     }
       
   411     else
       
   412     {
       
   413         proceedDataSorting = true;
       
   414     }
       
   415 
       
   416     if(!proceedDataSorting)
       
   417     {
       
   418         return mWantedSortOrder == Qt::AscendingOrder ? lessThan : !lessThan;
       
   419     }
       
   420     
       
   421     // Do comparisation based on the role:
       
   422     //  VideoCollectionCommon::KeyTitle,
       
   423     //  VideoCollectionCommon::KeySizeValue,
       
   424     //  VideoCollectionCommon::KeyNumberOfItems,
       
   425     //  VideoCollectionCommon::KeyDateValue
       
   426     // 
       
   427     // If role does not match, do not sort
       
   428     int sRole = sortRole();
       
   429     QVariant leftData = sourceModel()->data(left, sRole);
       
   430     QVariant rightData = sourceModel()->data(right, sRole);
       
   431 
       
   432     if(!leftData.isValid() || !rightData.isValid())
       
   433     {
       
   434         return false;
       
   435     }
       
   436     if(sRole == VideoCollectionCommon::KeyTitle)
       
   437     {
       
   438         QString leftString = leftData.toString().toUpper();
       
   439         QString rightString = rightData.toString().toUpper();
       
   440         return QString::localeAwareCompare(leftString, rightString) < 0;
       
   441     }
       
   442     else if(sRole == VideoCollectionCommon::KeySizeValue ||
       
   443             sRole == VideoCollectionCommon::KeyNumberOfItems)
       
   444     {
       
   445         quint32 leftSize = leftData.toUInt();
       
   446         quint32 rightSize = rightData.toUInt();
       
   447         return leftSize < rightSize;
       
   448     }
       
   449     else if(sRole == VideoCollectionCommon::KeyDateTime)
       
   450     {
       
   451         QDateTime leftDateTime = leftData.toDateTime();
       
   452         QDateTime rightDateTime = rightData.toDateTime();
       
   453         // datetime sorting role has inverted sorting order compared to other roles 
       
   454         return rightDateTime < leftDateTime;
       
   455     }
       
   456     return false;
       
   457 }
       
   458 
       
   459 // -----------------------------------------------------------------------------
       
   460 // VideoSortFilterProxyModel::filterAcceptsRow
       
   461 // -----------------------------------------------------------------------------
       
   462 //
       
   463 bool VideoSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
       
   464 {
       
   465     Q_UNUSED(source_parent);
       
   466     
       
   467     if(!sourceModel())
       
   468     {
       
   469         return false;
       
   470     }
       
   471 
       
   472     if(source_row < 0 || source_row >= sourceModel()->rowCount())
       
   473     {
       
   474         return false;
       
   475     }
       
   476     TMPXItemId id = mModel->mediaIdAtIndex(source_row);
       
   477     if(id == TMPXItemId::InvalidId())
       
   478     {
       
   479         return false;
       
   480     }
       
   481     
       
   482     if (mType == VideoCollectionCommon::EModelTypeAllVideos)
       
   483     {
       
   484         if(id.iId2 == KVcxMvcMediaTypeVideo)
       
   485         {
       
   486             return true;
       
   487         }
       
   488     }
       
   489     else if(mType == VideoCollectionCommon::EModelTypeCollections)
       
   490     {
       
   491         if(mLevel == VideoCollectionCommon::ELevelCategory && id.iId2 != KVcxMvcMediaTypeVideo)
       
   492         {
       
   493             return true;
       
   494         }       
       
   495     }
       
   496     else if (mType == VideoCollectionCommon::EModelTypeCollectionContent)
       
   497     {
       
   498         // if item belongs to the open album, accept it
       
   499         if (mModel->belongsToAlbum(id))
       
   500         {
       
   501             return true;
       
   502         }
       
   503     }
       
   504     else if(mType == VideoCollectionCommon::EModelTypeGeneric)
       
   505     {
       
   506         if(mLevel == VideoCollectionCommon::ELevelVideos && id.iId2 == KVcxMvcMediaTypeVideo)
       
   507         {
       
   508             //  filter items that belong to that album setted as filter id
       
   509             // if there's no filter or setted filter is "all videos", we accept everything
       
   510             if(mGenericFilterId == TMPXItemId::InvalidId() || 
       
   511                (mGenericFilterId.iId1 == KVcxMvcCategoryIdAll && 
       
   512                 mGenericFilterId.iId2 == KVcxMvcMediaTypeCategory) ||
       
   513                 mGenericFilterValue == mModel->belongsToAlbum(id, mGenericFilterId))
       
   514             {
       
   515                 return true;
       
   516             }
       
   517         }
       
   518         else if(mLevel == VideoCollectionCommon::ELevelCategory && id.iId2 == KVcxMvcMediaTypeAlbum)    
       
   519         {
       
   520             // we do not filter albums yet
       
   521             return true;
       
   522         }
       
   523     }
       
   524     
       
   525     return false;
       
   526 }
       
   527 
       
   528 // -----------------------------------------------------------------------------
       
   529 // VideoSortFilterProxyModel::getMediaIdAtIndex()
       
   530 // -----------------------------------------------------------------------------
       
   531 //
       
   532 const TMPXItemId& VideoSortFilterProxyModel::getMediaIdAtIndex(const QModelIndex &index) const
       
   533 {
       
   534     if(index.isValid())
       
   535     {
       
   536         int rowIndex = mapToSource(index).row();
       
   537         if(mModel)
       
   538         {
       
   539             return mModel->mediaIdAtIndex(rowIndex);
       
   540         }
       
   541     }
       
   542     return INVALID_ID;
       
   543 }
       
   544 
       
   545 // -----------------------------------------------------------------------------
       
   546 //  VideoSortFilterProxyModel::indexOfId()
       
   547 // -----------------------------------------------------------------------------
       
   548 //
       
   549 QModelIndex VideoSortFilterProxyModel::indexOfId(const TMPXItemId &id)
       
   550 {    
       
   551     QModelIndex sourceIndex;
       
   552     if(!mModel || id == TMPXItemId::InvalidId())
       
   553     {
       
   554         return sourceIndex;
       
   555     }
       
   556     sourceIndex = mModel->indexOfId(id);
       
   557     return mapFromSource(sourceIndex);
       
   558 }
       
   559 
       
   560 // -----------------------------------------------------------------------------
       
   561 // VideoSortFilterProxyModel::getMediaFilePathForId()
       
   562 // -----------------------------------------------------------------------------
       
   563 //
       
   564 QString VideoSortFilterProxyModel::getMediaFilePathForId(const TMPXItemId &mediaId)
       
   565 {
       
   566     QString filePath;
       
   567     if(mModel)
       
   568     {
       
   569         filePath = mModel->mediaFilePathForId(mediaId);
       
   570     }
       
   571     return filePath;
       
   572 }
       
   573 
       
   574 // -----------------------------------------------------------------------------
       
   575 // VideoSortFilterProxyModel::addNewAlbum()
       
   576 // -----------------------------------------------------------------------------
       
   577 //
       
   578 TMPXItemId VideoSortFilterProxyModel::addNewAlbum(const QString &title)
       
   579 {
       
   580 	FUNC_LOG_ADDR(this);
       
   581     TMPXItemId id = TMPXItemId::InvalidId();
       
   582     
       
   583     if (mCollectionClient)
       
   584     {
       
   585         id = mCollectionClient->addNewAlbum(title);
       
   586     }
       
   587     
       
   588     return id;
       
   589 }
       
   590 
       
   591 // -----------------------------------------------------------------------------
       
   592 // VideoSortFilterProxyModel::removeAlbums()
       
   593 // -----------------------------------------------------------------------------
       
   594 //
       
   595 int VideoSortFilterProxyModel::removeAlbums(const QModelIndexList &indexList)
       
   596 {
       
   597 	FUNC_LOG_ADDR(this);
       
   598 	int err(-1);
       
   599     
       
   600 	if (mCollectionClient)
       
   601 	{
       
   602 		TMPXItemId mpxId;
       
   603 		QList<TMPXItemId> ids;
       
   604 
       
   605 		for(int i = 0; i < indexList.count(); ++i)
       
   606 		{
       
   607 			mpxId = getMediaIdAtIndex(indexList.at(i));
       
   608 			if((mpxId != TMPXItemId::InvalidId()) && (mpxId.iId2 == KVcxMvcMediaTypeAlbum))
       
   609 			{
       
   610 				ids.append(getMediaIdAtIndex(indexList.at(i)));
       
   611 			}
       
   612 		}
       
   613 		
       
   614 		if (ids.count())
       
   615 		{
       
   616 			err = mCollectionClient->removeAlbums(ids);
       
   617 		}
       
   618 	}
       
   619 
       
   620     return err;
       
   621 }
       
   622 
       
   623 // -----------------------------------------------------------------------------
       
   624 // VideoSortFilterProxyModel::resolveAlbumName()
       
   625 // -----------------------------------------------------------------------------
       
   626 //
       
   627 QString VideoSortFilterProxyModel::resolveAlbumName(
       
   628     const QString& albumName) const
       
   629 {
       
   630 	FUNC_LOG_ADDR(this);
       
   631     QString resolvedName = albumName.trimmed();
       
   632 
       
   633     // for checking names, we need to use collection list proxy model 
       
   634     // to get all existing album names including default ones
       
   635     VideoSortFilterProxyModel *collectionModel = 
       
   636                        VideoCollectionWrapper::instance().getModel(
       
   637                                    VideoCollectionCommon::EModelTypeCollections);
       
   638     if(!collectionModel || !mModel)
       
   639     {
       
   640         return resolvedName;
       
   641     }    
       
   642     
       
   643     int i(0);
       
   644     QModelIndex proxyIndex = collectionModel->index(i, 0);
       
   645     QSet<QString> names;
       
   646     QVariant data;
       
   647     // create set of existing names
       
   648     while (proxyIndex.isValid())
       
   649     {
       
   650         data = mModel->data(collectionModel->mapToSource(proxyIndex), VideoCollectionCommon::KeyTitle);
       
   651         if (data.isValid())
       
   652         {
       
   653             names.insert(data.toString());
       
   654         }
       
   655         proxyIndex = collectionModel->index(++i, 0, QModelIndex());
       
   656     }
       
   657     i = 0;
       
   658     QString firstMatch("");
       
   659     // find a name that does not yet exists
       
   660     while(names.contains(resolvedName))
       
   661     {
       
   662         if (!firstMatch.length())
       
   663         {
       
   664             firstMatch = resolvedName;
       
   665         }
       
   666         ++i;
       
   667         resolvedName = tr("%1 (%2)").arg(firstMatch).arg(i);
       
   668     }
       
   669     return resolvedName;
       
   670 }
       
   671 
       
   672 // -----------------------------------------------------------------------------
       
   673 // VideoSortFilterProxyModel::addItemsInAlbum()
       
   674 // -----------------------------------------------------------------------------
       
   675 //
       
   676 int VideoSortFilterProxyModel::addItemsInAlbum(TMPXItemId &albumId,
       
   677         const QList<TMPXItemId> &mediaIds)
       
   678 {
       
   679 	FUNC_LOG_ADDR(this);
       
   680     int err(-1);
       
   681     
       
   682     if (mCollectionClient)
       
   683     {        
       
   684         // add items in album
       
   685         err = mCollectionClient->addItemsInAlbum(albumId, mediaIds);
       
   686     }
       
   687     
       
   688     return err;
       
   689 }
       
   690 
       
   691 // -----------------------------------------------------------------------------
       
   692 // VideoSortFilterProxyModel::removeItemsFromAlbum()
       
   693 // -----------------------------------------------------------------------------
       
   694 //
       
   695 int VideoSortFilterProxyModel::removeItemsFromAlbum(TMPXItemId &albumId, 
       
   696         const QList<TMPXItemId> &mediaIds)
       
   697 {
       
   698 	FUNC_LOG_ADDR(this);
       
   699     int err(-1);
       
   700 
       
   701     // Disable thumbnail fetching while items are removed from the model. 
       
   702     VideoThumbnailData::instance().enableBackgroundFetching(false);
       
   703     
       
   704     if (mModel)
       
   705     {
       
   706         // remove items in album
       
   707         err = mModel->removeItemsFromAlbum(albumId, mediaIds);
       
   708         if(err > 0)
       
   709         {
       
   710             // if there really were items to be removed, invalid filter
       
   711             INFO_1("VideoSortFilterProxyModel::removeItemsFromAlbum() [0x%x] items removed, invaliding.", this);
       
   712             invalidateFilter();
       
   713             err = 0;
       
   714         }
       
   715     }
       
   716  
       
   717     VideoThumbnailData::instance().enableBackgroundFetching(true);
       
   718     return err;
       
   719 }
       
   720 
       
   721 // -----------------------------------------------------------------------------
       
   722 // VideoSortFilterProxyModel::renameItem()
       
   723 // -----------------------------------------------------------------------------
       
   724 //
       
   725 int VideoSortFilterProxyModel::renameItem(const TMPXItemId &itemId, const QString &newTitle)
       
   726 {
       
   727 	FUNC_LOG_ADDR(this);
       
   728     int err(-1);
       
   729 
       
   730     if(mCollectionClient)
       
   731     {
       
   732         return mCollectionClient->renameItem(itemId, newTitle);
       
   733     }
       
   734     return err;
       
   735 }
       
   736 
       
   737 // -----------------------------------------------------------------------------
       
   738 // VideoSortFilterProxyModel::getOpenItem()
       
   739 // -----------------------------------------------------------------------------
       
   740 //
       
   741 TMPXItemId VideoSortFilterProxyModel::getOpenItem() const
       
   742 {
       
   743 	FUNC_LOG_ADDR(this);
       
   744     TMPXItemId itemId = TMPXItemId::InvalidId();
       
   745     
       
   746     if(mModel && mCollectionClient)
       
   747     {
       
   748         if(mType == VideoCollectionCommon::EModelTypeAllVideos)
       
   749         {
       
   750             INFO_1("VideoSortFilterProxyModel::getOpenItem() [0x%x] all videos is open.", this);
       
   751             itemId.iId1 = KVcxMvcCategoryIdAll;
       
   752             itemId.iId2 = KVcxMvcMediaTypeCategory;
       
   753         }
       
   754         else if(mType == VideoCollectionCommon::EModelTypeCollectionContent)
       
   755         {
       
   756             INFO_1("VideoSortFilterProxyModel::getOpenItem() [0x%x] category or album is open.", this);
       
   757             itemId = mModel->albumInUse();
       
   758         }
       
   759     }
       
   760 
       
   761     return itemId;
       
   762 }
       
   763 
       
   764 // -----------------------------------------------------------------------------
       
   765 // VideoSortFilterProxyModel::setGenericIdFilter()
       
   766 // -----------------------------------------------------------------------------
       
   767 //
       
   768 void VideoSortFilterProxyModel::setGenericIdFilter(const TMPXItemId &itemId, bool filterValue)
       
   769 {
       
   770 	FUNC_LOG_ADDR(this);
       
   771     if(mType == VideoCollectionCommon::EModelTypeGeneric)
       
   772     {
       
   773         INFO_3("VideoSortFilterProxyModel::setGenericIdFilter() [0x%x] itemId.iId2: %d, filterValue: %d", this, itemId.iId2, filterValue);
       
   774         mGenericFilterId = itemId;
       
   775         mGenericFilterValue = filterValue;
       
   776         INFO_1("VideoSortFilterProxyModel::setGenericIdFilter() [0x%x] invalidating.", this);
       
   777         invalidateFilter();
       
   778     }
       
   779 }
       
   780 
       
   781 // -----------------------------------------------------------------------------
       
   782 // VideoSortFilterProxyModel::setAlbumInUse()
       
   783 // -----------------------------------------------------------------------------
       
   784 //
       
   785 void VideoSortFilterProxyModel::setAlbumInUse(const TMPXItemId &albumId)
       
   786 {
       
   787 	FUNC_LOG_ADDR(this);
       
   788     if(mModel)
       
   789     {
       
   790         INFO_1("VideoSortFilterProxyModel::setAlbumInUse() [0x%x] invalidating.", this);
       
   791         mModel->setAlbumInUse(albumId);
       
   792         invalidateFilter();
       
   793     }
       
   794 }
       
   795 
       
   796 // -----------------------------------------------------------------------------
       
   797 // VideoSortFilterProxyModel::albumChangedSlot()
       
   798 // -----------------------------------------------------------------------------
       
   799 //
       
   800 void VideoSortFilterProxyModel::albumChangedSlot()
       
   801 {
       
   802 	FUNC_LOG_ADDR(this);
       
   803     // ignore if not collection content model
       
   804     if (mType == VideoCollectionCommon::EModelTypeCollectionContent)
       
   805     {
       
   806         INFO_1("VideoSortFilterProxyModel::albumChangedSlot() [0x%x] invalidating.", this);
       
   807 	    // sort and invalidate filtering, otherwise newly created album content won't sort
       
   808     	invalidateFilter();
       
   809     	setSortRole(mWantedSortRole);
       
   810         sort(0, mWantedSortOrder);
       
   811     }
       
   812 }
       
   813 
       
   814 // -----------------------------------------------------------------------------
       
   815 // VideoSortFilterProxyModel::getType()
       
   816 // -----------------------------------------------------------------------------
       
   817 //
       
   818 VideoCollectionCommon::TModelType VideoSortFilterProxyModel::getType()
       
   819 {
       
   820 	FUNC_LOG_ADDR(this);
       
   821 	return mType;
       
   822 }
       
   823 
       
   824 // End of file