EngSrc/IEImageList.cpp
changeset 3 93fff7023be8
equal deleted inserted replaced
2:e1e28b0273b0 3:93fff7023be8
       
     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: Juha Kauppinen, Mika Hokkanen
       
    13 * 
       
    14 * Description: Photo Browser
       
    15 *
       
    16 */
       
    17 
       
    18 // INCLUDE FILES
       
    19 
       
    20 #include <eikenv.h>
       
    21 #include <exifread.h>
       
    22 #include <f32file.h>
       
    23 #include <s32file.h>
       
    24 #include <bautils.h>
       
    25 #include "IEImageList.h"
       
    26 #include "IEImageData.h"
       
    27 #include "IEEngineImp.h"
       
    28 #include "IEEngineUtils.h"
       
    29 #include "ImageMonitorAO.h"
       
    30 #include "IEFileLoader.h"
       
    31 #ifdef _S60_5x_ACCELEROMETER_
       
    32 #include "IESensorMonitor.h"
       
    33 #endif
       
    34 
       
    35 #define LATETHUMBCHECK
       
    36 //#define GROUP_FOLDERS_BY_NAME
       
    37 #define CHECK_IF_IMAGE_IS_VISIBLE
       
    38 
       
    39 _LIT(KDatabaseFileName, "photobrowser.db");
       
    40 _LIT8(KDatabaseId, "IMGC0008");
       
    41 const TInt KNumOfDrives = 3;
       
    42 
       
    43 EXPORT_C CIEImageList* CIEImageList::NewL(        
       
    44         RArray<CImageData*>& aImageData, 
       
    45         CIEFileLoader* aCallback)
       
    46     {
       
    47     CIEImageList* self = new (ELeave) CIEImageList(aImageData, aCallback);
       
    48     CleanupStack::PushL(self);
       
    49     self->ConstructL();
       
    50     CleanupStack::Pop();
       
    51     return self;
       
    52     }
       
    53 
       
    54 CIEImageList::CIEImageList(
       
    55         RArray<CImageData*>& aImageData, 
       
    56         CIEFileLoader* aCallback) :
       
    57     iCallback(aCallback),
       
    58     iImageDataList(aImageData),
       
    59     iGridMode(EGridModeTime)	
       
    60     {
       
    61     for (TInt i = 0;i < KNumOfDrives;i++)
       
    62         iDatabaseChanged[i] = EFalse; 
       
    63     }
       
    64 
       
    65 void CIEImageList::ConstructL() 
       
    66     {
       
    67     User::LeaveIfError(iCritical.CreateLocal());
       
    68     }
       
    69         
       
    70 EXPORT_C CIEImageList::~CIEImageList()
       
    71     {
       
    72     iCritical.Close();
       
    73     }
       
    74         
       
    75 EXPORT_C void CIEImageList::SetGridMode(TGridMode aGridMode)
       
    76     {
       
    77     if (iGridMode != aGridMode) 
       
    78         {
       
    79         iGridMode = aGridMode;
       
    80         iCritical.Wait();
       
    81         Rearrange(0);
       
    82         iCritical.Signal();
       
    83         }
       
    84     }
       
    85 
       
    86 EXPORT_C TGridMode CIEImageList::GetGridMode() const
       
    87     {
       
    88     return iGridMode; 
       
    89     }
       
    90 
       
    91 EXPORT_C void CIEImageList::SetChanged(TDesC& aPath)
       
    92     {
       
    93     TImageListDrive drive = EImageListDriveC;
       
    94     TRAPD(err, drive = GetPathDriveL(aPath));
       
    95     if (err == KErrNone)
       
    96         {
       
    97         iDatabaseChanged[drive] = ETrue;
       
    98         }
       
    99     }
       
   100 
       
   101 void CIEImageList::SetChanged(CImageData* aImageData)
       
   102     {
       
   103     TFileName fileName;
       
   104     aImageData->GetFileName(fileName, EFullSize);
       
   105     SetChanged(fileName);
       
   106     }
       
   107 
       
   108 CImageData* CIEImageList::CreateImageDataL(
       
   109         const TFileName& aFileName, 
       
   110         const TTime& aTime,
       
   111         const TReal orientation)
       
   112     {
       
   113     DP0_IMAGIC(_L("CIEImageList::CreateImageDataL++"));
       
   114     
       
   115     // Create new image data instance
       
   116     CImageData* imageData = CImageData::NewL(
       
   117 #ifdef LATETHUMBCHECK            
       
   118             /*EFullSize|*/ESize512x512|ESize128x128|ESize32x32
       
   119 #endif            
       
   120             );
       
   121     
       
   122     imageData->SetCreatedTime(aTime);
       
   123     imageData->SetFileNameL(aFileName);
       
   124     imageData->SetOrientation(orientation);    
       
   125     
       
   126 #ifdef _S60_5x_ACCELEROMETER_
       
   127     // Portrait
       
   128     if(iCallback->DeviceOrientation() == TSensrvOrientationData::EOrientationDisplayUp)
       
   129         {
       
   130         imageData->iGridData.iTargetRotationAngle = 90 + orientation;
       
   131         }
       
   132     // Landscape
       
   133     else//(iCallback->DeviceOrientation() == TSensrvOrientationData::EOrientationDisplayRightUp)
       
   134         {
       
   135         imageData->iGridData.iTargetRotationAngle = orientation;
       
   136         }
       
   137     imageData->iGridData.iRotationAngle = orientation;
       
   138 #else
       
   139     imageData->iGridData.iRotationAngle = orientation;
       
   140     imageData->iGridData.iTargetRotationAngle = orientation;
       
   141 #endif
       
   142     
       
   143     DP1_IMAGIC(_L("CIEImageList::AddImageL - filename: %S"), &aFileName);
       
   144 
       
   145 #ifndef LATETHUMBCHECK    
       
   146     //Check and mark to imageData which thumbnails exists
       
   147     CheckCreatedThumbnails(*imageData);
       
   148 #endif
       
   149     
       
   150     DP0_IMAGIC(_L("CIEImageList::CreateImageDataL--"));
       
   151     return imageData;
       
   152     }
       
   153     
       
   154 TBool CIEImageList::IsImageBefore(CImageData* aNewImageData, TInt aIndex) const
       
   155     {
       
   156     if (aIndex >= iImageDataList.Count())
       
   157         return ETrue;
       
   158     
       
   159     // Use folder grouping
       
   160     if (iGridMode != EGridModeTime)      
       
   161         {
       
   162         TFileName newPath, path;
       
   163         aNewImageData->GetPath(newPath);
       
   164         iImageDataList[aIndex]->GetPath(path);
       
   165 
       
   166 #ifdef GROUP_FOLDERS_BY_NAME
       
   167         // Folders are sorted by name
       
   168         if (newPath > path)      // TODO: should trim drive + base path (e.g. C:\data\)
       
   169             return ETrue;
       
   170         if (newPath < path)
       
   171             return EFalse;
       
   172 #else
       
   173 
       
   174         if (iGridMode == EGridModePeople)
       
   175             {
       
   176             return (iImageDataList[aIndex]->iPersonId > 
       
   177                     aNewImageData->iPersonId);
       
   178             }
       
   179         else if (iGridMode == EGridModeFolder && aIndex > 0)
       
   180             {
       
   181             // Current image path is not same
       
   182             if (path != newPath)
       
   183                 {
       
   184                 TFileName prevPath;
       
   185                 iImageDataList[aIndex - 1]->GetPath(prevPath);
       
   186                   
       
   187                 // Previous image path is same, add after that
       
   188                 if (newPath == prevPath)
       
   189                      return ETrue;
       
   190                 
       
   191                 // Compare only against the first image in the folder
       
   192                 if (path == prevPath)
       
   193                      return EFalse;
       
   194                 }
       
   195             }
       
   196 #endif
       
   197         }
       
   198     
       
   199     // Compare times
       
   200     return (aNewImageData->GetCreatedTime() > iImageDataList[aIndex]->GetCreatedTime());
       
   201     }
       
   202 
       
   203 TInt CIEImageList::GetNewImageIndex(CImageData* aImageData) const
       
   204     {
       
   205     TInt index = 0; 
       
   206     while(index < iImageDataList.Count())
       
   207         {
       
   208         if(IsImageBefore(aImageData, index))
       
   209             {
       
   210             break;
       
   211             }
       
   212         index++;
       
   213         }
       
   214     return index;
       
   215     }
       
   216 
       
   217 void CIEImageList::Rearrange(TInt aStartIndex)
       
   218     {
       
   219     for (TInt i = aStartIndex;i < iImageDataList.Count();i++)
       
   220         {
       
   221         CImageData* imageData = iImageDataList[i];            
       
   222         iImageDataList.Remove(i);
       
   223         TInt newIndex = GetNewImageIndex(imageData);
       
   224         iImageDataList.Insert(imageData, newIndex);
       
   225         }
       
   226     }
       
   227 
       
   228 EXPORT_C void CIEImageList::AddImage(CImageData* aImageData)
       
   229     {
       
   230     DP0_IMAGIC(_L("CIEImageList::AddImageL++"));
       
   231     
       
   232     iCritical.Wait();  
       
   233     
       
   234     // Insert image to list
       
   235     TInt index = GetNewImageIndex(aImageData);
       
   236     iImageDataList.Insert(aImageData, index);
       
   237         
       
   238     // Need to resort all items if use time based folder sort
       
   239 #ifndef GROUP_FOLDERS_BY_NAME
       
   240     if (iGridMode != EGridModeTime)      
       
   241         {
       
   242         Rearrange(index + 1);
       
   243         }
       
   244 #endif        
       
   245 
       
   246     // Image is not added as last image
       
   247     if (index < iImageDataList.Count() - 1)
       
   248         {
       
   249         // Mark database as changed
       
   250         SetChanged(aImageData);
       
   251         
       
   252         // Inform UI
       
   253         //iCallback->ImageListChanged(index, ETrue);
       
   254         }
       
   255     
       
   256     iCallback->ImageListChanged(index, ETrue);
       
   257     
       
   258     iCritical.Signal();
       
   259     
       
   260     DP0_IMAGIC(_L("CIEImageList::AddImageL-- tmpImageData"));
       
   261     }
       
   262 
       
   263 #ifdef IMAGIC_DATABASE
       
   264 
       
   265 void CIEImageList::GetDatabaseFileName(TFileName& aFileName, TImageListDrive aDrive)
       
   266     {
       
   267     switch (aDrive)
       
   268         {
       
   269         case EImageListDriveC:
       
   270             aFileName.Copy(PathInfo::PhoneMemoryRootPath());
       
   271             break;
       
   272             
       
   273         case EImageListDriveE:
       
   274             aFileName.Copy(PathInfo::MemoryCardRootPath());
       
   275             break;
       
   276             
       
   277         case EImageListDriveF:           
       
   278             aFileName.Copy(KRootPathFDrive);
       
   279             break;
       
   280            
       
   281         default:
       
   282             return;
       
   283         }
       
   284     
       
   285     aFileName.Append(KDatabaseFileName);
       
   286     }
       
   287 
       
   288 EXPORT_C void CIEImageList::ReadDatabaseL()
       
   289     {  
       
   290     DP0_IMAGIC(_L("CIEImageList::ReadDatabaseL++"));
       
   291 
       
   292     RFileReadStream readStreams[KNumOfDrives];
       
   293     TBool openStreams[KNumOfDrives];
       
   294     CImageData* imageDatas[KNumOfDrives];
       
   295     RFs fs;
       
   296     
       
   297     User::LeaveIfError(fs.Connect());
       
   298     CleanupClosePushL(fs);
       
   299     
       
   300     // Open databases
       
   301     for (TInt i = 0;i < KNumOfDrives;i++)
       
   302         {
       
   303         openStreams[i] = EFalse;
       
   304         imageDatas[i] = NULL;        
       
   305         
       
   306         TFileName databaseFileName;
       
   307         GetDatabaseFileName(databaseFileName, TImageListDrive(i));
       
   308         if (readStreams[i].Open(fs, databaseFileName, EFileShareAny) == KErrNone)
       
   309             {
       
   310             // Check file validity and version
       
   311             TUint8 buf[8];
       
   312             TPtr8 ptr(buf, sizeof(buf));
       
   313             readStreams[i].ReadL(ptr, KDatabaseId.iTypeLength);
       
   314             if (ptr.Compare(KDatabaseId) != 0)
       
   315                 readStreams[i].Close();
       
   316             else
       
   317                 openStreams[i] = ETrue;
       
   318             }
       
   319         }
       
   320     
       
   321     // Read databases
       
   322     while(iCallback->ImageFinderState() == CIEFileLoader::EImageFinderRunning)
       
   323         {
       
   324         // Read image datas from each database
       
   325         TBool endOfData = ETrue;
       
   326         for(TInt i = 0;i < KNumOfDrives;i++)
       
   327             {
       
   328             // Database is open and no image data is left
       
   329             if (imageDatas[i] == NULL && openStreams[i])
       
   330                 {
       
   331                 TRAPD(err, imageDatas[i] = ReadImageDataL(readStreams[i], fs));
       
   332                 if (err != KErrNone || imageDatas[i] == NULL) 
       
   333                     {
       
   334                     openStreams[i] = EFalse;
       
   335                     readStreams[i].Close();
       
   336                     }
       
   337                 }
       
   338             
       
   339             if (imageDatas[i])
       
   340                 endOfData = EFalse;
       
   341             }
       
   342         
       
   343         if (endOfData)
       
   344             break;
       
   345         
       
   346         // Pick the most leftmost image 
       
   347         TInt index = -1;
       
   348         for (TInt i = 0;i < KNumOfDrives;i++)
       
   349             {
       
   350             if (imageDatas[i] && 
       
   351                     (index < 0 || 
       
   352                      IsImageBefore(imageDatas[i], index)))
       
   353                 index = i;
       
   354             }
       
   355             
       
   356         // Add image to list
       
   357         if (index >= 0) 
       
   358             {
       
   359             AddImage(imageDatas[index]);
       
   360             imageDatas[index] = NULL;
       
   361             }
       
   362         }
       
   363     
       
   364     CleanupStack::Pop();
       
   365     fs.Close();
       
   366 
       
   367     DP0_IMAGIC(_L("CIEImageList::ReadDatabaseL--"));
       
   368     }
       
   369 
       
   370 CImageData* CIEImageList::ReadImageDataL(RFileReadStream& readStream, RFs& aFs)
       
   371     {
       
   372     TUint8 buf[KMaxFileName * 2];
       
   373     TPtr8 ptr(buf, sizeof(buf));
       
   374     TFileName fileName;
       
   375     TTime fileTime, createdTime;
       
   376     TSize size;
       
   377     TInt faces;
       
   378     TUint16 orientation;
       
   379     CImageData* imageData = NULL;
       
   380            
       
   381     // Read until get valid image data
       
   382     while (imageData == NULL) {
       
   383     
       
   384         // Read file name (1 byte length, unicode name)
       
   385         TInt len = readStream.ReadUint8L();
       
   386     
       
   387         // End of list
       
   388         if (len == 0)
       
   389             return NULL;
       
   390 
       
   391         readStream.ReadL(ptr, len * 2);
       
   392         TPtrC16 ptr16((const TUint16*)buf, len);
       
   393         fileName.Copy(ptr16);
       
   394             
       
   395         // Read file time
       
   396         readStream.ReadL(ptr, sizeof(TTime));
       
   397         fileTime = *(TTime*)ptr.Ptr();
       
   398 
       
   399         // Read created time
       
   400         readStream.ReadL(ptr, sizeof(TTime));
       
   401         createdTime = *(TTime*)ptr.Ptr();                    
       
   402 
       
   403         // Read orientation (in 90 degrees angles)
       
   404         orientation = readStream.ReadUint8L() * 90L;
       
   405             
       
   406         // Read resolution
       
   407         size.iWidth = readStream.ReadUint32L();
       
   408         size.iHeight = readStream.ReadUint32L();
       
   409 
       
   410         // Read number of faces
       
   411         faces = readStream.ReadInt8L();
       
   412         
       
   413         TInt personId = readStream.ReadInt32L();
       
   414 
       
   415         // Check that no multiple entries
       
   416         if ((imageData = GetImageData(fileName)) != NULL) 
       
   417             {
       
   418             imageData = NULL;
       
   419             continue;
       
   420             }
       
   421         
       
   422         // Check if image exist and not be hidden
       
   423         TInt error = KErrNone;
       
   424         TBool visible = ETrue;
       
   425 #ifdef CHECK_IF_IMAGE_IS_VISIBLE        
       
   426 
       
   427         TRAP(error, visible = IsImageViewableL(fileName, aFs));
       
   428 #endif        
       
   429         if (error == KErrNone && visible)
       
   430             {
       
   431             // Create image data object
       
   432             imageData = CreateImageDataL(
       
   433                     fileName, 
       
   434                     createdTime, 
       
   435                     orientation);
       
   436 
       
   437             if (imageData) 
       
   438                 {
       
   439                 imageData->SetFileTime(fileTime);
       
   440                 imageData->SetSize(size);
       
   441                 imageData->SetNumberOfFaces(faces);
       
   442                 imageData->iPersonId = personId;
       
   443                 //imageData->SetImageReady(EFullSize, ETrue);
       
   444                 }        
       
   445             }
       
   446         else
       
   447             {
       
   448             // Delete thumbnails if file could not be read
       
   449             if (error != KErrNone)
       
   450                 CIEEngineUtils::DeleteThumbnails(fileName, aFs);
       
   451             SetChanged(fileName);
       
   452             }
       
   453         }
       
   454     
       
   455     return imageData;
       
   456     }
       
   457     
       
   458 EXPORT_C void CIEImageList::WriteDatabaseL() 
       
   459     {
       
   460     DP0_IMAGIC(_L("CIEImageList::WriteDatabaseL++"));
       
   461 
       
   462     RFs fs;
       
   463     User::LeaveIfError(fs.Connect());
       
   464     CleanupClosePushL(fs);
       
   465     
       
   466     for (TInt i = 0;i < KNumOfDrives;i++) 
       
   467         {
       
   468         if (iDatabaseChanged[i])
       
   469             {
       
   470             TRAP_IGNORE(WriteDatabaseL(TImageListDrive(i), fs)); 
       
   471             iDatabaseChanged[i] = EFalse;
       
   472             }
       
   473         }
       
   474     
       
   475     CleanupStack::Pop(); // fs
       
   476     fs.Close();    
       
   477     
       
   478     DP0_IMAGIC(_L("CIEImageList::WriteDatabaseL--"));    
       
   479     }
       
   480         
       
   481 void CIEImageList::WriteDatabaseL(TImageListDrive aDrive, RFs& aFs)
       
   482     {
       
   483     TUint8 buf[sizeof(TUint32)];
       
   484     TPtr8 ptr(buf, sizeof(buf));
       
   485     RFile f;
       
   486 
       
   487     TFileName path, fileName;
       
   488     GetDatabaseFileName(fileName, aDrive);
       
   489     
       
   490     TParse parser;
       
   491     parser.Set(fileName, NULL, NULL);
       
   492     path = parser.DriveAndPath();
       
   493     TRAP_IGNORE(BaflUtils::EnsurePathExistsL(aFs, path));    
       
   494     
       
   495     if (f.Replace(
       
   496             aFs, 
       
   497             fileName, 
       
   498             EFileWrite) != KErrNone) 
       
   499         return;
       
   500         
       
   501     CleanupClosePushL(f);
       
   502     
       
   503     f.SetAtt(KEntryAttHidden, 0);
       
   504     
       
   505     RFileWriteStream writeStream(f); 
       
   506     CleanupClosePushL(writeStream); 
       
   507     
       
   508     writeStream.WriteL(KDatabaseId);
       
   509 
       
   510     for (TInt32 i = 0;i < iImageDataList.Count();i++)
       
   511         {
       
   512         TFileName fileName;
       
   513         TImageListDrive drive = EImageListDriveC;
       
   514         iImageDataList[i]->GetFileName(fileName, EFullSize);
       
   515         
       
   516         // Write only files that belong to this drive
       
   517         TRAPD(err, drive = GetPathDriveL(fileName));
       
   518         if (err != KErrNone || drive != aDrive)
       
   519             continue;
       
   520 
       
   521         // Write file name
       
   522         writeStream.WriteUint8L(fileName.Length());
       
   523         writeStream.WriteL(fileName, fileName.Length());
       
   524           
       
   525         // Write file time
       
   526         TTime fileTime = iImageDataList[i]->GetFileTime();
       
   527         TPtrC8 fileTimeptr((const TUint8 *)&fileTime, sizeof(TTime));
       
   528         writeStream.WriteL(fileTimeptr);
       
   529 
       
   530         // Write created time
       
   531         TTime createdTime = iImageDataList[i]->GetCreatedTime();
       
   532         TPtrC8 createdTimeptr((const TUint8 *)&createdTime, sizeof(TTime));
       
   533         writeStream.WriteL(createdTimeptr);
       
   534 
       
   535         // Write orientation (in 90 degrees)
       
   536         writeStream.WriteUint8L(iImageDataList[i]->GetOrientation() / 90);
       
   537                 
       
   538         // Write size
       
   539         writeStream.WriteUint32L(iImageDataList[i]->GetSize().iWidth);
       
   540         writeStream.WriteUint32L(iImageDataList[i]->GetSize().iHeight);
       
   541 
       
   542         // Write number of faces
       
   543         writeStream.WriteInt8L(iImageDataList[i]->GetNumberOfFaces());
       
   544         writeStream.WriteInt32L(iImageDataList[i]->iPersonId);
       
   545         }
       
   546 
       
   547     // End of stream notification
       
   548     writeStream.WriteUint8L(0);
       
   549     
       
   550     writeStream.Close();
       
   551     
       
   552     CleanupStack::PopAndDestroy(); // write stream
       
   553     CleanupStack::PopAndDestroy(); // f
       
   554     }
       
   555 #endif
       
   556 
       
   557 EXPORT_C TBool CIEImageList::IsImageViewableL(TDesC& aFileName, RFs& aFs) const 
       
   558     {
       
   559     TUint att;
       
   560     //if(!IsFileExist(fileName))
       
   561     TInt error = aFs.Att(aFileName, att);
       
   562     if (error != KErrNone)
       
   563         User::Leave(error);
       
   564     
       
   565     return ((att & KEntryAttHidden) == KEntryAttHidden) ? EFalse : ETrue;  
       
   566     }
       
   567 
       
   568 EXPORT_C TInt CIEImageList::GetImageIndex(CImageData* aImageData)
       
   569     {
       
   570     for (TInt i = 0;i < iImageDataList.Count();i++) 
       
   571         {
       
   572         if (aImageData == iImageDataList[i])
       
   573             return i;
       
   574         }
       
   575     return -1;
       
   576     }
       
   577 
       
   578 EXPORT_C CImageData* CIEImageList::GetImageData(const TFileName& aFileName)
       
   579     {
       
   580     CImageData* imageData = NULL;
       
   581     iCritical.Wait();
       
   582     
       
   583     for (TInt i = 0;i < iImageDataList.Count();i++) 
       
   584         {
       
   585         TFileName fileName;
       
   586         iImageDataList[i]->GetFileName(fileName, EFullSize);
       
   587         if (fileName.Compare(aFileName) == 0)
       
   588             {
       
   589             imageData = iImageDataList[i];
       
   590             break;
       
   591             }
       
   592         }
       
   593     
       
   594     iCritical.Signal();
       
   595         
       
   596     return imageData;
       
   597     }
       
   598 
       
   599 EXPORT_C void CIEImageList::RemoveNonExistImagesL(TDesC* aPath, RFs& aFs)
       
   600     {
       
   601     DP0_IMAGIC(_L("CIEImageList::RemoveNonExistImagesL++"));
       
   602     
       
   603     TInt i = 0;
       
   604     while (i < iImageDataList.Count()) 
       
   605         {
       
   606         iCritical.Wait();
       
   607         
       
   608         // File may not exist
       
   609         TBool bRemove = !iImageDataList[i]->IsImageReady(EFullSize); 
       
   610         
       
   611         // Start of path must be same
       
   612         if (bRemove && aPath) {
       
   613             TFileName path;
       
   614             iImageDataList[i]->GetPath(path);
       
   615             bRemove = (aPath->Compare(path) == 0);
       
   616         }
       
   617 
       
   618         iCritical.Signal();
       
   619         
       
   620         // Remove from list
       
   621         if (bRemove)
       
   622             {
       
   623             Remove(i, aFs);
       
   624             if (aPath)
       
   625                 SetChanged(*aPath);
       
   626             }
       
   627         else
       
   628             {
       
   629             i++;
       
   630             }
       
   631         }
       
   632     
       
   633     DP0_IMAGIC(_L("CIEImageList::RemoveNonExistImagesL--"));
       
   634     }
       
   635 
       
   636 CIEImageList::TImageListDrive CIEImageList::GetPathDriveL(TDesC& aPath)
       
   637     {
       
   638     TParse parser;
       
   639     parser.Set(aPath, NULL, NULL);
       
   640     TPtrC drive = parser.Drive();
       
   641     const TPtrC drives[] = { _L("C:"), _L("E:"), _L("F:") };
       
   642     
       
   643     for (TInt i = 0;i < sizeof(drives) / sizeof(TPtrC);i++)
       
   644         {
       
   645         if (drive.Compare(drives[i]) == 0)
       
   646             {
       
   647             return TImageListDrive(i);
       
   648             }
       
   649         }
       
   650     
       
   651     User::Leave(KErrArgument);
       
   652     return EImageListDriveC;
       
   653     }
       
   654 
       
   655 EXPORT_C void CIEImageList::Remove(TInt aIndex, RFs& aFs)
       
   656     {
       
   657     TFileName fileName;
       
   658     
       
   659     if (aIndex < 0 || aIndex >= iImageDataList.Count())
       
   660         return;
       
   661     
       
   662     // Delete thumbnails if original file doesn't exist anymore
       
   663     iImageDataList[aIndex]->GetFileName(fileName, EFullSize);
       
   664     if(!BaflUtils::FileExists(aFs, fileName))
       
   665         CIEEngineUtils::DeleteThumbnails(fileName, aFs);
       
   666     
       
   667     iCritical.Wait();
       
   668     
       
   669     // Remove from the list
       
   670     CImageData* pRemovedImageData = iImageDataList[aIndex];
       
   671     iImageDataList.Remove(aIndex);
       
   672     delete pRemovedImageData;
       
   673     
       
   674     iCritical.Signal();
       
   675     
       
   676     SetChanged(fileName);
       
   677     
       
   678     iCallback->ImageListChanged(aIndex, EFalse);
       
   679     }