|
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 } |