photosgallery/viewframework/commandhandlers/commoncommandhandlers/src/glxcommandhandlerrotate.cpp
changeset 0 4e91876724a2
child 9 6b87b143d312
equal deleted inserted replaced
-1:000000000000 0:4e91876724a2
       
     1 /*
       
     2 * Copyright (c) 2008-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:    Temporary rotate command implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 
       
    23 #include "glxcommandhandlerrotate.h"
       
    24 
       
    25 #include <data_caging_path_literals.hrh>
       
    26 #include <alf/alfdisplay.h>
       
    27 
       
    28 #include <glxattributecontext.h>
       
    29 #include <glxuiutility.h>
       
    30 #include <glxmediageneraldefs.h>
       
    31 #include <glxsettingsmodel.h>
       
    32 #include <glxthumbnailcontext.h>
       
    33 #include <glxuistd.h>
       
    34 #include <glxvisuallistmanager.h>
       
    35 #include <mglxmedialist.h>
       
    36 #include <mglxvisuallist.h>
       
    37 #include <glxlog.h>
       
    38 #include <glxtracer.h>
       
    39 #include <mglxlayoutowner.h>
       
    40 
       
    41 #include <glxcommandhandlers.hrh>
       
    42 #include <glxuiutilities.rsg>
       
    43 #include <glxicons.mbg>
       
    44 
       
    45 #include    <ExifRead.h>
       
    46 #include    <glxcommandfactory.h>
       
    47 #include    <mpxcommandgeneraldefs.h>                   // Content ID identifying general category of content provided
       
    48 #include    <glxtexturemanager.h>
       
    49 
       
    50 #include<bautils.h>
       
    51 
       
    52 // ======== MEMBER FUNCTIONS ========
       
    53 
       
    54 // ---------------------------------------------------------------------------
       
    55 // Two-phased constructor.
       
    56 // ---------------------------------------------------------------------------
       
    57 //
       
    58 EXPORT_C CGlxCommandHandlerRotate*
       
    59             CGlxCommandHandlerRotate::NewL(
       
    60                                         MGlxMediaListProvider* aMediaListProvider,
       
    61                                         MGlxLayoutOwner* aLayoutOwner,
       
    62                                         TInt aLayoutIndex)
       
    63     {
       
    64     TRACER("CGlxCommandHandlerRotate* CGlxCommandHandlerRotate::NewL()");
       
    65     CGlxCommandHandlerRotate* self
       
    66             = new (ELeave) CGlxCommandHandlerRotate(aMediaListProvider, 
       
    67                 aLayoutOwner, aLayoutIndex);
       
    68     CleanupStack::PushL(self);
       
    69     self->ConstructL();
       
    70     CleanupStack::Pop(self);
       
    71     return self;
       
    72     }
       
    73 
       
    74 // ---------------------------------------------------------------------------
       
    75 // Destructor
       
    76 // ---------------------------------------------------------------------------
       
    77 //
       
    78 CGlxCommandHandlerRotate::~CGlxCommandHandlerRotate()
       
    79     {
       
    80     TRACER("CGlxCommandHandlerRotate::~CGlxCommandHandlerRotate");
       
    81     if ( iVisualListManager )
       
    82         {
       
    83         iVisualListManager->Close();
       
    84         }
       
    85 
       
    86     if ( iUiUtility )
       
    87         {
       
    88         iUiUtility->Close();
       
    89         }
       
    90     iFs.Close();
       
    91        
       
    92     if(iExifData != NULL)
       
    93         {
       
    94         delete iExifData;
       
    95         iExifData = NULL;
       
    96         }
       
    97     if(iExifWriter != NULL)
       
    98         {
       
    99         delete iExifWriter;
       
   100         iExifWriter = NULL;
       
   101         }
       
   102     }
       
   103 
       
   104 // ---------------------------------------------------------------------------
       
   105 // DoExecuteL
       
   106 // ---------------------------------------------------------------------------
       
   107 //
       
   108 TBool CGlxCommandHandlerRotate::DoExecuteL(TInt aCommandId,
       
   109                                                     MGlxMediaList& aList)
       
   110     {
       
   111     TRACER("CGlxCommandHandlerRotate::DoExecuteL");
       
   112     TBool handled = EFalse;
       
   113 	TInt rotationAngle ;
       
   114 	iMediaList = &aList;
       
   115 	switch ( aCommandId )
       
   116         {
       
   117 		case EGlxCmdRotateLeft:
       
   118 			rotationAngle = -90;
       
   119 			break;
       
   120 		case EGlxCmdRotateRight:
       
   121 			rotationAngle = 90;
       
   122 			break;
       
   123 		default:
       
   124             return handled;
       
   125 		}
       
   126 	DoRotateL(aList, rotationAngle);
       
   127     
       
   128     return handled;
       
   129     }
       
   130 
       
   131 // ---------------------------------------------------------------------------
       
   132 // DoActivateL
       
   133 // ---------------------------------------------------------------------------
       
   134 //
       
   135 void CGlxCommandHandlerRotate::DoActivateL(TInt aViewId)
       
   136     {
       
   137     TRACER("CGlxCommandHandlerRotate::DoActivateL");
       
   138     iViewId = aViewId;
       
   139     }
       
   140 
       
   141 // ---------------------------------------------------------------------------
       
   142 // Deactivate
       
   143 // ---------------------------------------------------------------------------
       
   144 //
       
   145 void CGlxCommandHandlerRotate::Deactivate()
       
   146     {
       
   147     TRACER("CGlxCommandHandlerRotate::Deactivate");
       
   148     
       
   149     iViewId = 0;
       
   150     }
       
   151 
       
   152 
       
   153 
       
   154 
       
   155 // ---------------------------------------------------------------------------
       
   156 // HandleItemAddedL
       
   157 // ---------------------------------------------------------------------------
       
   158 //
       
   159 void CGlxCommandHandlerRotate::HandleItemAddedL(TInt /*aStartIndex*/,
       
   160             TInt /*aEndIndex*/, MGlxMediaList* /*aList*/)
       
   161     {
       
   162     }
       
   163 
       
   164 // ---------------------------------------------------------------------------
       
   165 // HandleMediaL
       
   166 // ---------------------------------------------------------------------------
       
   167 //
       
   168 void CGlxCommandHandlerRotate::HandleMediaL(TInt /*aListIndex*/,
       
   169             MGlxMediaList* /*aList*/)
       
   170     {
       
   171     }
       
   172 
       
   173 // ---------------------------------------------------------------------------
       
   174 // HandleItemRemovedL
       
   175 // ---------------------------------------------------------------------------
       
   176 //
       
   177 void CGlxCommandHandlerRotate::HandleItemRemovedL(TInt /*aStartIndex*/,
       
   178             TInt /*aEndIndex*/, MGlxMediaList* /*aList*/)
       
   179     {
       
   180     }
       
   181 
       
   182 // ---------------------------------------------------------------------------
       
   183 // HandleItemModifiedL
       
   184 // ---------------------------------------------------------------------------
       
   185 //
       
   186 void CGlxCommandHandlerRotate::HandleItemModifiedL(
       
   187             const RArray<TInt>& /*aItemIndexes*/, MGlxMediaList* /*aList*/)
       
   188     {
       
   189     }
       
   190 
       
   191 // ---------------------------------------------------------------------------
       
   192 // HandleAttributesAvailableL
       
   193 // ---------------------------------------------------------------------------
       
   194 //
       
   195 void CGlxCommandHandlerRotate::HandleAttributesAvailableL(
       
   196             TInt /*aItemIndex*/, const RArray<TMPXAttribute>& /*aAttributes*/,
       
   197             MGlxMediaList* /*aList*/)
       
   198     {
       
   199     TRACER("CGlxCommandHandlerRotate::HandleAttributesAvailableL");
       
   200         
       
   201     }
       
   202 
       
   203 // ---------------------------------------------------------------------------
       
   204 // HandleFocusChangedL
       
   205 // ---------------------------------------------------------------------------
       
   206 //
       
   207 void CGlxCommandHandlerRotate::HandleFocusChangedL(
       
   208             NGlxListDefs::TFocusChangeType /*aType*/, TInt /*aNewIndex*/, 
       
   209             TInt /*aOldIndex*/, MGlxMediaList* /*aList*/)
       
   210     {
       
   211     TRACER("CGlxCommandHandlerRotate::HandleFocusChangedL");
       
   212     //Not required as we are doing this after each rotation DoPreserveOrientationL();
       
   213     DoCleanupRotationParametersL();
       
   214     
       
   215     iMediaList = NULL;
       
   216     }
       
   217 
       
   218 // ---------------------------------------------------------------------------
       
   219 // HandleItemSelectedL
       
   220 // ---------------------------------------------------------------------------
       
   221 //
       
   222 void CGlxCommandHandlerRotate::HandleItemSelectedL(TInt /*aIndex*/,
       
   223             TBool /*aSelected*/, MGlxMediaList* /*aList*/)
       
   224     {
       
   225     }
       
   226 
       
   227 // ---------------------------------------------------------------------------
       
   228 // HandleMessageL
       
   229 // ---------------------------------------------------------------------------
       
   230 //
       
   231 void CGlxCommandHandlerRotate::HandleMessageL(
       
   232             const CMPXMessage& /*aMessage*/, MGlxMediaList* /*aList*/)
       
   233     {
       
   234     }
       
   235 
       
   236 // ---------------------------------------------------------------------------
       
   237 // C++ default constructor can NOT contain any code that might leave.
       
   238 // ---------------------------------------------------------------------------
       
   239 //
       
   240 CGlxCommandHandlerRotate::CGlxCommandHandlerRotate(
       
   241                                         MGlxMediaListProvider* aMediaListProvider,
       
   242                                         MGlxLayoutOwner* aLayoutOwner,
       
   243                                         TInt aLayoutIndex) :
       
   244         CGlxMediaListCommandHandler(aMediaListProvider),
       
   245         iLayoutOwner(aLayoutOwner),
       
   246         iLayoutIndex(aLayoutIndex)
       
   247     {
       
   248     TRACER("CGlxCommandHandlerRotate::CGlxCommandHandlerRotate");
       
   249     }
       
   250 
       
   251 // ---------------------------------------------------------------------------
       
   252 // Symbian 2nd phase constructor can leave.
       
   253 // ---------------------------------------------------------------------------
       
   254 // 
       
   255 void CGlxCommandHandlerRotate::ConstructL()
       
   256     {
       
   257     TRACER("CGlxCommandHandlerRotate::ConstructL");
       
   258     iUiUtility = CGlxUiUtility::UtilityL();
       
   259       
       
   260     // Add rotate command for images only
       
   261    	TCommandInfo rotate(EGlxCmdRotate);
       
   262    	rotate.iCategoryFilter = EMPXImage;
       
   263    	rotate.iCategoryRule = TCommandInfo::ERequireAll;
       
   264     AddCommandL(rotate);
       
   265 	TCommandInfo rotateLeft(EGlxCmdRotateLeft);
       
   266 	rotateLeft.iCategoryFilter = EMPXImage;
       
   267    	rotateLeft.iCategoryRule = TCommandInfo::ERequireAll;
       
   268     AddCommandL(rotateLeft);
       
   269 	TCommandInfo rotateRight(EGlxCmdRotateRight);
       
   270 	rotateLeft.iCategoryFilter = EMPXImage;
       
   271    	rotateLeft.iCategoryRule = TCommandInfo::ERequireAll;
       
   272     AddCommandL(rotateRight);
       
   273 
       
   274     // Add view state dummy commands
       
   275    	TCommandInfo view(EGlxCmdStateView);
       
   276     AddCommandL(view);
       
   277    	TCommandInfo browse(EGlxCmdStateBrowse);
       
   278     AddCommandL(browse);
       
   279 	
       
   280     //File system 
       
   281     User::LeaveIfError(iFs.Connect());
       
   282     iAddedObserver=EFalse;
       
   283     }
       
   284 
       
   285 
       
   286 // ---------------------------------------------------------------------------
       
   287 // DoIsDisabled
       
   288 // ---------------------------------------------------------------------------
       
   289 //
       
   290 TBool CGlxCommandHandlerRotate::DoIsDisabled(TInt aCommandId, 
       
   291                                                 MGlxMediaList& aList) const
       
   292     {
       
   293     TRACER("CGlxCommandHandlerRotate::DoIsDisabled");
       
   294     TBool disabled = EFalse;
       
   295     /**/
       
   296     if( ViewingState() == TCommandInfo::EViewingStateView )
       
   297         {
       
   298         return ETrue;
       
   299         }
       
   300     switch (aCommandId)
       
   301         {
       
   302         case EGlxCmdRotate:
       
   303 		case EGlxCmdRotateLeft:
       
   304 		case EGlxCmdRotateRight:
       
   305             {
       
   306             if((aList.Count()<=0) || aList.Item(aList.FocusIndex()).IsStatic())
       
   307                 {
       
   308                 disabled = ETrue;
       
   309                 }
       
   310             break;
       
   311             }
       
   312       
       
   313         default:
       
   314             break;
       
   315         }
       
   316     
       
   317     return disabled;
       
   318     }
       
   319 // ---------------------------------------------------------------------------
       
   320 // DoRotateL
       
   321 // ---------------------------------------------------------------------------
       
   322 //
       
   323 void CGlxCommandHandlerRotate::DoRotateL(MGlxMediaList& /*aList*/, TInt aAngle)
       
   324     {
       
   325     TRACER("CGlxCommandHandlerRotate::DoRotateL");
       
   326     const TGlxMedia& item = MediaList().Item( MediaList().FocusIndex() );	
       
   327     iGlxItem =  &item;
       
   328     GLX_LOG_INFO("CGlxCommandHandlerRotate::DoRotateL1");
       
   329     TSize imageSize(0,0);
       
   330     item.GetDimensions(imageSize);
       
   331     iRotationAngle += aAngle;
       
   332     if(aAngle<0)
       
   333         {
       
   334         if (iRotationAngle < 0)
       
   335             {
       
   336             iRotationAngle = 270;
       
   337             }
       
   338         }
       
   339     else
       
   340         {
       
   341         if (iRotationAngle > 270)
       
   342             {
       
   343             iRotationAngle = 0;
       
   344             }
       
   345         }
       
   346     iFileToBeRotated.Copy(item.Uri());
       
   347     DoInitializeRotationParametersL();
       
   348     if(iInitialOrientation > 4)
       
   349         {
       
   350         imageSize.SetSize(imageSize.iHeight,imageSize.iWidth);
       
   351         }
       
   352     iUiUtility->SetRotatedImageSize(imageSize);
       
   353     //Perform Rotation Here itself rather than Calling it each time 
       
   354     DoPreserveOrientationL();
       
   355     } 
       
   356 
       
   357 // ---------------------------------------------------------------------------
       
   358 // DoCalculateOrientationL
       
   359 // ---------------------------------------------------------------------------
       
   360 //
       
   361 TInt CGlxCommandHandlerRotate::DoCalculateOrientationL(TInt aInitialOrientation)
       
   362     {
       
   363     TRACER("CGlxCommandHandlerRotate::DoCalculateOrientationL");
       
   364     /*
       
   365      * possible orientation state with angles for rotation
       
   366      * Possible Angles 0 - 90 - 180 - 270
       
   367      * Possible states 1 - 6 - 3 - 8 without a Flip
       
   368      * Possible states 2 - 5 - 4 - 7 when Flip is on
       
   369      */
       
   370     GLX_LOG_INFO("CGlxCommandHandlerRotate::DoCalculateOrientationL");
       
   371     TInt finalOrientation = aInitialOrientation;
       
   372     if(aInitialOrientation >8 || aInitialOrientation <0 )
       
   373         {
       
   374         return finalOrientation;
       
   375         }
       
   376     
       
   377     //Nitz subst code
       
   378     TInt rotOffset = iRotationAngle/90;
       
   379     TInt isOrientationOdd = aInitialOrientation % 2;
       
   380     TInt initStateIndex = 0;
       
   381     TInt finalStateIndex = 0;
       
   382     //Setting the orientation states for the initial unflipped orientation combinations
       
   383     TInt orientationStateArray[] = {1,6,3,8};
       
   384     //Seting the index for current orientation
       
   385     if(aInitialOrientation < 3)
       
   386         {
       
   387         initStateIndex = 0;
       
   388         }
       
   389     else if(aInitialOrientation >= 3 && aInitialOrientation < 5)
       
   390         {
       
   391         initStateIndex = 2;
       
   392         }
       
   393     else if(aInitialOrientation >= 5 && aInitialOrientation < 7)
       
   394         {
       
   395         initStateIndex = 1;
       
   396         }
       
   397     else if(aInitialOrientation >= 7 && aInitialOrientation <= 8)
       
   398         {
       
   399         initStateIndex = 3;
       
   400         }
       
   401     //Calculating the final orientation using the cyclic orientationStateArray. 
       
   402     //folding final index so that it behaves like a cyclic machine 
       
   403     finalStateIndex = (initStateIndex+rotOffset)%4;
       
   404     finalOrientation = orientationStateArray[finalStateIndex];
       
   405     //Checking if a Flip was present 
       
   406     if(aInitialOrientation>4 && isOrientationOdd )
       
   407         {
       
   408         finalOrientation -= 1;
       
   409         }
       
   410     if(aInitialOrientation<5 && !isOrientationOdd)
       
   411         {
       
   412         finalOrientation += 1;
       
   413         }
       
   414     GLX_LOG_INFO1("CGlxCommandHandlerRotate::DoCalculateOrientationL finalOrientation=%d",finalOrientation);
       
   415     return finalOrientation;
       
   416     }
       
   417 
       
   418 
       
   419 // ---------------------------------------------------------------------------
       
   420 // DoPreserveOrientationL
       
   421 // ---------------------------------------------------------------------------
       
   422 //
       
   423 void CGlxCommandHandlerRotate::DoPreserveOrientationL()
       
   424     {
       
   425     TRACER("CGlxCommandHandlerRotate::DoPreserveOrientationL");
       
   426     TUint16 finalOrientation = DoCalculateOrientationL(iInitialOrientation);
       
   427     if(finalOrientation != iInitialOrientation && iDoAttemptToSaveFile)
       
   428         {
       
   429         iExifWriter->SetOrientationL(finalOrientation);
       
   430         HBufC8* ModifiedexifData=NULL;
       
   431         //need only first KGlxMaxExifSize bytes of data as exif cannot bypass this size 
       
   432         TRAPD(err,ModifiedexifData = iExifWriter->WriteDataL(iExifData->Des()));  
       
   433         //Nitz To-do Write only first KGlxMaxExifSize bytes to the file
       
   434         //It currently fails in cases of JPEG files without Exif so removing it. 
       
   435         //TPtrC8 exifPtr =  ModifiedexifData->Mid(0,KGlxMaxExifSize);
       
   436         if(err == KErrNone)
       
   437             {
       
   438             iFileHandle.Write(0,ModifiedexifData->Des());
       
   439             delete ModifiedexifData;
       
   440             }
       
   441         else
       
   442             {
       
   443             iDoAttemptToSaveFile = EFalse;
       
   444             }
       
   445 
       
   446         //Reinitializing some class variables
       
   447         iInitialOrientation = finalOrientation;
       
   448         iRotationAngle = 0;
       
   449 
       
   450         }
       
   451     iFileHandle.Close();
       
   452     iInitialOrientation = 9;
       
   453     iRotationAngle = 0;
       
   454     iRotationApplied = EFalse;
       
   455     if(iExifData != NULL)
       
   456         {
       
   457         delete iExifData;
       
   458         iExifData = NULL;
       
   459         }
       
   460     if(iExifWriter != NULL)
       
   461         {
       
   462         delete iExifWriter;
       
   463         iExifWriter = NULL;
       
   464         } 
       
   465     //This will be called when there would be a change in Media list focus.
       
   466     //So removing the call from here
       
   467     //DoCleanupRotationParameters();
       
   468     }
       
   469 // ---------------------------------------------------------------------------
       
   470 // DoInitializeRotationParameters
       
   471 // ---------------------------------------------------------------------------
       
   472 //
       
   473 void CGlxCommandHandlerRotate::DoInitializeRotationParametersL()
       
   474     {
       
   475     TRACER("CGlxCommandHandlerRotate::DoInitializeRotationParametersL");
       
   476     if((!iDoAttemptToSaveFile)&& (!iAddedObserver))
       
   477         {
       
   478         iAddedObserver=ETrue;
       
   479         iMediaList->AddMediaListObserverL(this);
       
   480         }
       
   481     if(!iRotationApplied)
       
   482             {
       
   483             
       
   484             iTempFile.Copy(_L("c:\\data\\temp.ext"));
       
   485             User::LeaveIfError(iFileHandle.Open(iFs,
       
   486                     iFileToBeRotated, EFileWrite));
       
   487             iRotationApplied = ETrue;
       
   488             TInt filesize;
       
   489             User::LeaveIfError(iFileHandle.Size(filesize));
       
   490             iExifData = HBufC8::NewL(filesize);
       
   491             TPtr8 ptr(iExifData->Des());
       
   492             User::LeaveIfError(iFileHandle.Read(ptr));
       
   493             const CExifRead* exifReader = NULL;
       
   494             TRAPD(Exiferr,iExifWriter = CExifModify::NewL(*iExifData,CExifModify::EModify,CExifModify::ENoJpegParsing));
       
   495             if(Exiferr == KErrNone)
       
   496                 {
       
   497                 iDoAttemptToSaveFile = ETrue;
       
   498                 exifReader = iExifWriter->Reader();
       
   499                 TInt err = exifReader->GetOrientation(iInitialOrientation);
       
   500                 if(err != KErrNone)
       
   501                     {
       
   502                     iInitialOrientation = 9;
       
   503                     }
       
   504                 }
       
   505             else
       
   506                 {
       
   507                 iDoAttemptToSaveFile = EFalse;
       
   508                 }
       
   509             }
       
   510     }
       
   511 // ---------------------------------------------------------------------------
       
   512 // DoCleanupRotationParameters
       
   513 // ---------------------------------------------------------------------------
       
   514 //
       
   515 void CGlxCommandHandlerRotate::DoCleanupRotationParametersL()
       
   516     {
       
   517     TRACER("CGlxCommandHandlerRotate::DoCleanupRotationParametersL()");
       
   518     if(iDoAttemptToSaveFile)
       
   519         {
       
   520         //This is done just to get an MDS callback
       
   521         BaflUtils::CopyFile(iFs,iFileToBeRotated,iTempFile);
       
   522         BaflUtils::CopyFile(iFs,iTempFile,iFileToBeRotated);   
       
   523         BaflUtils::DeleteFile(iFs,iTempFile);
       
   524         iDoAttemptToSaveFile = EFalse;
       
   525         }  
       
   526 
       
   527     iTempFile.Zero();
       
   528     iInitialOrientation = 9;
       
   529     iRotationAngle = 0;
       
   530     //Cleanup the thumbnail DB using Cleanup command as MDS takes a Long time for a callback.
       
   531     CMPXCommand* command = TGlxCommandFactory::ThumbnailCleanupCommandLC();
       
   532     command->SetTObjectValueL<TAny*>(KMPXCommandGeneralSessionId, static_cast<TAny*>(this));
       
   533     
       
   534     //Nitz To Do Initialize cleanup command Just for the respective Media Items
       
   535   //TGlxMediaId itemId= iGlxItem->Id();
       
   536   //  command->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId,itemId.Value()); 
       
   537     iMediaList->CommandL(*command);
       
   538     CleanupStack::PopAndDestroy(command);
       
   539     iMediaList->RemoveMediaListObserver(this);
       
   540     iAddedObserver=EFalse;
       
   541     //CGlxTextureManager& tm = iUiUtility->GlxTextureManager();
       
   542     //tm.UpdateThumbnailTexture(*iGlxItem);
       
   543     iMediaList = NULL;
       
   544     iGlxItem = NULL;
       
   545 
       
   546     iRotationApplied = EFalse;
       
   547     if(iExifData != NULL)
       
   548         {
       
   549         delete iExifData;
       
   550         iExifData = NULL;
       
   551         }
       
   552     if(iExifWriter != NULL)
       
   553         {
       
   554         delete iExifWriter;
       
   555         iExifWriter = NULL;
       
   556         } 
       
   557     }
       
   558 //  End of File