camerauis/cameraapp/generic/src/camfolderutility.cpp
changeset 19 d9aefe59d544
parent 3 8b2d6d0384b0
child 21 fa6d9f75d6a6
child 28 3075d9b614e6
equal deleted inserted replaced
3:8b2d6d0384b0 19:d9aefe59d544
     1 /*
       
     2 * Copyright (c) 2007-2008 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 *  Copyright © 2007-2008 Nokia.  All rights reserved.
       
    17 *  This material, including documentation and any related computer
       
    18 *  programs, is protected by copyright controlled by Nokia.  All
       
    19 *  rights are reserved.  Copying, including reproducing, storing,
       
    20 *  adapting or translating, any or all of this material requires the
       
    21 *  prior written consent of Nokia.  This material also contains
       
    22 *  confidential information which may not be disclosed to others
       
    23 *  without the prior written consent of Nokia.
       
    24 
       
    25 *
       
    26 *
       
    27 */
       
    28 
       
    29 
       
    30 // ===========================================================================
       
    31 // Included headers
       
    32 
       
    33 
       
    34 #include <bldvariant.hrh> // for feature definitions
       
    35 
       
    36 #include <f32file.h>
       
    37 #include <centralrepository.h>
       
    38 #include <pathinfo.h>
       
    39 #include <StringLoader.h>
       
    40 
       
    41 #include <cameraapp.rsg>
       
    42 #include <vgacamsettings.rsg>
       
    43 
       
    44 #include "CamPanic.h"
       
    45 #include "CamUtility.h"       // PRINT macros
       
    46 #include "CameraappPrivateCRKeys.h"  
       
    47 #include "camfolderutility.h"
       
    48 
       
    49 
       
    50 // ===========================================================================
       
    51 // Local constants
       
    52 
       
    53 static const TInt KMultipleFolderNumberChars = 2;
       
    54 static const TInt KMaxMonthFolders           = 260;
       
    55 static const TInt KBase10                    = 10;
       
    56 static const TInt KCamMonthFolderNameLength = 8;
       
    57 
       
    58 
       
    59 _LIT( KCamMonthFolderFormat, "%F%Y%M" );  
       
    60 _LIT( KBackslash,            "\\"     );
       
    61 _LIT( KCharacterOffset,      "A"      );
       
    62 _LIT( KDigitOffset,          "0"      );
       
    63 _LIT( KMaxCharacter,         "Z"      );
       
    64 _LIT( KWildCardCharacter,    "?"      );
       
    65 
       
    66 
       
    67 
       
    68 // ===========================================================================
       
    69 // CCamFolderUtility implementation
       
    70 
       
    71 // ---------------------------------------------------------------------------
       
    72 // GetBasePathL
       
    73 // Generates the path where new images/videos are to be saved to.
       
    74 // ---------------------------------------------------------------------------
       
    75 //
       
    76 void
       
    77 CCamFolderUtility::GetBasePathL( TInt*                 aMonthCounters,
       
    78                                  TInt                  aStorage, // TCamMediaStorage
       
    79                                  TDes&                 aPath, 
       
    80                                  TCamCameraMode aCaptureMode, 
       
    81                                  TBool                 aCreateAll,
       
    82                                  TInt                  aRequiredFileCount,
       
    83                                  TTime                 aTime )
       
    84   {
       
    85   PRINT( _L("Camera => CCamFolderUtility::GetBasePathL"))
       
    86 
       
    87   TInt folderTypeIndex = 0;
       
    88   
       
    89     if ( ( aStorage == ECamMediaStoragePhone ) ) // Saving to phone memory
       
    90        { 
       
    91        // phone folders are in the odd indexes
       
    92        folderTypeIndex ++;
       
    93        PRINT( _L("Camera GetBasePathL saving to phone memory"))
       
    94        aPath.Copy( PathInfo::PhoneMemoryRootPath() );
       
    95        }
       
    96        // with multiple drives, mass storage is the default, like phone memory used to be.
       
    97     else if ( aStorage == ECamMediaStorageMassStorage ) // Saving to mass storage memory
       
    98        {
       
    99        PRINT( _L("Camera GetBasePathL saving to mass storage memory"))
       
   100        // Get the root path of the mass storage drive.
       
   101        TInt drive;
       
   102        TInt err = DriveInfo::GetDefaultDrive( DriveInfo::EDefaultMassStorage, drive );
       
   103        TFileName path;
       
   104        err = PathInfo::GetRootPath( path, drive );
       
   105        aPath.Copy(path);
       
   106        }
       
   107     else  // Saving to MMC
       
   108        {
       
   109        PRINT( _L("Camera GetBasePathL saving to memory card"))
       
   110        // Get the root path of the mmc.
       
   111        TInt drive;
       
   112        TInt err = DriveInfo::GetDefaultDrive( DriveInfo::EDefaultRemovableMassStorage, drive );
       
   113        TFileName path;
       
   114        err = PathInfo::GetRootPath( path, drive );
       
   115        aPath.Copy(path);
       
   116        }
       
   117 
       
   118      // Append the folder to the path
       
   119   if ( ECamControllerVideo == aCaptureMode )
       
   120       {
       
   121       aPath.Append( PathInfo::VideosPath() );
       
   122       // video folders are offset to ECamFolderTypeVideoMMC
       
   123       folderTypeIndex += ECamFolderTypeVideoMMC;
       
   124       }
       
   125   else 
       
   126       {
       
   127       aPath.Append( PathInfo::ImagesPath() );  
       
   128       }             
       
   129      
       
   130   // Add a folder for the current month
       
   131   // Use the specified time to determine the year and month.
       
   132   // If this is 0 then use the current time.
       
   133   TTime now = aTime;
       
   134   if ( now.Int64() == TInt64( 0 ) )
       
   135       {
       
   136       now.HomeTime();
       
   137       }
       
   138   TBuf<KCamMonthFolderNameLength> monthFolder;
       
   139   now.FormatL( monthFolder, KCamMonthFolderFormat );
       
   140   // If the month folder name is different to the last used month folder name
       
   141   // this indicates that a new month has been started. All the counters will
       
   142   // need to be reinitialised
       
   143   
       
   144   // Get last used folder name
       
   145   TBuf<KCamMonthFolderNameLength> previousMonthFolder;
       
   146   CRepository* cr = CRepository::NewLC( KCRUidCameraappSettings );
       
   147   cr->Get( KCamCrLastUsedMonthFolder, previousMonthFolder );
       
   148   
       
   149   // Compare to current folder name, if different then reset all counters
       
   150   if ( monthFolder.Compare( previousMonthFolder) != 0 )
       
   151       {
       
   152       ResetCounters( aMonthCounters );
       
   153       // Write month folder name to shared data 
       
   154       cr->Set( KCamCrLastUsedMonthFolder, monthFolder );
       
   155       }  
       
   156   CleanupStack::PopAndDestroy( cr );    
       
   157   TBuf<KMaxNameBaseLength> cameraFolder;
       
   158   StringLoader::Load( cameraFolder, R_CAM_CAMERA_SUBFOLDER );
       
   159   aPath.Append( cameraFolder );   
       
   160   aPath.Append( KBackslash );          
       
   161   aPath.Append( monthFolder );  
       
   162   aPath.Append( KBackslash ); 
       
   163   
       
   164   // Keep track of the month folder (YYYYMM) name length
       
   165   // This may be returned e.g.if the month counter destination folder  (YYYYMMXX) is
       
   166   // not created
       
   167   TInt monthFolderLength = aPath.Length();
       
   168   
       
   169   RFs rfs;
       
   170   User::LeaveIfError( rfs.Connect() );
       
   171   CleanupClosePushL( rfs );     
       
   172  
       
   173   // ensure the path exists
       
   174   TInt err = rfs.MkDirAll( aPath );
       
   175  
       
   176   // If the folder is newly created then set the counter to 0  
       
   177   if      ( KErrNone          == err ) aMonthCounters[folderTypeIndex] = 0;
       
   178   else if ( KErrAlreadyExists == err ) err = KErrNone;
       
   179   else                                 User::Leave( err );
       
   180 
       
   181           
       
   182   // If the month counter is uninitialised it needs to be set up
       
   183   if ( aMonthCounters[folderTypeIndex] < 0 )
       
   184       {
       
   185       User::LeaveIfError( InitialiseMonthCounter( aMonthCounters,
       
   186                                                   aPath,
       
   187                                                   monthFolder,
       
   188                                                   rfs,
       
   189                                                   folderTypeIndex ) );
       
   190       }
       
   191   aPath.Append( monthFolder ); 
       
   192   // Only ensure the folder exists (and has space) if the aCreateAll flag is set
       
   193   if ( aCreateAll )
       
   194       {
       
   195       PRINT( _L("Camera GetBasePathL creating month counter folder") )
       
   196       // This adds on the correct counter if completing without error
       
   197       User::LeaveIfError( CreateDestinationFolder( aMonthCounters,
       
   198                                                    aPath, 
       
   199                                                    rfs, 
       
   200                                                    folderTypeIndex, 
       
   201                                                    aRequiredFileCount ) );
       
   202       }
       
   203   else
       
   204       {
       
   205       TInt monthCounter = aMonthCounters[folderTypeIndex];
       
   206       aPath.Append( KCharacterOffset()[0] + monthCounter/KBase10 );
       
   207       aPath.Append( KDigitOffset()[0] + monthCounter%KBase10 );
       
   208       aPath.Append( KBackslash );
       
   209       // If the folder does not exist then remove the final folder name from the path
       
   210       TEntry entry;
       
   211       if ( rfs.Entry( aPath, entry ) == KErrNotFound )
       
   212           {
       
   213           aPath.SetLength( monthFolderLength );
       
   214           }
       
   215       }        
       
   216   CleanupStack::PopAndDestroy( &rfs );
       
   217 
       
   218   PRINT( _L("Camera <= CCamAppController::GetBasePathL returning") )
       
   219   }
       
   220 
       
   221 
       
   222 // ---------------------------------------------------------------------------
       
   223 // ResetCounters
       
   224 // ---------------------------------------------------------------------------
       
   225 //
       
   226 void 
       
   227 CCamFolderUtility::ResetCounters( TInt* aMonthCounters,
       
   228                                   TInt  aFrom,
       
   229                                   TInt  aTo )
       
   230   {
       
   231   PRINT( _L("Camera => CCamFolderUtility::ResetCounters") )
       
   232     {
       
   233     for( TInt i = aFrom; i <= aTo; i++ )
       
   234       {
       
   235       aMonthCounters[i] = -1;
       
   236       }
       
   237     }
       
   238   }
       
   239 
       
   240 
       
   241 
       
   242 // ---------------------------------------------------------------------------
       
   243 // InitialiseMonthCounter
       
   244 // Sets the value of the folder counter for the current month/media store/mode
       
   245 // ---------------------------------------------------------------------------
       
   246 //  
       
   247 TInt 
       
   248 CCamFolderUtility::InitialiseMonthCounter( TInt*  aMonthCounters,
       
   249                                            TDes&  aPath,
       
   250                                            TDesC& aMonthFolder,
       
   251                                            RFs&   aFs,
       
   252                                            TInt   aFolderType )
       
   253   {
       
   254   PRINT( _L("Camera => CCamFolderUtility::InitialiseMonthCounter") )
       
   255 
       
   256   // start by initialising the appropriate folder counter to 0
       
   257   aMonthCounters[aFolderType] = 0; 
       
   258       
       
   259   TInt monthFolderLength = aPath.Length();
       
   260   // The month counter folder starts with the same characters as the parent month folder
       
   261   aPath.Append( aMonthFolder );  
       
   262   TInt charCount;
       
   263   // Add on '??' wildcard characters to get a list of all folders with this 
       
   264   // month's format
       
   265   for ( charCount = 0; charCount < KMultipleFolderNumberChars; charCount++ )
       
   266       {
       
   267       aPath.Append( KWildCardCharacter );
       
   268       }
       
   269   // Get a list of folders for this month, sorted in descending alphabetical order
       
   270   // the first entry should be the latest used folder
       
   271   CDir* dirList;
       
   272   TInt err = KErrNone;
       
   273   err =  aFs.GetDir( aPath,
       
   274                      KEntryAttMatchExclusive|KEntryAttDir,
       
   275                      ESortByName|EDescending,
       
   276                      dirList );
       
   277   // Prune back to the parent folder path                           
       
   278   aPath.SetLength( monthFolderLength );                           
       
   279   if ( err == KErrNone )                           
       
   280     {
       
   281     TInt monthFolderCount = dirList->Count();                
       
   282     TInt index = 0;
       
   283     TBool done = EFalse;
       
   284     // Look through the list of folders in the month for the highest numbered folder
       
   285     // with the format YYYYMMAX Where YYYY is the year MM is the month A is an alphabetical
       
   286     // character in the range a-z or A-Z and X is a digit 0-9
       
   287     while ( index < monthFolderCount && !done )
       
   288       {
       
   289       done = ETrue;
       
   290       // The list is sorted in descending order. Get the last 2 characters from
       
   291       // the first directory in the list these indicate the highest folder number
       
   292       TPtrC name = ( *dirList )[index].iName; 
       
   293       TInt nameLength = name.Length();
       
   294       // Check the first character is in the range a-z or A-Z
       
   295       TChar firstChar = name[nameLength - KMultipleFolderNumberChars];
       
   296       firstChar.UpperCase();
       
   297       // If the character is not in the range then disregard this folder
       
   298       if ( firstChar < KCharacterOffset()[0] ||
       
   299            firstChar > KMaxCharacter()[0] )
       
   300         {
       
   301         done = EFalse;
       
   302         }
       
   303       // Check the second character is in the range 0-9                
       
   304       TChar secondChar = name[nameLength - 1];
       
   305       TInt secondCharVal = secondChar.GetNumericValue();
       
   306       if ( secondCharVal < 0 ||
       
   307            secondCharVal > KBase10 - 1 )
       
   308         {
       
   309         done = EFalse;
       
   310         }   
       
   311       if ( done )                             
       
   312         {
       
   313         TUint folderNumber = firstChar;
       
   314         // 10's part of folder number is represented by characters A-Z
       
   315         // convert the character into a decimal value
       
   316         folderNumber -= KCharacterOffset()[0];
       
   317         folderNumber *= KBase10; 
       
   318         // Now add on the units
       
   319         folderNumber += secondCharVal;
       
   320         aMonthCounters[aFolderType] = folderNumber;
       
   321         }
       
   322       // TUint folderNumber = name[nameLength - 2];       
       
   323       index++;   
       
   324       } 
       
   325     }
       
   326   delete dirList;  
       
   327   dirList = NULL;     
       
   328 
       
   329   PRINT1( _L("Camera <= CCamAppController::InitialiseMonthCounter returning %d"), err)
       
   330   return err;      
       
   331   }
       
   332   
       
   333 // ---------------------------------------------------------------------------
       
   334 // CreateDestinationFolder
       
   335 // Creates the folder where new images/videos are to be saved to.
       
   336 // ---------------------------------------------------------------------------
       
   337 //
       
   338 TInt 
       
   339 CCamFolderUtility::CreateDestinationFolder( TInt* aMonthCounters,
       
   340                                             TDes& aPath,
       
   341                                             RFs&  aFs, 
       
   342                                             TInt  aFolderType,
       
   343                                             TInt  aRequiredFileCount )    
       
   344   {
       
   345   PRINT( _L("Camera => CCamFolderUtility::CreateDestinationFolder ") ) 
       
   346   __ASSERT_DEBUG( aFolderType < ECamFolderTypeLast, CamPanic( ECamPanicBadIndex ) );
       
   347 
       
   348   TInt folderCreated = EFalse;
       
   349   // This error value will only be retained if the counter is outside
       
   350   // the allowed range 
       
   351   TInt err = KErrArgument; 
       
   352   TInt monthCounter = aMonthCounters[aFolderType];
       
   353   while ( !folderCreated && monthCounter < KMaxMonthFolders )
       
   354     {
       
   355     aMonthCounters[aFolderType] = monthCounter;
       
   356     err = KErrNone;   
       
   357     // Add on the new counter
       
   358     aPath.Append( KCharacterOffset()[0] + monthCounter/KBase10 );
       
   359     aPath.Append( KDigitOffset()[0] + monthCounter%KBase10 );
       
   360     aPath.Append( KBackslash );
       
   361     err = aFs.MkDirAll( aPath );
       
   362     PRINT1( _L("Camera <> MkDirAll returned %d "), err ) 
       
   363     // If the folder already exists then check there is enough space for the required file count
       
   364     if ( err == KErrAlreadyExists )
       
   365       {
       
   366       PRINT( _L("Camera <> MkDirAll KErrALreadyExists ") ) 
       
   367       // if this is the final folder (Z9) there is no need to check for available space
       
   368       // this folder will be used anyway
       
   369       if ( monthCounter >= KMaxMonthFolders - 1 ) 
       
   370         {
       
   371         PRINT( _L("Camera <> MkDirAll KErrALreadyExists Z9") ) 
       
   372         folderCreated = ETrue;
       
   373         // sanity check to ensure the counter is not too high
       
   374         aMonthCounters[aFolderType] = KMaxMonthFolders - 1;
       
   375         err = KErrNone;
       
   376         }
       
   377       // if this is not the final folder (Z9) check for space and try the next one if necessary
       
   378       else
       
   379         {  
       
   380         PRINT( _L("Camera <> MkDirAll KErrALreadyExists not Z9, retry") )                        
       
   381         CDir* fileList;  
       
   382         TInt dirErr = ( aFs.GetDir( aPath,
       
   383                                     KEntryAttMaskSupported,
       
   384                                     ESortNone,
       
   385                                     fileList ) );  
       
   386         TBool spaceRemaining = EFalse;    
       
   387         if ( !dirErr )
       
   388           {
       
   389           spaceRemaining = ( fileList->Count() + aRequiredFileCount <= KMaxFilesPerFolder );   
       
   390           }
       
   391         delete fileList;  
       
   392         fileList = NULL;                      
       
   393         if ( dirErr )        
       
   394           {
       
   395           PRINT1( _L("Camera <= CCamFolderUtility::DoCreateDestinationFolderL returning %d"), err)   
       
   396           return dirErr;    
       
   397           }             
       
   398                 
       
   399         // If there is insufficient space then try the next folder                                       
       
   400         if ( !spaceRemaining )  
       
   401           {
       
   402           monthCounter++;
       
   403           // Remove the previous counter characters and the trailing backslash then try again                                        
       
   404           aPath.SetLength( aPath.Length() - ( KMultipleFolderNumberChars + 1 ) );
       
   405           }
       
   406         else // This folder has enough space for the capture
       
   407           {
       
   408           folderCreated = ETrue;
       
   409           err = KErrNone;
       
   410           }     
       
   411         }
       
   412       }
       
   413     // There is a problem creating folders - report error         
       
   414     else if ( err )   
       
   415       {
       
   416       PRINT1( _L("Camera <= CCamFolderUtility::DoCreateDestinationFolderL returning %d"), err)
       
   417       return err;    
       
   418       }
       
   419     // A new folder has been created. There is no need to check the space
       
   420     else 
       
   421       {
       
   422       folderCreated = ETrue;
       
   423       }            
       
   424     }
       
   425 
       
   426   PRINT1( _L("Camera <= CCamFolderUtility::DoCreateDestinationFolderL returning %d"), err)
       
   427   return err;        
       
   428   }
       
   429 
       
   430 // ===========================================================================
       
   431 
       
   432 // end of file