|
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: |
|
15 * |
|
16 */ |
|
17 #include <pathinfo.h> |
|
18 #include <pathconfiguration.hrh> |
|
19 #include <coemain.h> // For CCoeEnv |
|
20 #include <QDate> |
|
21 |
|
22 #include "cxefilenamegeneratorsymbian.h" |
|
23 #include "cxeengine.h" |
|
24 #include "cxenamespace.h" |
|
25 #include "cxutils.h" |
|
26 #include "cxesysutil.h" |
|
27 #include "cxesettings.h" |
|
28 #include "cxeerror.h" |
|
29 #include "cxeerrormappingsymbian.h" |
|
30 |
|
31 |
|
32 using namespace Cxe; |
|
33 |
|
34 // =========================================================================== |
|
35 // Local constants |
|
36 |
|
37 static const int KMultipleFolderNumberChars = 2; |
|
38 static const int KMaxMonthFolders = 260; |
|
39 static const int KBase10 = 10; |
|
40 static const int KMaxFilesPerFolder = 100; |
|
41 |
|
42 const char* CAMERA_FOLDER = "Camera"; |
|
43 const char* FOLDER_SEPARATOR = "\\"; |
|
44 const char* WILDCARD_CHARACTER = "?"; |
|
45 |
|
46 const char CHAR_OFFSET = 'A'; |
|
47 const char DIGIT_OFFSET = '0'; |
|
48 const char MAX_CHAR = 'Z'; |
|
49 |
|
50 const TInt64 KMinRequiredSpaceImage = 2000000; |
|
51 const TInt64 KMinRequiredSpaceVideo = 4000000; |
|
52 |
|
53 |
|
54 |
|
55 // =========================================================================== |
|
56 // Local functions |
|
57 |
|
58 /** |
|
59 * Convert QString to TPtrC16. |
|
60 */ |
|
61 inline TPtrC16 convertToTPtrC16(const QString& string) |
|
62 { |
|
63 return TPtrC16(reinterpret_cast<const TUint16*>(string.utf16())); |
|
64 } |
|
65 |
|
66 |
|
67 // =========================================================================== |
|
68 // Class functions |
|
69 |
|
70 /** |
|
71 * Constructor |
|
72 */ |
|
73 CxeFilenameGeneratorSymbian::CxeFilenameGeneratorSymbian(CxeSettings &settings, CameraMode mode) |
|
74 : mFs(CCoeEnv::Static()->FsSession()), |
|
75 mSettings(settings), |
|
76 mCurrentMode(mode) |
|
77 { |
|
78 CX_DEBUG_ENTER_FUNCTION(); |
|
79 |
|
80 // Set default values (used in case of error retrieving values) |
|
81 mCurrentMonth = ""; |
|
82 mMonthCounterImage = -1; |
|
83 mMonthCounterVideo = -1; |
|
84 mImageCounter = 0; |
|
85 mVideoCounter = 0; |
|
86 |
|
87 // Retrieve last used counter values from settings |
|
88 mSettings.get(CxeSettingIds::FNAME_MONTH_FOLDER, mCurrentMonth); |
|
89 mSettings.get(CxeSettingIds::FNAME_IMAGE_COUNTER, mImageCounter); |
|
90 mSettings.get(CxeSettingIds::FNAME_VIDEO_COUNTER, mVideoCounter); |
|
91 |
|
92 CX_DEBUG_EXIT_FUNCTION(); |
|
93 } |
|
94 |
|
95 /** |
|
96 * Destructor |
|
97 */ |
|
98 CxeFilenameGeneratorSymbian::~CxeFilenameGeneratorSymbian() |
|
99 { |
|
100 CX_DEBUG_ENTER_FUNCTION(); |
|
101 |
|
102 CX_DEBUG_EXIT_FUNCTION(); |
|
103 } |
|
104 |
|
105 /** |
|
106 * This must be called for every burst capture. |
|
107 */ |
|
108 void CxeFilenameGeneratorSymbian::startNewImageFilenameSequence() |
|
109 { |
|
110 CX_DEBUG_ENTER_FUNCTION(); |
|
111 |
|
112 /* NOTES |
|
113 When the client calls this function, we should start a new "sequence" of filenames... |
|
114 What I mean here is that for burst capture, we have filename sequences like... |
|
115 Filename1 |
|
116 Filename1(002) |
|
117 Filename1(003) |
|
118 and so on... |
|
119 |
|
120 So this function says "Ok, I'm starting a new capture sequence here... so reset your variables" |
|
121 This should be done below... |
|
122 Development efforts need to be aware of Edrive vs. Cdrive, and also multiple drive support. |
|
123 */ |
|
124 |
|
125 CX_DEBUG_EXIT_FUNCTION(); |
|
126 } |
|
127 |
|
128 /** |
|
129 * Generates the next file name in the sequence. |
|
130 * @param filename: A QString reference to hold the filename |
|
131 * @return error id, Id::None if no error |
|
132 */ |
|
133 CxeError::Id CxeFilenameGeneratorSymbian::nextImageFilenameInSequence(QString &qfName, const QString &fileExt) |
|
134 { |
|
135 CX_DEBUG_IN_FUNCTION(); |
|
136 |
|
137 /** @todo: When the client calls this function, the next filename in the |
|
138 * sequence is retrieved. The entire path should be included... e.g |
|
139 * C//PHOTOS//SOMETHING//HELLO//Filename001.jpg |
|
140 */ |
|
141 return generateFilename(qfName, fileExt); |
|
142 } |
|
143 |
|
144 /** |
|
145 * Generates image/video file name depending on the current active mode. |
|
146 * @param filename: A QString reference to hold the filename |
|
147 * @return error id, CxeError::None if no error. |
|
148 */ |
|
149 CxeError::Id CxeFilenameGeneratorSymbian::generateFilename(QString &qfName, const QString &fileExt) |
|
150 { |
|
151 CX_DEBUG_ENTER_FUNCTION(); |
|
152 |
|
153 // Make sure that the path for images/videos exists |
|
154 QString path; |
|
155 int err = selectFolder(path); |
|
156 |
|
157 // Continue generating filename, if no errors encountered yet |
|
158 if (!err) { |
|
159 // Generate and append the file name to construct the full path |
|
160 QString fileName; |
|
161 err = generateUniqueFileName(path, fileName, fileExt); |
|
162 if (!err) { |
|
163 qfName = path + fileName; |
|
164 } |
|
165 } |
|
166 |
|
167 CX_DEBUG_EXIT_FUNCTION(); |
|
168 return CxeErrorHandlingSymbian::map(err); |
|
169 } |
|
170 |
|
171 /** |
|
172 * Generates a unique file name in the given path. |
|
173 * @param filePath Path for the file (reference) |
|
174 * @param fileName Name of the file (reference) |
|
175 * @return Symbian error code (used internally) |
|
176 */ |
|
177 int CxeFilenameGeneratorSymbian::generateUniqueFileName(QString &filePath, QString &fileName, const QString &ext) |
|
178 { |
|
179 CX_DEBUG_ENTER_FUNCTION(); |
|
180 |
|
181 // At this point the path must exist. |
|
182 // Remote possibility / security threat that it doesn't exist or is not a folder. |
|
183 TEntry entry; |
|
184 int ferr = mFs.Entry(convertToTPtrC16(filePath), entry); |
|
185 if (ferr != KErrNone || !entry.IsDir()) { |
|
186 return ferr; |
|
187 } |
|
188 |
|
189 // Initialize counters and file extension |
|
190 int *fileCounter = &mImageCounter; |
|
191 |
|
192 if (mCurrentMode==VideoMode) { |
|
193 fileCounter = &mVideoCounter; |
|
194 } |
|
195 |
|
196 QString fnFormat("%1%2%3"); |
|
197 QString number; |
|
198 |
|
199 // get the file name suffix |
|
200 QString baseFileName; |
|
201 mSettings.get(CxeSettingIds::FNAME_FOLDER_SUFFIX, baseFileName); |
|
202 |
|
203 while (true) { |
|
204 // Generate new name |
|
205 number = number.sprintf("%04d", *fileCounter); |
|
206 fileName = fnFormat.arg(number, baseFileName, ext); |
|
207 |
|
208 CX_DEBUG(("Checking filename [%s]", fileName.toAscii().constData())); |
|
209 |
|
210 // Check if it exists |
|
211 ferr = checkExistence(filePath + fileName); |
|
212 if (ferr == KErrNone) { |
|
213 // Filename has already been used in this location, try the next number |
|
214 CX_DEBUG(("File exists already")); |
|
215 (*fileCounter)++; |
|
216 } else if (ferr == KErrNotFound) { |
|
217 // No file with this name, use it. |
|
218 CX_DEBUG(("Filename free, using it")); |
|
219 ferr = KErrNone; |
|
220 break; |
|
221 } else { |
|
222 // Filename could not be reserved. Log actual error and report as general error. |
|
223 CX_DEBUG(("[WARNING] Error %d generating filename!", ferr)); |
|
224 ferr = KErrGeneral; |
|
225 break; |
|
226 } |
|
227 } |
|
228 |
|
229 // Increment counter if image mode. Video counter is incremented when |
|
230 // video has been actually recorded |
|
231 if (mCurrentMode == ImageMode) { |
|
232 raiseCounterValue(); |
|
233 } |
|
234 |
|
235 CX_DEBUG_EXIT_FUNCTION(); |
|
236 return ferr; |
|
237 } |
|
238 |
|
239 /** |
|
240 * Computes the suffix to be used in destination folder name. |
|
241 */ |
|
242 void CxeFilenameGeneratorSymbian::computeFolderSuffix(int folderNumber, QString &suffix) |
|
243 { |
|
244 CX_DEBUG_ENTER_FUNCTION(); |
|
245 |
|
246 // Clear any old content. |
|
247 suffix = ""; |
|
248 |
|
249 // Example: |
|
250 // if folderNumber is 15 |
|
251 // 15/10 = 1 (int) |
|
252 // A + 1 = B |
|
253 suffix += (CHAR_OFFSET + folderNumber/KBase10); |
|
254 // 15%10 = 5 |
|
255 // 0 + 5 = 5 |
|
256 // => suffix = B5 |
|
257 suffix += (DIGIT_OFFSET + folderNumber%KBase10); |
|
258 CX_DEBUG_EXIT_FUNCTION(); |
|
259 } |
|
260 |
|
261 /** |
|
262 * Compute the month counter value (0 to 259 => A0 to Z9). |
|
263 * @param |
|
264 * @return Symbian error code (internal to class) |
|
265 */ |
|
266 int CxeFilenameGeneratorSymbian::computeMonthCounter(QString &path, QString& monthFolder, int &monthCounter) |
|
267 { |
|
268 CX_DEBUG_ENTER_FUNCTION(); |
|
269 bool done = false; |
|
270 |
|
271 // Query the month folder: path\YYYYMM?? |
|
272 QString queryPath = path + monthFolder; |
|
273 for (int charCount = 0; charCount < KMultipleFolderNumberChars; charCount++) { |
|
274 queryPath += WILDCARD_CHARACTER; |
|
275 } |
|
276 CX_DEBUG(("Listing folders with wildcards: [%s]", queryPath.toAscii().constData())); |
|
277 |
|
278 // Get a list of folders for this month, sorted in descending alphabetical order. |
|
279 // The first entry should be the latest used folder. |
|
280 CDir* dirList; |
|
281 int err = mFs.GetDir(convertToTPtrC16(queryPath), |
|
282 KEntryAttMatchExclusive|KEntryAttDir, |
|
283 ESortByName|EDescending, |
|
284 dirList); |
|
285 |
|
286 // On errors (or empty list of folders), let's default to zero. |
|
287 // Errors here should be recoverable when we start to |
|
288 // count files within current directory. |
|
289 monthCounter = 0; |
|
290 |
|
291 // If directory listing worked fine, then figure out the last month folder number |
|
292 if (err == KErrNone) { |
|
293 int monthFolderCount = dirList->Count(); |
|
294 CX_DEBUG(("Matching folder count: %d", monthFolderCount)); |
|
295 int index = 0; |
|
296 // Look through the list of folders in the month for the highest numbered folder |
|
297 // with the format YYYYMMAX Where YYYY is the year MM is the month A is an alphabetical |
|
298 // character in the range a-z or A-Z and X is a digit 0-9 |
|
299 while ( index < monthFolderCount && !done ) { |
|
300 // The list is sorted in descending order. Get the last 2 characters from |
|
301 // the first directory in the list these indicate the highest folder number |
|
302 TPtrC name = ( *dirList )[index].iName; |
|
303 int nameLength = name.Length(); |
|
304 |
|
305 // Check the first character is in the range a-z or A-Z |
|
306 // and the second character is in the range 0-9 |
|
307 TChar firstChar = name[nameLength - KMultipleFolderNumberChars]; |
|
308 firstChar.UpperCase(); |
|
309 TChar secondChar = name[nameLength - 1]; |
|
310 int secondCharVal = secondChar.GetNumericValue(); |
|
311 |
|
312 // If 1st character is NOT in the range(A-Z) then disregard this folder |
|
313 if (firstChar < CHAR_OFFSET || firstChar > MAX_CHAR) { |
|
314 done = false; |
|
315 } |
|
316 // If 2nd character is NOT in the range(0-9) then disregard this folder |
|
317 else if (secondCharVal < 0 || secondCharVal > KBase10-1) { |
|
318 done = false; |
|
319 } |
|
320 else { |
|
321 done = true; |
|
322 } |
|
323 |
|
324 // If no problems were encountered, then calculate the folder number |
|
325 if (done) { |
|
326 // 10's part of folder number is represented by characters A-Z |
|
327 // convert the character into a decimal value (*10) and add on the units. |
|
328 monthCounter = ((int)firstChar-(int)CHAR_OFFSET)*KBase10 + secondCharVal; |
|
329 CX_DEBUG(("Calculated month counter value: %d", monthCounter)); |
|
330 // Make sure that month counter doesn't exceed Z9 |
|
331 if (monthCounter >= KMaxMonthFolders) { |
|
332 monthCounter = KMaxMonthFolders - 1; |
|
333 } |
|
334 } |
|
335 index++; |
|
336 } |
|
337 } else { |
|
338 CX_DEBUG(("[WARNING] Error %d listing month folders!", err)); |
|
339 } |
|
340 |
|
341 delete dirList; |
|
342 CX_DEBUG_EXIT_FUNCTION(); |
|
343 return err; |
|
344 } |
|
345 |
|
346 /** |
|
347 * Checks that the month folder exists: creates the folder if required. |
|
348 * Returns error code if the folder can't be created. |
|
349 */ |
|
350 int CxeFilenameGeneratorSymbian::selectFolder(QString &suggestedPath) |
|
351 { |
|
352 CX_DEBUG_ENTER_FUNCTION(); |
|
353 |
|
354 // Compose the path string and select counter based on mode. |
|
355 QString basePath = "%1%2\\"; |
|
356 int *monthCounter = &mMonthCounterImage; |
|
357 |
|
358 if (ImageMode == mCurrentMode) { |
|
359 basePath = basePath.arg(mImagesPath, mCurrentMonth); |
|
360 } |
|
361 else { // VideoMode |
|
362 basePath = basePath.arg(mVideosPath, mCurrentMonth); |
|
363 monthCounter = &mMonthCounterVideo; |
|
364 } |
|
365 CX_DEBUG(("Base path [%s]", basePath.toAscii().constData())); |
|
366 |
|
367 QString suffix; |
|
368 QString newPath; |
|
369 int status(KErrNone); |
|
370 bool created(false); |
|
371 |
|
372 while (true) { |
|
373 // Construct the complete path |
|
374 computeFolderSuffix(*monthCounter, suffix); |
|
375 newPath = basePath + mCurrentMonth + suffix + FOLDER_SEPARATOR; |
|
376 |
|
377 // Check if the folder exists, and create if not. |
|
378 CX_DEBUG(("Checking new path [%s] ..", newPath.toAscii().constData())); |
|
379 status = ensureExists(newPath, created); |
|
380 |
|
381 // Check if the folder can be used. |
|
382 if (status == KErrNone) { |
|
383 // If the folder was newly created, it's empty and can be used. |
|
384 // If the folder is last available month folder, |
|
385 // we need to use it even if it has "too many" files. |
|
386 if (created || *monthCounter >= (KMaxMonthFolders-1)) { |
|
387 CX_DEBUG(("Newly created folder, or the last month folder available, using it")); |
|
388 suggestedPath = newPath; |
|
389 break; |
|
390 } else { |
|
391 // For other folders, if the folder already exists then make sure |
|
392 // that it doesn't contain maximum number of files already. |
|
393 CX_DEBUG(("Folder already existed, check the amount of files..")); |
|
394 CDir* fileList; |
|
395 status = mFs.GetDir(convertToTPtrC16(newPath), |
|
396 KEntryAttMaskSupported, |
|
397 ESortNone, |
|
398 fileList); |
|
399 CX_DEBUG(("Folder contains %d files", fileList->Count())); |
|
400 |
|
401 bool spaceRemaining(fileList->Count() < KMaxFilesPerFolder); |
|
402 |
|
403 delete fileList; |
|
404 fileList = NULL; |
|
405 |
|
406 if (status == KErrNone && spaceRemaining) { |
|
407 // Not too many files on the folder, use it. |
|
408 CX_DEBUG(("File count acceptable, using this folder")); |
|
409 suggestedPath = newPath; |
|
410 break; |
|
411 } else { |
|
412 // Need to check the next folder, this one is full, |
|
413 // or we had error listing it's contents. |
|
414 CX_DEBUG(("Folder full, continue search")); |
|
415 (*monthCounter)++; |
|
416 } |
|
417 } |
|
418 } else { |
|
419 // Unknown error encountered. |
|
420 // LOG the error and use the basePath! |
|
421 // Base path's existence has been checked when init was called. |
|
422 CX_DEBUG(("[WARNING] - error %d encountered. Using base path as fallback.", status)); |
|
423 suggestedPath = basePath; |
|
424 break; |
|
425 } |
|
426 } |
|
427 |
|
428 CX_DEBUG_EXIT_FUNCTION(); |
|
429 |
|
430 // We fallback to basePath in case of unknown errors, |
|
431 // so no error will be reported here. |
|
432 return KErrNone; |
|
433 } |
|
434 |
|
435 |
|
436 |
|
437 /** |
|
438 * Initializes the month folders. |
|
439 * @return Symbian error code (internal to class) |
|
440 */ |
|
441 int CxeFilenameGeneratorSymbian::initMonthFolders() |
|
442 { |
|
443 CX_DEBUG_ENTER_FUNCTION(); |
|
444 |
|
445 // Month folder: YYYYMM, with suffix: YYYYMMXX |
|
446 QString monthFolder = QDate::currentDate().toString("yyyyMM"); |
|
447 |
|
448 // If the month folder name is different from the last used month folder name |
|
449 // this indicates that a new month has been started. |
|
450 if ( monthFolder.compare(mCurrentMonth) != 0 ) { |
|
451 resetCounters(monthFolder); |
|
452 } |
|
453 |
|
454 // Check/create that the month folder exists |
|
455 int *monthCounter = &mMonthCounterImage; |
|
456 QString path = "%1%2\\"; |
|
457 if (ImageMode==mCurrentMode) { |
|
458 path = path.arg(mImagesPath, monthFolder); |
|
459 } |
|
460 else { |
|
461 path = path.arg(mVideosPath, monthFolder); |
|
462 monthCounter = &mMonthCounterVideo; |
|
463 } |
|
464 |
|
465 CX_DEBUG(("Check if exists, create if not [%s]", path.toAscii().constData())); |
|
466 bool created(false); |
|
467 int status(ensureExists(path, created)); |
|
468 |
|
469 if (status == KErrNone) { |
|
470 if (created) { |
|
471 // New folder, new month -> counter starts from zero. |
|
472 *monthCounter = 0; |
|
473 } else { |
|
474 // If the month counter is un-initialised it needs to be set up. |
|
475 if (*monthCounter < 0) { |
|
476 status = computeMonthCounter(path, monthFolder, *monthCounter); |
|
477 if (status != KErrNone) { |
|
478 CX_DEBUG(("[WARNING] - Error setting month counter: %d", status)); |
|
479 *monthCounter = 0; |
|
480 } |
|
481 } |
|
482 } |
|
483 } else { |
|
484 //! @todo: Review error handling |
|
485 // Report error - can't continue without 'camera' and camera\YYYYMM folders |
|
486 CX_DEBUG(("[FATAL] - Could not create month folder, error %d", status)); |
|
487 } |
|
488 |
|
489 CX_DEBUG_EXIT_FUNCTION(); |
|
490 return status; |
|
491 } |
|
492 |
|
493 /** |
|
494 * Checks if the passed amount of disk space is available on the passed drive. |
|
495 * @return true if space available, false otherwise |
|
496 */ |
|
497 bool CxeFilenameGeneratorSymbian::spaceAvailable(int &driveIndex, TInt64 minSpaceInBytes) |
|
498 { |
|
499 CX_DEBUG_ENTER_FUNCTION(); |
|
500 |
|
501 TVolumeInfo vInfo; |
|
502 |
|
503 // Get the drive/volume details |
|
504 int status(KErrNone); |
|
505 driveIndex = CxeSysUtil::getCameraDrive(mFs); |
|
506 if (driveIndex >= 0) { |
|
507 status = mFs.Volume(vInfo, driveIndex); |
|
508 } |
|
509 |
|
510 CX_DEBUG_EXIT_FUNCTION(); |
|
511 return (status == KErrNone) ? vInfo.iFree >= minSpaceInBytes : false; |
|
512 |
|
513 } |
|
514 |
|
515 /** |
|
516 * Selects the drive to use based on preference and availability. |
|
517 * @param index of the drive to be used (reference) |
|
518 * @return Symbian error code (internal to class) |
|
519 */ |
|
520 int CxeFilenameGeneratorSymbian::selectDrive(int &drive) |
|
521 { |
|
522 CX_DEBUG_ENTER_FUNCTION(); |
|
523 int err = KErrNone; |
|
524 TInt64 minDiskSpace = KMinRequiredSpaceImage; |
|
525 |
|
526 if (Cxe::VideoMode == mCurrentMode) { |
|
527 minDiskSpace = KMinRequiredSpaceVideo; |
|
528 } |
|
529 |
|
530 // Check the available space. |
|
531 // Drive index is set here also. |
|
532 if ( !spaceAvailable(drive, minDiskSpace)) { |
|
533 // All drives are full or inaccessible |
|
534 err = KErrDiskFull; |
|
535 } |
|
536 |
|
537 CX_DEBUG_EXIT_FUNCTION(); |
|
538 return err; |
|
539 } |
|
540 |
|
541 /** |
|
542 * Initializes the value of base path for the given mode and drive. |
|
543 */ |
|
544 void CxeFilenameGeneratorSymbian::initBasePath(QString &path, int drive) |
|
545 { |
|
546 CX_DEBUG_ENTER_FUNCTION(); |
|
547 |
|
548 // Get the root path for the given drive. |
|
549 TFileName tPath; |
|
550 PathInfo::GetRootPath(tPath, drive); |
|
551 |
|
552 if (VideoMode == mCurrentMode) { |
|
553 tPath.Append( PathInfo::VideosPath() ); |
|
554 } |
|
555 else { |
|
556 tPath.Append( PathInfo::ImagesPath() ); |
|
557 } |
|
558 |
|
559 //! @todo: Fetch localized Camera folder name, if/when applicable. |
|
560 path = QString::fromUtf16(tPath.Ptr(), tPath.Length()); |
|
561 path = path + CAMERA_FOLDER + FOLDER_SEPARATOR; |
|
562 |
|
563 CX_DEBUG(("Path: %s", path.toAscii().constData())); |
|
564 CX_DEBUG_EXIT_FUNCTION(); |
|
565 } |
|
566 |
|
567 /** |
|
568 * Resets the image and video counters used for file name generation. |
|
569 */ |
|
570 void CxeFilenameGeneratorSymbian::resetCounters(QString &monthFolder) |
|
571 { |
|
572 CX_DEBUG_ENTER_FUNCTION(); |
|
573 |
|
574 mCurrentMonth = monthFolder; |
|
575 mMonthCounterImage = 0; |
|
576 mMonthCounterVideo = 0; |
|
577 |
|
578 // Save the setting values |
|
579 // Errors (if any) encountered here are not handled, since these indicate |
|
580 // that settings are'nt saved. If settings are not fetched next time, |
|
581 // then default settings are used. |
|
582 mSettings.set(CxeSettingIds::FNAME_MONTH_FOLDER, mCurrentMonth); |
|
583 |
|
584 CX_DEBUG_EXIT_FUNCTION(); |
|
585 } |
|
586 |
|
587 /** |
|
588 * Initializes the base folder names and counters |
|
589 * NB: Video mode init requires file name. So this should be called |
|
590 * before init is called for image/video capture controls. |
|
591 * Initializes only for appropriate mode (image/video). |
|
592 */ |
|
593 CxeError::Id CxeFilenameGeneratorSymbian::init(Cxe::CameraMode mode) |
|
594 { |
|
595 CX_DEBUG_ENTER_FUNCTION(); |
|
596 |
|
597 mCurrentMode = mode; |
|
598 int err = KErrNone; |
|
599 bool initialized = (mode==ImageMode && !mImagesPath.isEmpty()) || |
|
600 (mode==VideoMode && !mVideosPath.isEmpty()); |
|
601 |
|
602 if (!initialized) { |
|
603 // Select a drive based on available disk space |
|
604 int drive; |
|
605 err = selectDrive(drive); |
|
606 if (!err) { |
|
607 if (mode == ImageMode) { |
|
608 initBasePath(mImagesPath, drive); |
|
609 } |
|
610 else { |
|
611 initBasePath(mVideosPath, drive); |
|
612 } |
|
613 |
|
614 // Initialize the month folders and counters so that |
|
615 // file names can be generated quickly when requested. |
|
616 err = initMonthFolders(); |
|
617 } |
|
618 } |
|
619 |
|
620 CX_DEBUG_EXIT_FUNCTION(); |
|
621 return CxeErrorHandlingSymbian::map(err); |
|
622 } |
|
623 |
|
624 /** |
|
625 * Raises file name counter value by one |
|
626 */ |
|
627 void CxeFilenameGeneratorSymbian::raiseCounterValue() |
|
628 { |
|
629 if (VideoMode==mCurrentMode) { |
|
630 mSettings.set(CxeSettingIds::FNAME_VIDEO_COUNTER, ++mVideoCounter); |
|
631 } |
|
632 else { |
|
633 mSettings.set(CxeSettingIds::FNAME_IMAGE_COUNTER, ++mImageCounter); |
|
634 } |
|
635 } |
|
636 |
|
637 /** |
|
638 * Check if the given file or directory exists. |
|
639 * @return KErrNone, if given file/directory exists, KErrNotFound if not. |
|
640 * Other Symbian error code on "real" errors. |
|
641 */ |
|
642 int CxeFilenameGeneratorSymbian::checkExistence(const QString& path) |
|
643 { |
|
644 CX_DEBUG_ENTER_FUNCTION(); |
|
645 |
|
646 unsigned int placeHolder(0); |
|
647 int status(mFs.Att(convertToTPtrC16(path), placeHolder)); |
|
648 |
|
649 CX_DEBUG_EXIT_FUNCTION(); |
|
650 return status; |
|
651 } |
|
652 |
|
653 |
|
654 /** |
|
655 * Check if directory exists and create if not. |
|
656 * @param created When returned, holds if the folder needed to be created or not. |
|
657 * @return KErrNone, if folder existed or was created successfully. |
|
658 * Other Symbian error code if there were errors. |
|
659 */ |
|
660 int CxeFilenameGeneratorSymbian::ensureExists(const QString& path, bool& created) |
|
661 { |
|
662 CX_DEBUG_ENTER_FUNCTION(); |
|
663 |
|
664 // Default to "not created" if errors are encountered. |
|
665 created = false; |
|
666 |
|
667 unsigned int placeHolder(0); |
|
668 TPtrC16 pathDesc(convertToTPtrC16(path)); |
|
669 CX_DEBUG_SYMBIAN((_L("Checking [%S]"), &pathDesc)); |
|
670 |
|
671 // Check if it already exists |
|
672 CX_DEBUG(("CxeFilenameGeneratorSymbian::ensureExists - check existence..")); |
|
673 int status = mFs.Att(pathDesc, placeHolder); |
|
674 CX_DEBUG(("CxeFilenameGeneratorSymbian::ensureExists - ..check existence")); |
|
675 |
|
676 if( status == KErrPathNotFound || status == KErrNotFound ) { |
|
677 // Create path if doesn't exist yet. |
|
678 CX_DEBUG(("CxeFilenameGeneratorSymbian::ensureExists - create path..")); |
|
679 status = mFs.MkDirAll(pathDesc); |
|
680 CX_DEBUG(("CxeFilenameGeneratorSymbian::ensureExists - ..create path")); |
|
681 // Set "created" flag only if successfull |
|
682 created = (status == KErrNone); |
|
683 } |
|
684 |
|
685 CX_DEBUG_EXIT_FUNCTION(); |
|
686 return status; |
|
687 } |
|
688 |
|
689 |
|
690 // end of file |