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