1 /* |
|
2 * Copyright (c) 2006-2007 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: Store for thumbnails. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #ifndef THUMBNAILSTORE_H |
|
20 #define THUMBNAILSTORE_H |
|
21 |
|
22 #include <sqldb.h> |
|
23 #include <e32base.h> |
|
24 #include <f32file.h> |
|
25 #include "thumbnailcenrep.h" |
|
26 #include "thumbnailmanagerconstants.h" |
|
27 #include "thumbnaillog.h" |
|
28 #include "tmactivitymanager.h" |
|
29 |
|
30 class RFs; |
|
31 class CFbsBitmap; |
|
32 class CThumbnailServer; |
|
33 |
|
34 /** |
|
35 * Database transaction |
|
36 * |
|
37 * @since S60 v5.0 |
|
38 */ |
|
39 class RThumbnailTransaction |
|
40 { |
|
41 enum TState |
|
42 { |
|
43 EOpen, EOldOpen, EError, EClosed |
|
44 }; |
|
45 public: |
|
46 RThumbnailTransaction( RSqlDatabase& aDatabase ); |
|
47 |
|
48 void BeginL(); |
|
49 void Close(); |
|
50 void CommitL(); |
|
51 TInt Rollback(); |
|
52 |
|
53 private: |
|
54 RSqlDatabase& iDatabase; |
|
55 TState iState; |
|
56 }; |
|
57 |
|
58 |
|
59 /** |
|
60 * MThumbnailStoreDiskSpaceNotifierObserver |
|
61 * Observer interface for a disk space notifier. |
|
62 */ |
|
63 class MThumbnailStoreDiskSpaceNotifierObserver |
|
64 { |
|
65 public : |
|
66 /** |
|
67 * Called to notify the observer that disk space has crossed the specified threshold value. |
|
68 * |
|
69 * @param aDiskFull is disk full (freespace under specified threshold level) |
|
70 */ |
|
71 virtual void HandleDiskSpaceNotificationL(TBool aDiskFull) = 0; |
|
72 |
|
73 /** |
|
74 * Called to if disk space notifier has an error situation. |
|
75 * |
|
76 * @param aError error code |
|
77 */ |
|
78 virtual void HandleDiskSpaceError(TInt aError) = 0; |
|
79 |
|
80 }; |
|
81 |
|
82 /** |
|
83 * CThumbnailStoreDiskSpaceNotifierAO. |
|
84 * A disk space notifier class |
|
85 */ |
|
86 class CThumbnailStoreDiskSpaceNotifierAO : public CActive |
|
87 { |
|
88 public: |
|
89 enum TDiskSpaceNotifierState |
|
90 { |
|
91 ENormal, |
|
92 EIterate |
|
93 }; |
|
94 |
|
95 public : // Constructors and destructors |
|
96 /** |
|
97 * Constructs a disk space notifier implementation. |
|
98 * |
|
99 * @param aThreshold minimum free disk space threshold level in bytes |
|
100 * @param aFilename filename which defines monitored drive's number |
|
101 * @return implementation |
|
102 */ |
|
103 static CThumbnailStoreDiskSpaceNotifierAO* NewL( |
|
104 MThumbnailStoreDiskSpaceNotifierObserver& aObserver, |
|
105 TInt64 aThreshold, const TDesC& aFilename); |
|
106 |
|
107 /** |
|
108 * Constructs a disk space notifier implementation and leaves it |
|
109 * in the cleanup stack. |
|
110 * |
|
111 * @param aThreshold minimum free disk space threshold level in bytes |
|
112 * @return implementation |
|
113 */ |
|
114 static CThumbnailStoreDiskSpaceNotifierAO* NewLC( |
|
115 MThumbnailStoreDiskSpaceNotifierObserver& aObserver, |
|
116 TInt64 aThreshold, const TDesC& aFilename ); |
|
117 |
|
118 /** |
|
119 * Destructor. |
|
120 */ |
|
121 virtual ~CThumbnailStoreDiskSpaceNotifierAO(); |
|
122 |
|
123 TBool DiskFull() const; |
|
124 |
|
125 protected: // Functions from base classes |
|
126 /** |
|
127 * From CActive |
|
128 * Callback function. |
|
129 * Invoked to handle responses from the server. |
|
130 */ |
|
131 void RunL(); |
|
132 |
|
133 /** |
|
134 * From CActive |
|
135 * Handles errors that occur during notifying the observer. |
|
136 */ |
|
137 TInt RunError(TInt aError); |
|
138 |
|
139 /** |
|
140 * From CActive |
|
141 * Cancels any outstanding operation. |
|
142 */ |
|
143 void DoCancel(); |
|
144 |
|
145 private: // Constructors and destructors |
|
146 |
|
147 /** |
|
148 * constructor |
|
149 */ |
|
150 CThumbnailStoreDiskSpaceNotifierAO( |
|
151 MThumbnailStoreDiskSpaceNotifierObserver& aObserver, |
|
152 TInt64 aThreshold, TDriveNumber aDrive ); |
|
153 |
|
154 /** |
|
155 * 2nd phase constructor |
|
156 * @param aThreshold minimum free disk space threshold level in bytes |
|
157 * @param aDrive monitored drive's number |
|
158 */ |
|
159 void ConstructL(); |
|
160 |
|
161 private: // New methods |
|
162 |
|
163 void StartNotifier(); |
|
164 |
|
165 static TDriveNumber GetDriveNumberL( const TDesC& aFilename ); |
|
166 |
|
167 private: // Data |
|
168 |
|
169 MThumbnailStoreDiskSpaceNotifierObserver& iObserver; |
|
170 |
|
171 RFs iFileServerSession; |
|
172 |
|
173 const TInt64 iThreshold; |
|
174 |
|
175 const TDriveNumber iDrive; |
|
176 |
|
177 TDiskSpaceNotifierState iState; |
|
178 |
|
179 TInt iIterationCount; |
|
180 |
|
181 TBool iDiskFull; |
|
182 }; |
|
183 |
|
184 |
|
185 /** |
|
186 * Store for thumbnails. |
|
187 * |
|
188 * @since S60 v5.0 |
|
189 */ |
|
190 class CThumbnailStore: public CBase, |
|
191 public MThumbnailStoreDiskSpaceNotifierObserver, |
|
192 public MTMActivityManagerObserver |
|
193 { |
|
194 // Bitmasked Flags |
|
195 typedef enum |
|
196 { |
|
197 KThumbnailDbFlagCropped = 1, |
|
198 KThumbnailDbFlagBlacklisted = 2, |
|
199 KThumbnailDbFlagDeleted = 4 |
|
200 }TThumbnailDbFlags; |
|
201 |
|
202 public: |
|
203 |
|
204 /** |
|
205 * Two-phased constructor. |
|
206 * |
|
207 * @since S60 v5.0 |
|
208 * @param aFs File server. |
|
209 * @param aDrive Drive the store used for |
|
210 * @param aCenter Pointer to cenrep data handler |
|
211 * @param aReadOnly flag is store write protected |
|
212 * @return New CThumbnailStore instance. |
|
213 */ |
|
214 static CThumbnailStore* NewL( RFs& aFs, TInt aDrive, TDesC& aImei, CThumbnailServer* aServer, const TBool aReadOnly ); |
|
215 |
|
216 /** |
|
217 * Destructor |
|
218 * |
|
219 * @since S60 v5.0 |
|
220 */ |
|
221 virtual ~CThumbnailStore(); |
|
222 |
|
223 /** |
|
224 * Stores thumbnail image. |
|
225 * |
|
226 * @since S60 v5.0 |
|
227 * @param aPath Path of the image from which thumbnail was created. |
|
228 * @param aThumbnail Thumbnail bitmap. |
|
229 * @param aOriginalSize Original size of image. |
|
230 * @param aCropped Enabled if image is cropped. |
|
231 * @param aThumbnailSize Prededined size of requested thumbnail. |
|
232 * @param aThumbFromPath Thumbnail created from associated path. |
|
233 */ |
|
234 void StoreThumbnailL( const TDesC& aPath, CFbsBitmap* aThumbnail, const |
|
235 TSize& aOriginalSize, TBool aCropped, const TThumbnailSize aThumbnailSize, |
|
236 const TInt64 aModified, const TBool aThumbFromPath, TBool aBlackListed); |
|
237 |
|
238 /** |
|
239 * Fetches thumbnail image. |
|
240 * |
|
241 * @since S60 v5.0 |
|
242 * @param aPath Path of the media object whose thumbnail is |
|
243 * to be retrieved. |
|
244 * @param aThumbnail Pointer to get the fetched thumbnail bitmap. |
|
245 * Caller assumes ownership. |
|
246 * @param aData Pointer to get the fetched thumbnail JPEG. |
|
247 * Caller assumes ownership. |
|
248 |
|
249 * @param aAllowUpscaling If enabled, allow fetching thumbnails that |
|
250 * are smaller than requested. |
|
251 * @param aThumbnailSize Prededined size of requested thumbnail. |
|
252 * |
|
253 * @param aThumbnailSize Reference to real size of TN. |
|
254 */ |
|
255 void FetchThumbnailL( const TDesC& aPath, |
|
256 CFbsBitmap* & aThumbnail, |
|
257 TDesC8* & aData, |
|
258 const TThumbnailSize aThumbnailSize, |
|
259 TSize &aThumbnailRealSize |
|
260 ); |
|
261 |
|
262 /** |
|
263 * Delete thumbnails. |
|
264 * |
|
265 * @since S60 v5.0 |
|
266 * @param aPath Path of the media object whose thumbnail is |
|
267 * to be deleted. |
|
268 * @param aForce Force to delete instantly |
|
269 * @param aTransaction Create a transaction |
|
270 */ |
|
271 void DeleteThumbnailsL( const TDesC& aPath, TBool aForce = EFalse, |
|
272 TBool aTransaction = ETrue); |
|
273 |
|
274 /** |
|
275 * Rename thumbnails. |
|
276 * |
|
277 * @since S60 v5.0 |
|
278 * @param aCurrentPath Current path of the Thumbnail |
|
279 * @param aNewPath New path for the Thumbnail |
|
280 */ |
|
281 void RenameThumbnailsL( const TDesC& aCurrentPath, const TDesC& aNewPath ); |
|
282 |
|
283 /** |
|
284 * Persistent sizes. |
|
285 * |
|
286 * @since S60 v5.0 |
|
287 * @return List of thumbnail sizes (including othe parameters) which |
|
288 * are stored for later access. |
|
289 */ |
|
290 void SetPersistentSizes(const RArray < TThumbnailPersistentSize > &aSizes); |
|
291 |
|
292 /** |
|
293 * Get persistent sizes not yet in database |
|
294 * |
|
295 * @since S60 v5.0 |
|
296 * @param aPath Path where missing sizes are associated |
|
297 * @param aMissingSizes List of missing thumbnail sizes |
|
298 * @param aCheckGridSizeOnly check only is grid size missing |
|
299 */ |
|
300 void GetMissingSizesL( const TDesC& aPath, TInt aSourceType, RArray < |
|
301 TThumbnailPersistentSize > & aMissingSizes, TBool aCheckGridSizeOnly ); |
|
302 |
|
303 /** |
|
304 * Check IMEI (owner) of db |
|
305 * |
|
306 * @since S60 v5.0 |
|
307 */ |
|
308 TInt CheckImei(); |
|
309 |
|
310 /** |
|
311 * Check version of db |
|
312 * |
|
313 * @since S60 v5.0 |
|
314 */ |
|
315 TInt CheckVersion(); |
|
316 |
|
317 /** |
|
318 * Check mediaid of store |
|
319 * |
|
320 * @since S60 v5.0 |
|
321 */ |
|
322 TInt CheckMediaIDL(); |
|
323 |
|
324 /** |
|
325 * Add version and IMEI to db |
|
326 * |
|
327 * @since S60 v5.0 |
|
328 */ |
|
329 void AddVersionAndImeiL(); |
|
330 |
|
331 /** |
|
332 * Update IMEI to db |
|
333 * |
|
334 * @since S60 v5.0 |
|
335 */ |
|
336 void UpdateImeiL(); |
|
337 |
|
338 /** |
|
339 * Checks that database rowids match. |
|
340 * |
|
341 * @since S60 v5.0 |
|
342 */ |
|
343 |
|
344 TInt CheckRowIDs(); |
|
345 |
|
346 /** |
|
347 * Check is disk full |
|
348 * |
|
349 * @since S60 v5.0 |
|
350 */ |
|
351 TBool IsDiskFull(); |
|
352 |
|
353 /** |
|
354 * Checks timestamp of blacklisted entry to timestamp of file, from |
|
355 * which thumbnail entry was created, in filesystem |
|
356 * |
|
357 * @param aPath Path from which thumbnail created |
|
358 * @param aModified current timestampt |
|
359 * @contains indication whether file modified |
|
360 */ |
|
361 TBool CheckModifiedByPathL( const TDesC& aPath, const TInt64 aModified, TBool& modifiedChanged); |
|
362 |
|
363 /** |
|
364 * @return TBool is store write protected |
|
365 */ |
|
366 TBool IsReadOnly(); |
|
367 |
|
368 private: |
|
369 /** |
|
370 * C++ default constructor |
|
371 * |
|
372 * @since S60 v5.0 |
|
373 * @param aFs File server. |
|
374 * @param aDrive Drive the store used for |
|
375 * @param aReadOnly set flag if store is write protected |
|
376 * @return New CThumbnailStore instance. |
|
377 */ |
|
378 CThumbnailStore( RFs& aFs, TInt aDrive, TDesC& aImei, CThumbnailServer* aServer, const TBool aReadOnly); |
|
379 |
|
380 /** |
|
381 * Symbian 2nd phase constructor can leave. |
|
382 * |
|
383 * @since S60 v5.0 |
|
384 */ |
|
385 void ConstructL(); |
|
386 |
|
387 /** |
|
388 * Starts constructing database |
|
389 * |
|
390 * @since S60 v5.0 |
|
391 */ |
|
392 void PrepareDbL(); |
|
393 |
|
394 /** |
|
395 * Open database |
|
396 * |
|
397 * @since S60 v5.0 |
|
398 * @param aNewDatabase Delete existing before creating new |
|
399 */ |
|
400 TInt OpenDatabaseL( TBool aNewDatabase = EFalse); |
|
401 |
|
402 /** |
|
403 * Open database |
|
404 * |
|
405 * @since S60 v5.0 |
|
406 */ |
|
407 TInt OpenDatabaseFileL(); |
|
408 |
|
409 /** |
|
410 * Construct database tables |
|
411 * |
|
412 * @since S60 v5.0 |
|
413 */ |
|
414 void CreateTablesL(); |
|
415 void CreateTempTablesL(); |
|
416 |
|
417 /** |
|
418 * Delete and create database |
|
419 * |
|
420 * @since S60 v5.0 |
|
421 * @param aDelete Delete old db |
|
422 */ |
|
423 void RecreateDatabaseL( const TBool aDelete ); |
|
424 |
|
425 /** |
|
426 * Prepare, reset & close statements |
|
427 * |
|
428 * @since S60 v5.0 |
|
429 */ |
|
430 void PrepareStatementsL(); |
|
431 static void ResetStatement( TAny* aStmt ); |
|
432 void CloseStatements(); |
|
433 |
|
434 /** |
|
435 * Stores thumbnail image. |
|
436 * |
|
437 * @since S60 v5.0 |
|
438 * @param aPath Path of the image from which thumbnail was created. |
|
439 * @param aData Data. |
|
440 * @param aSize Size of thumbnail. |
|
441 * @param aOriginalSize Original size of image. |
|
442 * @param aFormat Format of the image. |
|
443 * @param aFlags Flags. |
|
444 * @param aThumbnailSize Associated size of the thumbnail to be deleted |
|
445 * @param aThumbFromPath Thumbnail created from associated path. |
|
446 */ |
|
447 void StoreThumbnailL( const TDesC& aPath, const TDes8& aData, const TSize& |
|
448 aSize, const TSize& aOriginalSize, const TThumbnailFormat& aFormat, TInt aFlags, |
|
449 const TThumbnailSize& aThumbnailSize, const TInt64 aModified, |
|
450 const TBool aThumbFromPath); |
|
451 |
|
452 /** |
|
453 * Finds possible existing duplicate thumbnail. |
|
454 * |
|
455 * @since S60 v5.0 |
|
456 * @param aPath Path of the image from which thumbnail was created. |
|
457 * @param aThumbnailId ID of the thumbnail |
|
458 * @param aThumbnailSize Associated size of the thumbnail to be deleted |
|
459 */ |
|
460 TBool FindDuplicateL( const TDesC& aPath, const TThumbnailSize& aThumbnailSize ); |
|
461 |
|
462 /** |
|
463 * Flush RAM cache containing generated TNs to persistent storage. |
|
464 * |
|
465 * @since S60 TB9.1 |
|
466 * @param aForce which forces logic to flush cache table. |
|
467 */ |
|
468 void FlushCacheTable( TBool aForce = EFalse ); |
|
469 |
|
470 /** |
|
471 * Start db auto flush timer |
|
472 * |
|
473 * @since S60 TB9.1 |
|
474 */ |
|
475 void StartAutoFlush(); |
|
476 |
|
477 /** |
|
478 * Stop db auto flush timer |
|
479 * |
|
480 * @since S60 TB9.1 |
|
481 */ |
|
482 void StopAutoFlush(); |
|
483 |
|
484 void StartMaintenance(); |
|
485 |
|
486 /** |
|
487 * Callback for harvesting complete timer |
|
488 * |
|
489 * @since S60 v5.0 |
|
490 */ |
|
491 static TInt AutoFlushTimerCallBack(TAny* aAny); |
|
492 |
|
493 /** |
|
494 * Callback for maintenance timer |
|
495 * |
|
496 * @since S60 v5.0 |
|
497 */ |
|
498 static TInt MaintenanceTimerCallBack(TAny* aAny); |
|
499 |
|
500 /** |
|
501 * Touches blacklisted items |
|
502 * |
|
503 */ |
|
504 void PrepareBlacklistedItemsForRetryL(); |
|
505 |
|
506 /** |
|
507 * Deletes thumbs added to Deleted table |
|
508 * |
|
509 */ |
|
510 TInt DeleteMarkedL(); |
|
511 |
|
512 /** |
|
513 * Checks if thumbnail source files are still in the file system. |
|
514 * If not, delete corresponding thumbs. |
|
515 * |
|
516 * @return ETrue, if finished. |
|
517 */ |
|
518 TBool FileExistenceCheckL(); |
|
519 |
|
520 /** |
|
521 * Checks if thumbnail database is usable |
|
522 * |
|
523 * @return KErrNone, if no problems |
|
524 */ |
|
525 TInt CheckDbState(); |
|
526 |
|
527 /** |
|
528 * Strips drive letter from URI. |
|
529 * |
|
530 * @since S60 v5.0 |
|
531 * @param aPath Path. |
|
532 */ |
|
533 void StripDriveLetterL( TDes& aPath ); |
|
534 |
|
535 public : // From MThumbnailStoreDiskSpaceNotifierObserver |
|
536 void HandleDiskSpaceNotificationL(TBool aDiskFull); |
|
537 |
|
538 void HandleDiskSpaceError(TInt aError); |
|
539 |
|
540 private: //From MTMActivityManagerObserver |
|
541 void ActivityChanged(const TBool aActive); |
|
542 |
|
543 private: |
|
544 // data |
|
545 |
|
546 /** |
|
547 * Fileserver. |
|
548 */ |
|
549 RFs& iFs; |
|
550 |
|
551 /** |
|
552 * Drive number & char |
|
553 */ |
|
554 TInt iDrive; |
|
555 TChar iDriveChar; |
|
556 |
|
557 /** |
|
558 * Thumbnail database. |
|
559 */ |
|
560 RSqlDatabase iDatabase; |
|
561 |
|
562 /** |
|
563 * Persistent sizes. |
|
564 */ |
|
565 RArray < TThumbnailPersistentSize > iPersistentSizes; |
|
566 |
|
567 /** |
|
568 * Count of cached TNs not yet committed to db |
|
569 */ |
|
570 TInt iBatchItemCount; |
|
571 |
|
572 /** |
|
573 * Phones IMEI code |
|
574 */ |
|
575 TDesC& iImei; |
|
576 |
|
577 /** |
|
578 * ThumbnailServer |
|
579 */ |
|
580 |
|
581 CThumbnailServer* iServer; |
|
582 |
|
583 #ifdef _DEBUG |
|
584 TUint32 iThumbCounter; |
|
585 #endif |
|
586 |
|
587 /** |
|
588 * Periodic timer handling automatic flushing of db cache |
|
589 */ |
|
590 CPeriodic* iAutoFlushTimer; |
|
591 |
|
592 /** |
|
593 * Periodic timer handling db maintenance |
|
594 */ |
|
595 CPeriodic* iMaintenanceTimer; |
|
596 |
|
597 /** |
|
598 * Notifier for situations where free disk space runs out. |
|
599 */ |
|
600 CThumbnailStoreDiskSpaceNotifierAO* iDiskFullNotifier; |
|
601 |
|
602 TBool iDiskFull; |
|
603 |
|
604 CTMActivityManager* iActivityManager; |
|
605 |
|
606 // device idle |
|
607 TBool iIdle; |
|
608 |
|
609 // delete thumbs |
|
610 TBool iDeleteThumbs; |
|
611 |
|
612 // check if thumb source files still exist |
|
613 TBool iCheckFilesExist; |
|
614 TInt64 iLastCheckedRowID; |
|
615 |
|
616 // store is in a state in which db can't be used |
|
617 TBool iUnrecoverable; |
|
618 |
|
619 // prepared statements |
|
620 RSqlStatement iStmt_KThumbnailSelectInfoByPath; |
|
621 RSqlStatement iStmt_KThumbnailSelectTempInfoByPath; |
|
622 RSqlStatement iStmt_KThumbnailInsertTempThumbnailInfo; |
|
623 RSqlStatement iStmt_KThumbnailInsertTempThumbnailInfoData; |
|
624 RSqlStatement iStmt_KThumbnailSelectModifiedByPath; |
|
625 RSqlStatement iStmt_KThumbnailSelectTempModifiedByPath; |
|
626 RSqlStatement iStmt_KThumbnailFindDuplicate; |
|
627 RSqlStatement iStmt_KThumbnailTempFindDuplicate; |
|
628 RSqlStatement iStmt_KThumbnailSqlFindDeleted; |
|
629 RSqlStatement iStmt_KThumbnailSelectSizeByPath; |
|
630 RSqlStatement iStmt_KThumbnailSelectTempSizeByPath; |
|
631 RSqlStatement iStmt_KThumbnailSqlSelectRowIDInfoByPath; |
|
632 RSqlStatement iStmt_KThumbnailSqlDeleteInfoByPath; |
|
633 RSqlStatement iStmt_KThumbnailSqlDeleteInfoDataByPath; |
|
634 RSqlStatement iStmt_KTempThumbnailSqlSelectRowIDInfoByPath; |
|
635 RSqlStatement iStmt_KTempThumbnailSqlDeleteInfoByPath; |
|
636 RSqlStatement iStmt_KTempThumbnailSqlDeleteInfoDataByPath; |
|
637 RSqlStatement iStmt_KThumbnailSqlInsertDeleted; |
|
638 RSqlStatement iStmt_KThumbnailSqlSelectMarked; |
|
639 RSqlStatement iStmt_KThumbnailSqlDeleteInfoByRowID; |
|
640 RSqlStatement iStmt_KThumbnailSqlDeleteInfoDataByRowID; |
|
641 RSqlStatement iStmt_KThumbnailSelectAllPaths; |
|
642 RSqlStatement iStmt_KThumbnailRename; |
|
643 RSqlStatement iStmt_KThumbnailTempRename; |
|
644 |
|
645 /** |
|
646 * Dynamic batch size |
|
647 */ |
|
648 TInt iBatchFlushItemCount; |
|
649 |
|
650 /** |
|
651 * Measure time spend in flush |
|
652 */ |
|
653 TTime iStartFlush, iStopFlush; |
|
654 /** |
|
655 * How long previous flush took ms |
|
656 */ |
|
657 TInt iPreviousFlushDelay; |
|
658 |
|
659 /** |
|
660 * is store write protected |
|
661 */ |
|
662 TBool iReadOnly; |
|
663 |
|
664 }; |
|
665 // End of File |
|
666 |
|
667 |
|
668 #endif // THUMBNAILSTORE_H |
|