screengrabber/src/SGModel.cpp
branchRCL_3
changeset 21 b3cee849fa46
parent 20 48060abbbeaf
child 22 fad26422216a
equal deleted inserted replaced
20:48060abbbeaf 21:b3cee849fa46
     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 
       
    18 
       
    19 
       
    20 #include "SGModel.h"
       
    21 #include "SGApp.h"
       
    22 #include "SG.hrh"
       
    23 #include "SGGifAnimator.h"
       
    24 
       
    25 #include <w32std.h>
       
    26 #include <e32keys.h>
       
    27 #include <imageconversion.h>
       
    28 #include <pathinfo.h>
       
    29 #include <AknGlobalConfirmationQuery.h>
       
    30 #include <aknnotewrappers.h>
       
    31 #include <textresolver.h>
       
    32 #include <bautils.h>
       
    33 #include <coeutils.h>
       
    34 #include <s32file.h>
       
    35 #include <AknGlobalNote.h>
       
    36 
       
    37 
       
    38 _LIT(KSingleShotSaved, "Screen shot saved to Media Gallery");
       
    39 _LIT(KMultipleShotsSaved, "%u screen shots saved to Media Gallery");
       
    40 _LIT(KVideoSaved, "Video saved to Media Gallery");
       
    41 _LIT(KErrorOccured, "Grabber error: ");
       
    42 _LIT(KDefaultImageFileName, "Shot");
       
    43 _LIT(KDefaultVideoFileName, "Video");
       
    44 _LIT(KScreenShotsSubDirectory, "Screen Shots\\");
       
    45 _LIT(KSGTemporaryDirectory, "\\system\\temp\\screengrabber\\");
       
    46 
       
    47 #define HIGH_QUALITY_JPEG 97
       
    48 #define LOW_QUALITY_JPEG 60
       
    49 #define DEFAULT_SEQ_CAPTURE_DELAY_MS 5000   // 5.000 secs
       
    50 #define VIDEO_CAPTURE_DELAY 250             // 0.25 secs
       
    51 #define VIDEO_CAPTURE_MINIMUM_DELAY 200     // 0.20 secs
       
    52 #define KEY_CAPTURE_PRIORITY 100            // do not change, this is for window server
       
    53 
       
    54 const TInt KSettingsDrive = EDriveC;
       
    55 _LIT(KSettingsFileName, "screengrabber_settings.ini");
       
    56 
       
    57 // ---------------------------------------------------------------------------
       
    58 
       
    59 CScreenGrabberModel* CScreenGrabberModel::NewL()
       
    60 	{
       
    61 	CScreenGrabberModel* self = new(ELeave) CScreenGrabberModel;
       
    62 	CleanupStack::PushL(self);
       
    63 	self->ConstructL();
       
    64 	CleanupStack::Pop();
       
    65 	return self;
       
    66 	}
       
    67 
       
    68 // ---------------------------------------------------------------------------
       
    69 
       
    70 CScreenGrabberModel::CScreenGrabberModel() : CActive(EPriorityStandard)
       
    71 	{
       
    72 	}
       
    73 
       
    74 // ---------------------------------------------------------------------------
       
    75 
       
    76 void CScreenGrabberModel::ConstructL()
       
    77 	{
       
    78     User::LeaveIfError(iTimer.CreateLocal());
       
    79 
       
    80     // init audio utility
       
    81   	iMdaAudioToneUtility = CMdaAudioToneUtility::NewL(*this);
       
    82 
       
    83     iSavedQuery = CSavedQuery::NewL();
       
    84     iVideoFrameArray = new(ELeave) CVideoFrameArray(10000);
       
    85 
       
    86 	iPreviouslyCapturedBitmap = new(ELeave) CFbsBitmap;
       
    87 
       
    88     iEnv = CEikonEnv::Static();
       
    89   	iRootWin = iEnv->RootWin();
       
    90   	iCapturingInProgress = EFalse;
       
    91   	iStopCapturing = EFalse;
       
    92   	iNumberOfTakenShots = 0;
       
    93   	iCurrentFrameNumber = 0;
       
    94   	iHashKeyCapturingActivated = EFalse;
       
    95   	iHashKeyDown = EFalse;
       
    96   	iGalleryUpdaterSupported = ETrue;
       
    97   	iGalleryUpdaterInitialized = EFalse;
       
    98 
       
    99 	CActiveScheduler::Add(this);
       
   100 	}
       
   101 
       
   102 // ---------------------------------------------------------------------------
       
   103 
       
   104 void CScreenGrabberModel::ActivateModelL()
       
   105 	{
       
   106     // clean temporary files
       
   107     TRAP_IGNORE( CleanTemporaryFilesL() );
       
   108             
       
   109     // load settings
       
   110     TRAP_IGNORE( LoadSettingsL() );
       
   111 
       
   112     // start capturing
       
   113     ActivateCaptureKeysL();
       
   114 	}
       
   115 
       
   116 // ---------------------------------------------------------------------------
       
   117 
       
   118 void CScreenGrabberModel::DeActivateModelL()
       
   119 	{
       
   120     CancelCapturing();
       
   121 
       
   122     // for a faster exit, send the application to background
       
   123     TApaTask selfTask(iEnv->WsSession());
       
   124     selfTask.SetWgId(iEnv->RootWin().Identifier());
       
   125     selfTask.SendToBackground();
       
   126 	}
       
   127 	
       
   128 // ---------------------------------------------------------------------------
       
   129 
       
   130 CScreenGrabberModel::~CScreenGrabberModel()
       
   131 	{
       
   132 	Cancel();
       
   133 
       
   134     // deactivate Media Gallery DLL
       
   135     if (iGalleryUpdaterInitialized)
       
   136         {
       
   137         if (iMGXFileManager)
       
   138             delete iMGXFileManager;
       
   139             
       
   140         iGalleryUpdaterDLL.Close();
       
   141         }
       
   142 
       
   143 	TRAP_IGNORE( CleanTemporaryFilesL() );
       
   144 
       
   145     iTimer.Close();
       
   146 
       
   147     if (iFrameImageData)
       
   148         delete iFrameImageData;
       
   149 
       
   150     if (iPreviouslyCapturedBitmap)
       
   151         delete iPreviouslyCapturedBitmap;
       
   152 
       
   153     if (iImageEncoder)
       
   154         delete iImageEncoder;
       
   155         
       
   156     delete iVideoFrameArray;
       
   157 
       
   158     delete iSavedQuery;
       
   159 
       
   160     delete iMdaAudioToneUtility;
       
   161     }
       
   162 
       
   163 // ---------------------------------------------------------------------------
       
   164 
       
   165 void CScreenGrabberModel::LoadDFSValueL(CDictionaryFileStore* aDicFS, const TUid& aUid, TInt& aValue)
       
   166     {
       
   167     if (aDicFS->IsPresentL(aUid))
       
   168         {
       
   169         RDictionaryReadStream in;
       
   170         in.OpenLC(*aDicFS, aUid);
       
   171         aValue = in.ReadInt16L();
       
   172         CleanupStack::PopAndDestroy(); // in        
       
   173         }
       
   174     }
       
   175 
       
   176 // ---------------------------------------------------------------------------
       
   177 
       
   178 void CScreenGrabberModel::LoadDFSValueL(CDictionaryFileStore* aDicFS, const TUid& aUid, TDes& aValue)
       
   179     {
       
   180     if (aDicFS->IsPresentL(aUid))
       
   181         {
       
   182         RDictionaryReadStream in;
       
   183         in.OpenLC(*aDicFS, aUid);
       
   184         TInt bufLength = in.ReadInt16L();   // get length of descriptor
       
   185         in.ReadL(aValue, bufLength);        // get the descriptor itself
       
   186         CleanupStack::PopAndDestroy(); // in
       
   187         }
       
   188     }
       
   189 
       
   190 // ---------------------------------------------------------------------------
       
   191 
       
   192 void CScreenGrabberModel::SaveDFSValueL(CDictionaryFileStore* aDicFS, const TUid& aUid, const TInt& aValue)
       
   193     {
       
   194     RDictionaryWriteStream out;
       
   195     out.AssignLC(*aDicFS, aUid);
       
   196     out.WriteInt16L(aValue);
       
   197     out.CommitL(); 	
       
   198     CleanupStack::PopAndDestroy(1);// out
       
   199     }
       
   200 
       
   201 // ---------------------------------------------------------------------------
       
   202 
       
   203 void CScreenGrabberModel::SaveDFSValueL(CDictionaryFileStore* aDicFS, const TUid& aUid, const TDes& aValue)
       
   204     {
       
   205     RDictionaryWriteStream out;
       
   206     out.AssignLC(*aDicFS, aUid);
       
   207     out.WriteInt16L(aValue.Length());       // write length of the descriptor
       
   208     out.WriteL(aValue, aValue.Length());    // write the descriptor itself
       
   209     out.CommitL(); 	
       
   210     CleanupStack::PopAndDestroy(1);// out
       
   211     }
       
   212     
       
   213 // ---------------------------------------------------------------------------
       
   214 
       
   215 void CScreenGrabberModel::LoadSettingsL()
       
   216     {
       
   217     // set defaults
       
   218     iGrabSettings.iCaptureMode = ECaptureModeSingleCapture;
       
   219     
       
   220     iGrabSettings.iSingleCaptureHotkey = EHotkeySendKey;
       
   221     iGrabSettings.iSingleCaptureImageFormat = EImageFormatPNG;
       
   222     iGrabSettings.iSingleCaptureMemoryInUse = CAknMemorySelectionSettingPage::EPhoneMemory; 
       
   223     iGrabSettings.iSingleCaptureMemoryInUseMultiDrive = EDriveC;
       
   224     iGrabSettings.iSingleCaptureFileName.Copy( KDefaultImageFileName );
       
   225 
       
   226     iGrabSettings.iSequantialCaptureHotkey = EHotkeySendKey;
       
   227     iGrabSettings.iSequantialCaptureImageFormat = EImageFormatPNG;
       
   228     iGrabSettings.iSequantialCaptureDelay = DEFAULT_SEQ_CAPTURE_DELAY_MS;
       
   229     iGrabSettings.iSequantialCaptureMemoryInUse = CAknMemorySelectionSettingPage::EPhoneMemory; 
       
   230     iGrabSettings.iSequantialCaptureMemoryInUseMultiDrive = EDriveC;
       
   231     iGrabSettings.iSequantialCaptureFileName.Copy( KDefaultImageFileName );
       
   232 
       
   233     iGrabSettings.iVideoCaptureHotkey = EHotkeySendKey;
       
   234     iGrabSettings.iVideoCaptureVideoFormat = EVideoFormatAnimatedGIF;
       
   235     iGrabSettings.iVideoCaptureMemoryInUse = CAknMemorySelectionSettingPage::EPhoneMemory; 
       
   236     iGrabSettings.iVideoCaptureMemoryInUseMultiDrive = EDriveC;
       
   237     iGrabSettings.iVideoCaptureFileName.Copy( KDefaultVideoFileName );
       
   238        
       
   239         
       
   240     // make sure that the private path of this app in c-drive exists
       
   241     iEnv->FsSession().CreatePrivatePath( KSettingsDrive ); // c:\\private\\101fb751\\
       
   242     
       
   243     // handle settings always in the private directory 
       
   244     if (iEnv->FsSession().SetSessionToPrivate( KSettingsDrive ) == KErrNone)
       
   245         {
       
   246         // open or create a dictionary file store
       
   247         CDictionaryFileStore* settingsStore = CDictionaryFileStore::OpenLC(iEnv->FsSession(), KSettingsFileName, KUidScreenGrabber);
       
   248 
       
   249         LoadDFSValueL(settingsStore, KSGSettingCaptureMode,                             iGrabSettings.iCaptureMode);
       
   250         
       
   251         LoadDFSValueL(settingsStore, KSGSettingSingleCaptureHotkey,                     iGrabSettings.iSingleCaptureHotkey);
       
   252         LoadDFSValueL(settingsStore, KSGSettingSingleCaptureImageFormat,                iGrabSettings.iSingleCaptureImageFormat);
       
   253         LoadDFSValueL(settingsStore, KSGSettingSingleCaptureMemoryInUse,                (TInt&)iGrabSettings.iSingleCaptureMemoryInUse);
       
   254         LoadDFSValueL(settingsStore, KSGSettingSingleCaptureMemoryInUseMultiDrive,      (TInt&)iGrabSettings.iSingleCaptureMemoryInUseMultiDrive);
       
   255         LoadDFSValueL(settingsStore, KSGSettingSingleCaptureFileName,                   iGrabSettings.iSingleCaptureFileName);
       
   256         
       
   257         LoadDFSValueL(settingsStore, KSGSettingSequantialCaptureHotkey,                 iGrabSettings.iSequantialCaptureHotkey);
       
   258         LoadDFSValueL(settingsStore, KSGSettingSequantialCaptureImageFormat,            iGrabSettings.iSequantialCaptureImageFormat);
       
   259         LoadDFSValueL(settingsStore, KSGSettingSequantialCaptureDelay,                  iGrabSettings.iSequantialCaptureDelay);
       
   260         LoadDFSValueL(settingsStore, KSGSettingSequantialCaptureMemoryInUse,            (TInt&)iGrabSettings.iSequantialCaptureMemoryInUse);
       
   261         LoadDFSValueL(settingsStore, KSGSettingSequantialCaptureMemoryInUseMultiDrive,  (TInt&)iGrabSettings.iSequantialCaptureMemoryInUseMultiDrive);
       
   262         LoadDFSValueL(settingsStore, KSGSettingSequantialCaptureFileName,               iGrabSettings.iSequantialCaptureFileName);
       
   263 
       
   264         LoadDFSValueL(settingsStore, KSGSettingVideoCaptureHotkey,                      iGrabSettings.iVideoCaptureHotkey);
       
   265         LoadDFSValueL(settingsStore, KSGSettingVideoCaptureVideoFormat,                 iGrabSettings.iVideoCaptureVideoFormat);
       
   266         LoadDFSValueL(settingsStore, KSGSettingVideoCaptureMemoryInUse,                 (TInt&)iGrabSettings.iVideoCaptureMemoryInUse);
       
   267         LoadDFSValueL(settingsStore, KSGSettingVideoCaptureMemoryInUseMultiDrive,       (TInt&)iGrabSettings.iVideoCaptureMemoryInUseMultiDrive);
       
   268         LoadDFSValueL(settingsStore, KSGSettingVideoCaptureFileName,                    iGrabSettings.iVideoCaptureFileName);
       
   269 
       
   270         CleanupStack::PopAndDestroy(); // settingsStore         
       
   271         }
       
   272     }
       
   273 
       
   274 // ---------------------------------------------------------------------------
       
   275 
       
   276 void CScreenGrabberModel::SaveSettingsL(TGrabSettings aGrabSettings)
       
   277     {
       
   278     // set the new settings
       
   279     iGrabSettings = aGrabSettings;
       
   280 
       
   281     // handle settings always in c:\\private\\101fb751\\
       
   282     if (iEnv->FsSession().SetSessionToPrivate( KSettingsDrive ) == KErrNone)
       
   283         {
       
   284         // delete existing store to make sure that it is clean and not eg corrupted
       
   285         if (BaflUtils::FileExists(iEnv->FsSession(), KSettingsFileName))
       
   286             {
       
   287             iEnv->FsSession().Delete(KSettingsFileName);
       
   288             }
       
   289         
       
   290         // create a dictionary file store
       
   291         CDictionaryFileStore* settingsStore = CDictionaryFileStore::OpenLC(iEnv->FsSession(), KSettingsFileName, KUidScreenGrabber);
       
   292 
       
   293         SaveDFSValueL(settingsStore, KSGSettingCaptureMode,                             iGrabSettings.iCaptureMode);
       
   294         
       
   295         SaveDFSValueL(settingsStore, KSGSettingSingleCaptureHotkey,                     iGrabSettings.iSingleCaptureHotkey);
       
   296         SaveDFSValueL(settingsStore, KSGSettingSingleCaptureImageFormat,                iGrabSettings.iSingleCaptureImageFormat);
       
   297         SaveDFSValueL(settingsStore, KSGSettingSingleCaptureMemoryInUse,                (TInt&)iGrabSettings.iSingleCaptureMemoryInUse);
       
   298         SaveDFSValueL(settingsStore, KSGSettingSingleCaptureMemoryInUseMultiDrive,      (TInt&)iGrabSettings.iSingleCaptureMemoryInUseMultiDrive);
       
   299         SaveDFSValueL(settingsStore, KSGSettingSingleCaptureFileName,                   iGrabSettings.iSingleCaptureFileName);
       
   300         
       
   301         SaveDFSValueL(settingsStore, KSGSettingSequantialCaptureHotkey,                 iGrabSettings.iSequantialCaptureHotkey);
       
   302         SaveDFSValueL(settingsStore, KSGSettingSequantialCaptureImageFormat,            iGrabSettings.iSequantialCaptureImageFormat);
       
   303         SaveDFSValueL(settingsStore, KSGSettingSequantialCaptureDelay,                  iGrabSettings.iSequantialCaptureDelay);
       
   304         SaveDFSValueL(settingsStore, KSGSettingSequantialCaptureMemoryInUse,            (TInt&)iGrabSettings.iSequantialCaptureMemoryInUse);
       
   305         SaveDFSValueL(settingsStore, KSGSettingSequantialCaptureMemoryInUseMultiDrive,  (TInt&)iGrabSettings.iSequantialCaptureMemoryInUseMultiDrive);
       
   306         SaveDFSValueL(settingsStore, KSGSettingSequantialCaptureFileName,               iGrabSettings.iSequantialCaptureFileName);
       
   307 
       
   308         SaveDFSValueL(settingsStore, KSGSettingVideoCaptureHotkey,                      iGrabSettings.iVideoCaptureHotkey);
       
   309         SaveDFSValueL(settingsStore, KSGSettingVideoCaptureVideoFormat,                 iGrabSettings.iVideoCaptureVideoFormat);
       
   310         SaveDFSValueL(settingsStore, KSGSettingVideoCaptureMemoryInUse,                 (TInt&)iGrabSettings.iVideoCaptureMemoryInUse);
       
   311         SaveDFSValueL(settingsStore, KSGSettingVideoCaptureMemoryInUseMultiDrive,       (TInt&)iGrabSettings.iVideoCaptureMemoryInUseMultiDrive);
       
   312         SaveDFSValueL(settingsStore, KSGSettingVideoCaptureFileName,                    iGrabSettings.iVideoCaptureFileName);
       
   313         
       
   314         settingsStore->CommitL();
       
   315         CleanupStack::PopAndDestroy(); // settingsStore             
       
   316         }
       
   317     }
       
   318     	
       
   319 // ---------------------------------------------------------------------------
       
   320 
       
   321 void CScreenGrabberModel::DoCancel()
       
   322 	{
       
   323     iTimer.Cancel();
       
   324 	}
       
   325 
       
   326 // ---------------------------------------------------------------------------
       
   327 
       
   328 void CScreenGrabberModel::ActivateCaptureKeysL(TBool aChangeKey)
       
   329     {
       
   330     // if changing the capture key, capturing needs to be cancelled first
       
   331     if (aChangeKey)
       
   332         {
       
   333         CancelCapturing();
       
   334         }
       
   335 
       
   336     // get hotkey of the capture
       
   337     TInt captureHotkey(0);
       
   338     if (iGrabSettings.iCaptureMode == ECaptureModeSingleCapture)
       
   339         captureHotkey = iGrabSettings.iSingleCaptureHotkey;
       
   340     else if (iGrabSettings.iCaptureMode == ECaptureModeSequantialCapture)
       
   341         captureHotkey = iGrabSettings.iSequantialCaptureHotkey;
       
   342     else if (iGrabSettings.iCaptureMode == ECaptureModeVideoCapture)
       
   343         captureHotkey = iGrabSettings.iVideoCaptureHotkey;
       
   344     else
       
   345         User::Panic(_L("Wrong mode"), 40);
       
   346     
       
   347     
       
   348     // capture hash key if needed
       
   349     if (captureHotkey == EHotkeyHashStar)
       
   350         {
       
   351         iCapturedKeyHash    = iRootWin.CaptureKey(EStdKeyHash, EModifierCtrl|EModifierShift|EModifierFunc, 0, KEY_CAPTURE_PRIORITY);
       
   352         iCapturedKeyHashUnD = iRootWin.CaptureKeyUpAndDowns(EStdKeyHash, EModifierCtrl|EModifierShift|EModifierFunc, 0, KEY_CAPTURE_PRIORITY);
       
   353         iHashKeyCapturingActivated = ETrue;
       
   354         }
       
   355     
       
   356 
       
   357     // start capturing based on user selected key
       
   358     switch (captureHotkey)
       
   359         {
       
   360         case EHotkeyShiftStar:
       
   361             {
       
   362             iCapturedKey    = iRootWin.CaptureKey('*', EModifierCtrl|EModifierShift|EModifierFunc, EModifierShift, KEY_CAPTURE_PRIORITY);
       
   363             iCapturedKeyUnD = iRootWin.CaptureKeyUpAndDowns('*', EModifierCtrl|EModifierShift|EModifierFunc, EModifierShift, KEY_CAPTURE_PRIORITY);
       
   364             break;
       
   365             }
       
   366         case EHotkeyHashStar:
       
   367             {
       
   368             iCapturedKey    = iRootWin.CaptureKey('*', EModifierCtrl|EModifierShift|EModifierFunc, 0, KEY_CAPTURE_PRIORITY);
       
   369             iCapturedKeyUnD = iRootWin.CaptureKeyUpAndDowns('*', EModifierCtrl|EModifierShift|EModifierFunc, 0, KEY_CAPTURE_PRIORITY);
       
   370             break;
       
   371             }
       
   372         case EHotkeyShiftMenu:
       
   373             {
       
   374             iCapturedKey    = iRootWin.CaptureKey(EStdKeyApplication0, EModifierCtrl|EModifierShift|EModifierFunc, EModifierShift, KEY_CAPTURE_PRIORITY);
       
   375             iCapturedKeyUnD = iRootWin.CaptureKeyUpAndDowns(EStdKeyApplication0, EModifierCtrl|EModifierShift|EModifierFunc, EModifierShift, KEY_CAPTURE_PRIORITY);
       
   376             break;
       
   377             }
       
   378         case EHotkeySendKey:
       
   379             {
       
   380             iCapturedKey    = iRootWin.CaptureKey(EStdKeyYes, EModifierCtrl|EModifierShift|EModifierFunc, 0, KEY_CAPTURE_PRIORITY);
       
   381             iCapturedKeyUnD = iRootWin.CaptureKeyUpAndDowns(EStdKeyYes, EModifierCtrl|EModifierShift|EModifierFunc, 0, KEY_CAPTURE_PRIORITY);
       
   382             break;
       
   383             }
       
   384         case EHotkeyPowerKey:
       
   385             {
       
   386             iCapturedKey    = iRootWin.CaptureKey(EStdKeyDevice2, EModifierCtrl|EModifierShift|EModifierFunc, 0, KEY_CAPTURE_PRIORITY);
       
   387             iCapturedKeyUnD = iRootWin.CaptureKeyUpAndDowns(EStdKeyDevice2, EModifierCtrl|EModifierShift|EModifierFunc, 0, KEY_CAPTURE_PRIORITY);
       
   388             break;
       
   389             }
       
   390         case EHotkeySideKey:
       
   391             {
       
   392             iCapturedKey    = iRootWin.CaptureKey(EStdKeyDevice6, EModifierCtrl|EModifierShift|EModifierFunc, 0, KEY_CAPTURE_PRIORITY);
       
   393             iCapturedKeyUnD = iRootWin.CaptureKeyUpAndDowns(EStdKeyDevice6, EModifierCtrl|EModifierShift|EModifierFunc, 0, KEY_CAPTURE_PRIORITY);
       
   394             break;            
       
   395             }
       
   396         case EHotkeyCameraKey1:
       
   397             {
       
   398             iCapturedKey    = iRootWin.CaptureKey(EStdKeyDevice7, EModifierCtrl|EModifierShift|EModifierFunc, 0, KEY_CAPTURE_PRIORITY);
       
   399             iCapturedKeyUnD = iRootWin.CaptureKeyUpAndDowns(EStdKeyDevice7, EModifierCtrl|EModifierShift|EModifierFunc, 0, KEY_CAPTURE_PRIORITY);
       
   400             break;            
       
   401             }
       
   402         case EHotkeyCameraKey2:
       
   403             {
       
   404             iCapturedKey    = iRootWin.CaptureKey(EStdKeyApplication1A, EModifierCtrl|EModifierShift|EModifierFunc, 0, KEY_CAPTURE_PRIORITY);
       
   405             iCapturedKeyUnD = iRootWin.CaptureKeyUpAndDowns(EStdKeyApplication1A, EModifierCtrl|EModifierShift|EModifierFunc, 0, KEY_CAPTURE_PRIORITY);
       
   406             break;            
       
   407             }
       
   408        	case EHotkeyPOC:
       
   409         	{
       
   410         	iCapturedKey    = iRootWin.CaptureKey(EStdKeyApplication1, EModifierCtrl|EModifierShift|EModifierFunc, 0, KEY_CAPTURE_PRIORITY);
       
   411             iCapturedKeyUnD = iRootWin.CaptureKeyUpAndDowns(EStdKeyApplication1, EModifierCtrl|EModifierShift|EModifierFunc, 0, KEY_CAPTURE_PRIORITY);
       
   412            	break;
       
   413         	}  
       
   414         default:
       
   415             {
       
   416             User::Panic(_L("Key not supported"), 100);
       
   417             break;
       
   418             }
       
   419         }
       
   420     }
       
   421 
       
   422 // ---------------------------------------------------------------------------
       
   423 
       
   424 void CScreenGrabberModel::CancelCapturing()
       
   425     {
       
   426 	// cancel all captures
       
   427     iRootWin.CancelCaptureKey(iCapturedKey);
       
   428     iRootWin.CancelCaptureKeyUpAndDowns(iCapturedKeyUnD);
       
   429     
       
   430     if (iHashKeyCapturingActivated)
       
   431         {
       
   432         iRootWin.CancelCaptureKey(iCapturedKeyHash);
       
   433         iRootWin.CancelCaptureKeyUpAndDowns(iCapturedKeyHashUnD);
       
   434         
       
   435         iHashKeyCapturingActivated = EFalse;
       
   436         }
       
   437     }
       
   438 
       
   439 // ---------------------------------------------------------------------------
       
   440 
       
   441 TBool CScreenGrabberModel::HandleCaptureCommandsL(const TWsEvent& aEvent)
       
   442     {
       
   443     TBool continueEventLoop(ETrue);
       
   444     
       
   445     // get hotkey of the capture
       
   446     TInt captureHotkey(0);
       
   447     if (iGrabSettings.iCaptureMode == ECaptureModeSingleCapture)
       
   448         captureHotkey = iGrabSettings.iSingleCaptureHotkey;
       
   449     else if (iGrabSettings.iCaptureMode == ECaptureModeSequantialCapture)
       
   450         captureHotkey = iGrabSettings.iSequantialCaptureHotkey;
       
   451     else if (iGrabSettings.iCaptureMode == ECaptureModeVideoCapture)
       
   452         captureHotkey = iGrabSettings.iVideoCaptureHotkey;
       
   453     else
       
   454         User::Panic(_L("Wrong mode"), 41);
       
   455 
       
   456 
       
   457     // ignore any errors
       
   458     if (aEvent.Type()==EEventErrorMessage)
       
   459 	    {
       
   460 	    // error
       
   461 	    }
       
   462 	
       
   463 	// check if hash key has been pushed down
       
   464 	else if (iHashKeyCapturingActivated && aEvent.Type()==EEventKeyDown && aEvent.Key()->iScanCode==EStdKeyHash)
       
   465 	    {
       
   466         iHashKeyDown = ETrue;	    
       
   467 	    }
       
   468 
       
   469 	// check if hash key has been released
       
   470 	else if (iHashKeyCapturingActivated && aEvent.Type()==EEventKeyUp && aEvent.Key()->iScanCode==EStdKeyHash)
       
   471 	    {
       
   472         iHashKeyDown = EFalse;	    
       
   473 	    }
       
   474 	    	
       
   475     // handle captured keys, we are interested here only of the keydown events
       
   476     else if (
       
   477               ( captureHotkey == EHotkeyShiftStar &&
       
   478                 aEvent.Type()==EEventKeyDown && aEvent.Key()->iScanCode=='*' &&
       
   479                 aEvent.Key()->iModifiers & EModifierShift)
       
   480             ||
       
   481               ( captureHotkey == EHotkeyHashStar &&
       
   482                 aEvent.Type()==EEventKeyDown && aEvent.Key()->iScanCode=='*' &&
       
   483                 iHashKeyDown)
       
   484             ||
       
   485               ( captureHotkey == EHotkeyShiftMenu &&
       
   486                 aEvent.Type()==EEventKeyDown && aEvent.Key()->iScanCode==EStdKeyApplication0 &&
       
   487                 aEvent.Key()->iModifiers & EModifierShift)
       
   488             ||
       
   489               ( captureHotkey == EHotkeySendKey &&
       
   490                 aEvent.Type()==EEventKeyDown && aEvent.Key()->iScanCode==EStdKeyYes )
       
   491             ||
       
   492               ( captureHotkey == EHotkeyPowerKey &&
       
   493                 aEvent.Type()==EEventKeyDown && aEvent.Key()->iScanCode==EStdKeyDevice2 )
       
   494             ||
       
   495               ( captureHotkey == EHotkeySideKey &&
       
   496                 aEvent.Type()==EEventKeyDown && aEvent.Key()->iScanCode==EStdKeyDevice6 )
       
   497             ||
       
   498               ( captureHotkey == EHotkeyCameraKey1 &&
       
   499                 aEvent.Type()==EEventKeyDown && aEvent.Key()->iScanCode==EStdKeyDevice7 )
       
   500             ||
       
   501               ( captureHotkey == EHotkeyCameraKey2 &&
       
   502                 aEvent.Type()==EEventKeyDown && aEvent.Key()->iScanCode==EStdKeyDevice7 )
       
   503             ||
       
   504               ( captureHotkey == EHotkeyPOC &&
       
   505                 aEvent.Type()==EEventKeyDown && aEvent.Key()->iScanCode==EStdKeyApplication1A )
       
   506             )
       
   507 		{
       
   508 		
       
   509 		// check if already capturing images in sequence
       
   510 		if ( iCapturingInProgress && !iStopCapturing && iNumberOfTakenShots!=0 && iGrabSettings.iCaptureMode == ECaptureModeSequantialCapture )
       
   511             {
       
   512             // asking to stop capturing
       
   513             iStopCapturing = ETrue;
       
   514             
       
   515             // cancel the active object, this will cancel any timer delays and ICL stuff
       
   516             Cancel();
       
   517             
       
   518             // set status
       
   519             iState = ECancelCapturing; 
       
   520             
       
   521             // jump smoothly to RunL()
       
   522             iTimer.After(iStatus, 50);
       
   523             SetActive(); 
       
   524 
       
   525        		// do not continue the event loop in HandleWsEventL for these events
       
   526            	continueEventLoop = EFalse;
       
   527             }
       
   528 
       
   529 		// check if already capturing video
       
   530 		else if ( iCapturingInProgress && !iStopCapturing && iGrabSettings.iCaptureMode == ECaptureModeVideoCapture )
       
   531             {
       
   532             // asking to stop capturing
       
   533             iStopCapturing = ETrue;
       
   534             
       
   535             // cancel the active object, this will cancel any timer delays and ICL stuff
       
   536             Cancel();
       
   537 
       
   538             // set status
       
   539             iState = ECancelVideoCapturing;
       
   540             
       
   541             // jump smoothly to RunL()
       
   542             iTimer.After(iStatus, 50);
       
   543             SetActive(); 
       
   544 
       
   545        		// do not continue the event loop in HandleWsEventL for these events
       
   546            	continueEventLoop = EFalse;
       
   547             }        
       
   548         else if (!iCapturingInProgress && (iGrabSettings.iCaptureMode == ECaptureModeSingleCapture || iGrabSettings.iCaptureMode == ECaptureModeSequantialCapture ))
       
   549             {
       
   550             // not capturing anything, so start doing that
       
   551             iCapturingInProgress = ETrue;    
       
   552 
       
   553 			// take a screen shot and save it
       
   554     	    TakeScreenShotAndSaveL();                
       
   555 
       
   556        		// do not continue the event loop in HandleWsEventL for these events
       
   557            	continueEventLoop = EFalse;
       
   558             }
       
   559         
       
   560         else if (!iCapturingInProgress && iGrabSettings.iCaptureMode == ECaptureModeVideoCapture )
       
   561             {
       
   562             // not capturing anything, so start doing that
       
   563             iCapturingInProgress = ETrue;
       
   564             
       
   565             // clean temporary files
       
   566             TRAP_IGNORE( CleanTemporaryFilesL() );
       
   567             
       
   568             // get initial dimensions for the video
       
   569             CWsScreenDevice* screenDevice = new(ELeave) CWsScreenDevice ( CEikonEnv::Static()->WsSession() );
       
   570             CleanupStack::PushL(screenDevice);
       
   571             User::LeaveIfError( screenDevice->Construct( iEnv->WsSession().GetFocusScreen() ) );
       
   572             iVideoDimensions = screenDevice->SizeInPixels();
       
   573             iPreviousFrameScreenDimension = screenDevice->SizeInPixels();
       
   574             CleanupStack::PopAndDestroy(); // screenDevice
       
   575 
       
   576 			// capture the first frame
       
   577 			CaptureFrameForVideoL();              
       
   578 
       
   579        		// do not continue the event loop in HandleWsEventL for these events
       
   580            	continueEventLoop = EFalse;
       
   581             }
       
   582 
       
   583 		}
       
   584 
       
   585     // catch other event types as well so that we can ignore them
       
   586     else if (
       
   587               ( captureHotkey == EHotkeyShiftStar &&
       
   588                 aEvent.Key()->iScanCode=='*' &&
       
   589                 aEvent.Key()->iModifiers & EModifierShift)
       
   590             ||
       
   591               ( captureHotkey == EHotkeyHashStar &&
       
   592                 aEvent.Key()->iScanCode=='*' &&
       
   593                 iHashKeyDown)
       
   594             ||
       
   595               ( captureHotkey == EHotkeyShiftMenu &&
       
   596                 aEvent.Key()->iScanCode==EStdKeyApplication0 &&
       
   597                 aEvent.Key()->iModifiers & EModifierShift)
       
   598             ||
       
   599               ( captureHotkey == EHotkeySendKey &&
       
   600                 aEvent.Key()->iScanCode==EStdKeyYes )
       
   601             ||
       
   602               ( captureHotkey == EHotkeyPowerKey &&
       
   603                 aEvent.Key()->iScanCode==EStdKeyDevice2 )
       
   604             ||
       
   605               ( captureHotkey == EHotkeySideKey &&
       
   606                 aEvent.Key()->iScanCode==EStdKeyDevice6 )
       
   607             ||
       
   608               ( captureHotkey == EHotkeyCameraKey1 &&
       
   609                 aEvent.Key()->iScanCode==EStdKeyDevice7 )
       
   610             ||
       
   611               ( captureHotkey == EHotkeyCameraKey2 &&
       
   612                 aEvent.Key()->iScanCode==EStdKeyApplication1A )
       
   613             ||
       
   614     		  ( captureHotkey == EHotkeyPOC &&
       
   615                 aEvent.Key()->iScanCode==EStdKeyApplication1 )
       
   616             )
       
   617 		{
       
   618 		// do not continue the event loop in HandleWsEventL for these events
       
   619         continueEventLoop = EFalse;
       
   620 		}
       
   621 
       
   622     return continueEventLoop;
       
   623     }
       
   624 
       
   625 // ---------------------------------------------------------------------------
       
   626 
       
   627 void CScreenGrabberModel::TakeScreenShotAndSaveL()
       
   628     {
       
   629 	// take a screen shot
       
   630 	CWsScreenDevice* screenDevice = new( ELeave ) CWsScreenDevice( CEikonEnv::Static()->WsSession() );
       
   631 	CleanupStack::PushL( screenDevice );
       
   632 	User::LeaveIfError( screenDevice->Construct( iEnv->WsSession().GetFocusScreen() ) );
       
   633 	User::LeaveIfError( iPreviouslyCapturedBitmap->Create(screenDevice->SizeInPixels(), screenDevice->DisplayMode()) );
       
   634 	User::LeaveIfError( screenDevice->CopyScreenToBitmap(iPreviouslyCapturedBitmap) );
       
   635 	CleanupStack::PopAndDestroy(); // screenDevice
       
   636 
       
   637     // play a beep sound for each shot when capturing in sequantial mode
       
   638     if (iGrabSettings.iCaptureMode == ECaptureModeSequantialCapture)
       
   639         PlayBeepSound();
       
   640 
       
   641 
       
   642     // get memory in use & image format of the screen capture
       
   643 #ifdef SCREENGRABBER_MULTIDRIVE_SUPPORT            
       
   644     TDriveNumber memoryInUse(EDriveC);
       
   645 #else
       
   646     TInt memoryInUse(0);
       
   647 #endif
       
   648     TInt imageFormat(0);
       
   649     TFileName fileName;
       
   650     
       
   651     if (iGrabSettings.iCaptureMode == ECaptureModeSingleCapture)
       
   652         {
       
   653 #ifdef SCREENGRABBER_MULTIDRIVE_SUPPORT            
       
   654         memoryInUse = iGrabSettings.iSingleCaptureMemoryInUseMultiDrive;
       
   655 #else
       
   656         memoryInUse = iGrabSettings.iSingleCaptureMemoryInUse;
       
   657 #endif
       
   658         imageFormat = iGrabSettings.iSingleCaptureImageFormat;
       
   659         fileName = iGrabSettings.iSingleCaptureFileName;
       
   660         }
       
   661     else if (iGrabSettings.iCaptureMode == ECaptureModeSequantialCapture)
       
   662         {
       
   663 #ifdef SCREENGRABBER_MULTIDRIVE_SUPPORT            
       
   664         memoryInUse = iGrabSettings.iSequantialCaptureMemoryInUseMultiDrive;
       
   665 #else
       
   666         memoryInUse = iGrabSettings.iSequantialCaptureMemoryInUse;
       
   667 #endif
       
   668 
       
   669         imageFormat = iGrabSettings.iSequantialCaptureImageFormat;
       
   670         fileName = iGrabSettings.iSequantialCaptureFileName;
       
   671         }
       
   672     else
       
   673         User::Panic(_L("Wrong mode"), 30);  
       
   674 
       
   675 
       
   676     // init the path for saving the file
       
   677 #ifdef SCREENGRABBER_MULTIDRIVE_SUPPORT
       
   678     if (PathInfo::GetRootPath(iSaveFileName, memoryInUse) != KErrNone || !DriveOK(memoryInUse))
       
   679         iSaveFileName.Copy( PathInfo::PhoneMemoryRootPath() );
       
   680 #else
       
   681     if (memoryInUse == CAknMemorySelectionSettingPage::EPhoneMemory || !MemoryCardOK())
       
   682         iSaveFileName.Copy( PathInfo::PhoneMemoryRootPath() );
       
   683     else
       
   684         iSaveFileName.Copy( PathInfo::MemoryCardRootPath() );
       
   685 #endif
       
   686 
       
   687     iSaveFileName.Append( PathInfo::ImagesPath() );
       
   688     iSaveFileName.Append( KScreenShotsSubDirectory );
       
   689     
       
   690     
       
   691     // a quick check that filename is valid
       
   692     if (fileName.Length() > 0 && fileName.Length() <= 255) 
       
   693         iSaveFileName.Append( fileName );
       
   694     else
       
   695         iSaveFileName.Append( KDefaultImageFileName );
       
   696 
       
   697     iSaveFileName.Append( _L(".") );
       
   698 
       
   699 
       
   700     // reset the encoder
       
   701     if (iImageEncoder)
       
   702         {
       
   703 	    delete iImageEncoder;
       
   704         iImageEncoder = NULL;
       
   705         }
       
   706         
       
   707     
       
   708     switch (imageFormat)
       
   709         {
       
   710         case EImageFormatPNG:
       
   711             {
       
   712             // set filename
       
   713             iSaveFileName.Append(_L("png"));
       
   714             CApaApplication::GenerateFileName(iEnv->FsSession(), iSaveFileName );  // unique filename
       
   715 
       
   716             // init & convert
       
   717             iImageEncoder = CImageEncoder::FileNewL(iEnv->FsSession(), iSaveFileName, CImageEncoder::EOptionAlwaysThread, KImageTypePNGUid);
       
   718             iImageEncoder->Convert( &iStatus, *iPreviouslyCapturedBitmap );
       
   719             }
       
   720             break;
       
   721         
       
   722         case EImageFormatJPGHQ:
       
   723         case EImageFormatJPGLQ:
       
   724             {
       
   725             // reset frameimagedata
       
   726             if (iFrameImageData)
       
   727                 {
       
   728                 delete iFrameImageData;
       
   729                 iFrameImageData = NULL;
       
   730                 }
       
   731             
       
   732             // set filename
       
   733             iSaveFileName.Append(_L("jpg"));
       
   734             CApaApplication::GenerateFileName(iEnv->FsSession(), iSaveFileName );  // unique filename
       
   735 
       
   736             // init 
       
   737             iImageEncoder = CImageEncoder::FileNewL(iEnv->FsSession(), iSaveFileName, CImageEncoder::EOptionAlwaysThread, KImageTypeJPGUid);
       
   738 
       
   739             // JPEG properties
       
   740             TJpegImageData* imageData = new(ELeave) TJpegImageData;
       
   741             imageData->iSampleScheme = TJpegImageData::EColor444;
       
   742             imageData->iQualityFactor = (imageFormat==EImageFormatJPGHQ) ? HIGH_QUALITY_JPEG : LOW_QUALITY_JPEG;
       
   743             iFrameImageData = CFrameImageData::NewL();
       
   744             User::LeaveIfError(iFrameImageData->AppendImageData(imageData));  //ownership of imageData is transferred
       
   745 
       
   746             // convert
       
   747             iImageEncoder->Convert( &iStatus, *iPreviouslyCapturedBitmap, iFrameImageData );
       
   748             }
       
   749             break;
       
   750         
       
   751         case EImageFormatBMP:
       
   752             {
       
   753             // set filename
       
   754             iSaveFileName.Append(_L("bmp"));
       
   755             CApaApplication::GenerateFileName(iEnv->FsSession(), iSaveFileName );  // unique filename
       
   756 
       
   757             // init & convert
       
   758             iImageEncoder = CImageEncoder::FileNewL(iEnv->FsSession(), iSaveFileName, CImageEncoder::EOptionAlwaysThread, KImageTypeBMPUid);
       
   759             iImageEncoder->Convert( &iStatus, *iPreviouslyCapturedBitmap );
       
   760             }
       
   761             break;
       
   762 
       
   763         case EImageFormatGIF:
       
   764             {
       
   765             // set filename
       
   766             iSaveFileName.Append(_L("gif"));
       
   767             CApaApplication::GenerateFileName(iEnv->FsSession(), iSaveFileName );  // unique filename
       
   768 
       
   769             // init & convert
       
   770             iImageEncoder = CImageEncoder::FileNewL(iEnv->FsSession(), iSaveFileName, CImageEncoder::EOptionAlwaysThread, KImageTypeGIFUid);
       
   771             iImageEncoder->Convert( &iStatus, *iPreviouslyCapturedBitmap );
       
   772             }
       
   773             break;
       
   774             
       
   775         case EImageFormatMBM:
       
   776             {
       
   777             // set filename
       
   778             iSaveFileName.Append(_L("mbm"));
       
   779             CApaApplication::GenerateFileName(iEnv->FsSession(), iSaveFileName );  // unique filename
       
   780 
       
   781             // init & convert
       
   782             iImageEncoder = CImageEncoder::FileNewL(iEnv->FsSession(), iSaveFileName, CImageEncoder::EOptionAlwaysThread, KImageTypeMBMUid);
       
   783             iImageEncoder->Convert( &iStatus, *iPreviouslyCapturedBitmap );
       
   784             }
       
   785             break;
       
   786             
       
   787         default:
       
   788             {
       
   789             User::Panic(_L("Invalid Img Type"), 20);
       
   790             }
       
   791         }
       
   792 
       
   793     // set the state of the active object
       
   794 	iState = EEncodingImage;
       
   795 
       
   796     // indicate an outstanding request
       
   797     SetActive();
       
   798     }
       
   799     
       
   800 // ---------------------------------------------------------------------------
       
   801 
       
   802 void CScreenGrabberModel::CaptureFrameForVideoL()
       
   803     {
       
   804     // record time
       
   805     TTime timeNow;
       
   806     timeNow.HomeTime();
       
   807     
       
   808     // take a screen shot	
       
   809  	CFbsBitmap* currentCapturedBitmap = new(ELeave) CFbsBitmap;
       
   810  	CleanupStack::PushL(currentCapturedBitmap);
       
   811 
       
   812 	CWsScreenDevice* screenDevice = new(ELeave) CWsScreenDevice( CEikonEnv::Static()->WsSession() );
       
   813 	CleanupStack::PushL( screenDevice );
       
   814 	User::LeaveIfError( screenDevice->Construct( iEnv->WsSession().GetFocusScreen() ) );
       
   815 	
       
   816     TSize currentScreenSize = screenDevice->SizeInPixels();
       
   817 
       
   818 	User::LeaveIfError( currentCapturedBitmap->Create(currentScreenSize, EColor256) );
       
   819 	User::LeaveIfError( screenDevice->CopyScreenToBitmap(currentCapturedBitmap) );
       
   820 	CleanupStack::PopAndDestroy(); // screenDevice
       
   821 
       
   822 	// grow video's dimensions if the size has changed
       
   823 	if (currentScreenSize.iWidth > iVideoDimensions.iWidth)
       
   824 	    {
       
   825 	    iVideoDimensions.iWidth = currentScreenSize.iWidth;
       
   826 	    }
       
   827 	if (currentScreenSize.iHeight > iVideoDimensions.iHeight)
       
   828 	    {
       
   829 	    iVideoDimensions.iHeight = currentScreenSize.iHeight;
       
   830 	    }
       
   831 
       
   832     TInt64 currentDelay(0);
       
   833  
       
   834     // play a beep sound every 30th frame
       
   835     if (iCurrentFrameNumber%30 == 0)
       
   836         PlayBeepSound();
       
   837 
       
   838     // create a new frame
       
   839     TVideoFrame frame;
       
   840     frame.iDelay = 500; // use default delay 5.00 secs
       
   841     
       
   842     // get info of the RAM drive
       
   843     TDriveNumber ramDrive = EDriveD;
       
   844     TVolumeInfo ramDriveInfo;
       
   845     iEnv->FsSession().Volume(ramDriveInfo, ramDrive);
       
   846     
       
   847     // init the directory for saving the file, preferably use ram drive if there is enough disk space, otherwise use always C drive
       
   848     TFileName tempDirectory;
       
   849     TFileName sessionPath;
       
   850     
       
   851     if (ramDriveInfo.iFree > (iVideoDimensions.iWidth*iVideoDimensions.iHeight+50000))
       
   852         sessionPath.Copy( _L("D:") );
       
   853     else
       
   854         sessionPath.Copy( _L("C:") );
       
   855     
       
   856     sessionPath.Append(KSGTemporaryDirectory);
       
   857     tempDirectory.Copy(KSGTemporaryDirectory);
       
   858     
       
   859     iEnv->FsSession().MkDirAll(sessionPath);
       
   860     iEnv->FsSession().SetSessionPath(sessionPath);
       
   861 
       
   862     // create a temp file, path to the bitmap is saved automatically to frame.iFileStorePath
       
   863     RFile file;
       
   864     User::LeaveIfError( file.Temp(iEnv->FsSession(), tempDirectory, frame.iFileStorePath, EFileWrite) );
       
   865     RFileWriteStream writeStream(file);
       
   866     
       
   867     TBool ignoreFrame(EFalse);
       
   868     
       
   869     // check if is this the first frame
       
   870     if (iCurrentFrameNumber == 0)
       
   871         {
       
   872         // first frame is always the full one
       
   873         frame.iWidth = currentScreenSize.iWidth;    
       
   874         frame.iHeight = currentScreenSize.iHeight;  
       
   875         frame.iXPos = 0;
       
   876         frame.iYPos = 0;
       
   877         frame.iEnableTransparency = EFalse;
       
   878         frame.iFillsWholeScreen = ETrue;
       
   879         
       
   880         currentCapturedBitmap->ExternalizeL(writeStream);  
       
   881 
       
   882         }
       
   883     
       
   884     else
       
   885         {
       
   886         // next frame is a difference between the previous one
       
   887         currentDelay = timeNow.MicroSecondsFrom(iPreviousFrameTaken).Int64();
       
   888         
       
   889         // get reference to previos frame
       
   890         TVideoFrame& prevFrame = iVideoFrameArray->At(iVideoFrameArray->Count()-1);
       
   891         
       
   892         
       
   893         // check if video dimensions have changed
       
   894         if (currentScreenSize.iWidth != iPreviousFrameScreenDimension.iWidth
       
   895             || currentScreenSize.iHeight != iPreviousFrameScreenDimension.iHeight)
       
   896             {
       
   897             // dimensions have changed -> save a full bitmap
       
   898             frame.iWidth = currentScreenSize.iWidth;    
       
   899             frame.iHeight = currentScreenSize.iHeight;  
       
   900             frame.iXPos = 0;
       
   901             frame.iYPos = 0;
       
   902             frame.iEnableTransparency = EFalse;
       
   903             frame.iFillsWholeScreen = ETrue;
       
   904             
       
   905             currentCapturedBitmap->ExternalizeL(writeStream);            
       
   906 
       
   907             // update the previous frame to contain the new delay value
       
   908             prevFrame.iDelay = TUint( (double) currentDelay / 10000 );
       
   909             }
       
   910 
       
   911         else
       
   912             {
       
   913             // compare the bitmaps
       
   914             HBufC8* curImgScanLineBuf = HBufC8::NewLC(currentScreenSize.iWidth*3);
       
   915             TPtr8 curImgScanLinePtr = curImgScanLineBuf->Des();
       
   916             HBufC8* prevImgScanLineBuf = HBufC8::NewLC(currentScreenSize.iWidth*3);
       
   917             TPtr8 prevImgScanLinePtr = prevImgScanLineBuf->Des();
       
   918             
       
   919             TPoint pt(0,0);
       
   920             TBool differenceFound(EFalse);
       
   921             TPoint leftTopDifferencePoint(0,0);
       
   922             TPoint rightBottomDifferencePoint(currentScreenSize.iWidth,currentScreenSize.iHeight);
       
   923             
       
   924             // scan the image from top to bottom
       
   925             for (TInt i=0; i<currentScreenSize.iHeight; i++)
       
   926                 {
       
   927                 pt.iY = i;
       
   928                 
       
   929                 currentCapturedBitmap->GetScanLine(curImgScanLinePtr, pt, currentScreenSize.iWidth, EColor256);
       
   930                 iPreviouslyCapturedBitmap->GetScanLine(prevImgScanLinePtr, pt, currentScreenSize.iWidth, EColor256);
       
   931                 
       
   932                 if (curImgScanLinePtr != prevImgScanLinePtr)
       
   933                     {
       
   934                     differenceFound = ETrue;
       
   935                     
       
   936                     // get the y-coordinate
       
   937                     leftTopDifferencePoint.iY = i;
       
   938 
       
   939                     break;    
       
   940                     }
       
   941                 }
       
   942                 
       
   943             if (differenceFound)
       
   944                 {
       
   945                 // now we know that there is some difference between those two captured frames,
       
   946                 // get the bottom value by scaning from bottom to top
       
   947                 for (TInt i=currentScreenSize.iHeight-1; i>=0; i--)
       
   948                     {
       
   949                     pt.iY = i;
       
   950                     
       
   951                     currentCapturedBitmap->GetScanLine(curImgScanLinePtr, pt, currentScreenSize.iWidth, EColor256);
       
   952                     iPreviouslyCapturedBitmap->GetScanLine(prevImgScanLinePtr, pt, currentScreenSize.iWidth, EColor256);
       
   953                     
       
   954                     if (curImgScanLinePtr != prevImgScanLinePtr)
       
   955                         {
       
   956                         // get the y-coordinate
       
   957                         rightBottomDifferencePoint.iY = i+1;
       
   958 
       
   959                         break;    
       
   960                         }
       
   961                     }
       
   962                     
       
   963                 // check that the height of the cropped image will be at least 1
       
   964                 if (rightBottomDifferencePoint.iY <= leftTopDifferencePoint.iY)
       
   965                     rightBottomDifferencePoint.iY = leftTopDifferencePoint.iY+1;  
       
   966                 
       
   967                       
       
   968                 // get also the x-coordinates by scanning vertical scan lines
       
   969                 HBufC8* curImgVerticalScanLineBuf = HBufC8::NewLC(currentScreenSize.iHeight*3);
       
   970                 TPtr8 curImgVerticalScanLinePtr = curImgScanLineBuf->Des();
       
   971                 HBufC8* prevImgVerticalScanLineBuf = HBufC8::NewLC(currentScreenSize.iHeight*3);
       
   972                 TPtr8 prevImgVerticalScanLinePtr = prevImgScanLineBuf->Des();
       
   973                         
       
   974                 // first scan by from left to right
       
   975                 for (TInt i=0; i<currentScreenSize.iWidth; i++)
       
   976                     {
       
   977                     currentCapturedBitmap->GetVerticalScanLine(curImgVerticalScanLinePtr, i, EColor256);
       
   978                     iPreviouslyCapturedBitmap->GetVerticalScanLine(prevImgVerticalScanLinePtr, i, EColor256);
       
   979                     
       
   980                     if (curImgVerticalScanLinePtr != prevImgVerticalScanLinePtr)
       
   981                         {
       
   982                         leftTopDifferencePoint.iX = i;
       
   983                         break;
       
   984                         }
       
   985                     }
       
   986 
       
   987                 // finally scan from right to left
       
   988                 for (TInt i=currentScreenSize.iWidth-1; i>=0; i--)
       
   989                     {
       
   990                     currentCapturedBitmap->GetVerticalScanLine(curImgVerticalScanLinePtr, i, EColor256);
       
   991                     iPreviouslyCapturedBitmap->GetVerticalScanLine(prevImgVerticalScanLinePtr, i, EColor256);
       
   992                     
       
   993                     if (curImgVerticalScanLinePtr != prevImgVerticalScanLinePtr)
       
   994                         {
       
   995                         rightBottomDifferencePoint.iX = i+1;
       
   996                         break;
       
   997                         }
       
   998                     }
       
   999                     
       
  1000                 CleanupStack::PopAndDestroy(2); //curImgVerticalScanLineBuf,prevImgVerticalScanLineBuf               
       
  1001 
       
  1002                 
       
  1003                 // check that the width of the cropped image will be at least 1
       
  1004                 if (rightBottomDifferencePoint.iX <= leftTopDifferencePoint.iX)
       
  1005                     rightBottomDifferencePoint.iX = leftTopDifferencePoint.iX+1;
       
  1006                    
       
  1007                 
       
  1008                 // record dimensions and position of the image           
       
  1009                 frame.iWidth = rightBottomDifferencePoint.iX - leftTopDifferencePoint.iX;    
       
  1010                 frame.iHeight = rightBottomDifferencePoint.iY - leftTopDifferencePoint.iY;  
       
  1011                 frame.iXPos = leftTopDifferencePoint.iX;
       
  1012                 frame.iYPos = leftTopDifferencePoint.iY;
       
  1013                 frame.iEnableTransparency = ETrue;
       
  1014                 frame.iFillsWholeScreen = EFalse;
       
  1015             
       
  1016             
       
  1017                 // take a copy of the current frame
       
  1018              	CFbsBitmap* workingBitmap = new(ELeave) CFbsBitmap;
       
  1019              	CleanupStack::PushL(workingBitmap);
       
  1020                 User::LeaveIfError( workingBitmap->Create(currentScreenSize, EColor256) );
       
  1021 
       
  1022                 HBufC8* tempScanLineBuf = HBufC8::NewLC(currentScreenSize.iWidth*3);
       
  1023                 TPtr8 tempScanLinePtr = tempScanLineBuf->Des();
       
  1024                 
       
  1025                 for (TInt i=0; i<currentScreenSize.iHeight; i++)
       
  1026                     {
       
  1027                     pt.iY = i;
       
  1028                     currentCapturedBitmap->GetScanLine(tempScanLinePtr, pt, currentScreenSize.iWidth, EColor256);
       
  1029                     workingBitmap->SetScanLine(tempScanLinePtr, i);
       
  1030                     }
       
  1031                     
       
  1032                 CleanupStack::PopAndDestroy(); //tempScanLineBuf
       
  1033                 
       
  1034                 
       
  1035                 // mark the non-changed areas with transparency color
       
  1036                 TUint8* curPtr = NULL;
       
  1037                 TUint8* prevPtr = NULL;
       
  1038                 for (TInt i=frame.iYPos; i<frame.iYPos+frame.iHeight; i++)
       
  1039                     {
       
  1040                     pt.iY = i;
       
  1041                     
       
  1042                     workingBitmap->GetScanLine(curImgScanLinePtr, pt, currentScreenSize.iWidth, EColor256);
       
  1043                     iPreviouslyCapturedBitmap->GetScanLine(prevImgScanLinePtr, pt, currentScreenSize.iWidth, EColor256);
       
  1044                     
       
  1045                     // check single pixels in the scanline
       
  1046                     for (TInt j=frame.iXPos; j<frame.iXPos+frame.iWidth; j++)
       
  1047                         {
       
  1048                         curPtr = &curImgScanLinePtr[j];
       
  1049                         prevPtr = &prevImgScanLinePtr[j];
       
  1050                         
       
  1051                         // check that our transparency index isn't already in use
       
  1052                         if (curPtr[0] == TRANSPARENCY_INDEX)
       
  1053                             curPtr[0] = TRANSPARENCY_ALTERNATIVE_INDEX;
       
  1054                         
       
  1055                         // replace with transparency index if there is no change compared to the previous frame
       
  1056                         if (curPtr[0] == prevPtr[0])
       
  1057                             curPtr[0] = TRANSPARENCY_INDEX;
       
  1058                         }
       
  1059                         
       
  1060                     // set new scanline    
       
  1061                     workingBitmap->SetScanLine(curImgScanLinePtr, i);
       
  1062                     }
       
  1063 
       
  1064 
       
  1065                 // externalize the bitmap
       
  1066                 TRect changedRect(leftTopDifferencePoint, rightBottomDifferencePoint);
       
  1067                 workingBitmap->ExternalizeRectangleL(writeStream, changedRect);
       
  1068                 
       
  1069                 CleanupStack::PopAndDestroy(); //workingBitmap
       
  1070  
       
  1071                 // update the previous frame to contain the new delay value
       
  1072                 prevFrame.iDelay = TUint( (double) currentDelay / 10000 );
       
  1073                 }
       
  1074 
       
  1075             else
       
  1076                 {
       
  1077                 // frames are identical, we can just ignore this one
       
  1078                 ignoreFrame = ETrue;     
       
  1079                 }
       
  1080             
       
  1081             CleanupStack::PopAndDestroy(2); //curImgScanLineBuf,prevImgScanLineBuf
       
  1082 
       
  1083             } // if (videoDimensionsHaveChanged)
       
  1084 
       
  1085         } //if (iCurrentFrameNumber == 0)
       
  1086             
       
  1087     // close the stream
       
  1088     writeStream.CommitL();
       
  1089     writeStream.Close();
       
  1090     file.Close();
       
  1091     
       
  1092 
       
  1093     if (ignoreFrame)
       
  1094         {
       
  1095         // delete the temp file since we don't need that
       
  1096         iEnv->FsSession().Delete(frame.iFileStorePath);
       
  1097         }
       
  1098     else
       
  1099         {
       
  1100         // remember for the next frame when this frame was taken
       
  1101         iPreviousFrameTaken = timeNow;
       
  1102 
       
  1103         // take a copy of currentCapturedBitmap to iPreviouslyCapturedBitmap
       
  1104         User::LeaveIfError( iPreviouslyCapturedBitmap->Create(iVideoDimensions, EColor256) );
       
  1105 
       
  1106         TPoint pt(0,0);
       
  1107         HBufC8* tempScanLineBuf = HBufC8::NewMaxLC(iVideoDimensions.iWidth);
       
  1108         TPtr8 tempScanLinePtr = tempScanLineBuf->Des();
       
  1109         
       
  1110         for (TInt i=0; i<iVideoDimensions.iHeight; i++)
       
  1111             {
       
  1112             pt.iY = i;
       
  1113             currentCapturedBitmap->GetScanLine(tempScanLinePtr, pt, iVideoDimensions.iWidth, EColor256);
       
  1114             iPreviouslyCapturedBitmap->SetScanLine(tempScanLinePtr, i);
       
  1115             }
       
  1116             
       
  1117         CleanupStack::PopAndDestroy(); //tempScanLineBuf
       
  1118         
       
  1119         // append frame information to the array
       
  1120         iVideoFrameArray->AppendL(frame);
       
  1121         
       
  1122         // remember screen size
       
  1123         iPreviousFrameScreenDimension = currentScreenSize;
       
  1124         }    
       
  1125 
       
  1126     
       
  1127     CleanupStack::PopAndDestroy(); //currentCapturedBitmap
       
  1128     
       
  1129 
       
  1130     // set the state of the active object
       
  1131 	iState = ENextVideoFrame;
       
  1132 	
       
  1133     // check time spent on the work above (probably this is not so important)
       
  1134 	TTime timeNow2;
       
  1135     timeNow2.HomeTime();
       
  1136     TInt64 handlingDelay = timeNow2.MicroSecondsFrom(timeNow).Int64();
       
  1137     
       
  1138 	// calculate delay till next frame
       
  1139 	TUint idealDelay = VIDEO_CAPTURE_DELAY*1000;
       
  1140 	TInt usedDelay; 
       
  1141 	if (currentDelay > idealDelay)
       
  1142 	    usedDelay = idealDelay - (currentDelay - idealDelay) - handlingDelay;
       
  1143 	else
       
  1144 	    usedDelay = idealDelay - handlingDelay;
       
  1145 	
       
  1146 	// check that the delay is atleast minimum delay anyway
       
  1147 	if (usedDelay < VIDEO_CAPTURE_MINIMUM_DELAY*1000)
       
  1148 	    usedDelay = VIDEO_CAPTURE_MINIMUM_DELAY*1000;
       
  1149 	
       
  1150 	iTimer.After(iStatus, usedDelay);
       
  1151 
       
  1152     // indicate an outstanding request
       
  1153     SetActive();
       
  1154     }
       
  1155     
       
  1156 // ---------------------------------------------------------------------------
       
  1157     
       
  1158 void CScreenGrabberModel::RunL()
       
  1159     {
       
  1160 	switch (iState) 
       
  1161 		{
       
  1162         // encoding of the image is now finished
       
  1163 		case EEncodingImage: 
       
  1164 			{
       
  1165             if (iGrabSettings.iCaptureMode == ECaptureModeSingleCapture)
       
  1166                 {
       
  1167                 // single shot done
       
  1168                 CapturingFinishedL( iStatus.Int() );
       
  1169                 }
       
  1170 
       
  1171             else if (iGrabSettings.iCaptureMode == ECaptureModeSequantialCapture)
       
  1172                 {
       
  1173                 // increase the counter    
       
  1174                 iNumberOfTakenShots++;
       
  1175                 
       
  1176                 // check if we can take more shots or just finish
       
  1177                 if (!iStopCapturing && iStatus.Int()==KErrNone)
       
  1178                     {
       
  1179                     // notify the new file to Media Gallery
       
  1180                     UpdateFileToGallery(iSaveFileName);
       
  1181         
       
  1182                     // some delay before the next shot can be taken    
       
  1183                     iState = ESequenceDelay;
       
  1184                     
       
  1185                     // some checking that the value of delay is valid
       
  1186                     TInt delay(iGrabSettings.iSequantialCaptureDelay); //ms
       
  1187                     if (delay<0 && delay > 999999)
       
  1188                         delay = DEFAULT_SEQ_CAPTURE_DELAY_MS;
       
  1189                       
       
  1190                     iTimer.After(iStatus, delay*1000);
       
  1191                     SetActive();  
       
  1192                     }
       
  1193                 else
       
  1194                     {
       
  1195                     // finished
       
  1196                     CapturingFinishedL( iStatus.Int() );
       
  1197                     }                       
       
  1198                }
       
  1199             else
       
  1200                 User::Panic(_L("Wrong mode"), 32);            
       
  1201 
       
  1202             break;
       
  1203 			}
       
  1204 
       
  1205         // delay finished, ready to take the next shot
       
  1206 		case ESequenceDelay: 
       
  1207 			{
       
  1208 			TakeScreenShotAndSaveL();
       
  1209 
       
  1210             break;
       
  1211 			}
       
  1212 			
       
  1213 		// asked to cancel capturing	
       
  1214 		case ECancelCapturing:
       
  1215 			{
       
  1216             // finished
       
  1217             CapturingFinishedL( iStatus.Int() );
       
  1218 
       
  1219             break;
       
  1220 			}
       
  1221 			
       
  1222 		case ENextVideoFrame:
       
  1223 		    {
       
  1224 		    // increase the counter
       
  1225 		    iCurrentFrameNumber++;
       
  1226 		    
       
  1227             // check if we can take more frames or just finish
       
  1228             if (!iStopCapturing && iStatus.Int()==KErrNone)
       
  1229                 {
       
  1230                 // take next frame
       
  1231                 CaptureFrameForVideoL();
       
  1232                 }
       
  1233             else
       
  1234                 {
       
  1235                 // finished, save video
       
  1236                 SaveVideoL( iStatus.Int() );
       
  1237                 } 		        
       
  1238 		    }
       
  1239 		    break;
       
  1240 
       
  1241 		case ECancelVideoCapturing:
       
  1242 		    {
       
  1243             // finished, save video
       
  1244             SaveVideoL( iStatus.Int() ); 		        
       
  1245 		    }
       
  1246 		    break;
       
  1247 		    			        
       
  1248         // delay of the query is now finished
       
  1249         case EQueryDelay:
       
  1250 			{
       
  1251     		iState = EIdle;
       
  1252 
       
  1253             // now remove the query
       
  1254             iSavedQuery->Cancel();
       
  1255 
       
  1256             // capturing can now be restarted
       
  1257             iCapturingInProgress = EFalse;
       
  1258             iStopCapturing = EFalse;
       
  1259 
       
  1260             break;
       
  1261 			}
       
  1262 
       
  1263 		default:
       
  1264 			{
       
  1265             break;
       
  1266 			}
       
  1267         }
       
  1268     }
       
  1269 
       
  1270 // ---------------------------------------------------------------------------
       
  1271 
       
  1272 void CScreenGrabberModel::SaveVideoL(TInt aErr)
       
  1273     {
       
  1274     if (aErr)
       
  1275         CapturingFinishedL(aErr);   
       
  1276    
       
  1277     else if (iGrabSettings.iVideoCaptureVideoFormat == EVideoFormatAnimatedGIF)
       
  1278         {
       
  1279         TInt err(KErrNone);
       
  1280         
       
  1281         // init the path for saving the file
       
  1282 
       
  1283 #ifdef SCREENGRABBER_MULTIDRIVE_SUPPORT
       
  1284         if (PathInfo::GetRootPath(iSaveFileName, iGrabSettings.iVideoCaptureMemoryInUseMultiDrive) != KErrNone || !DriveOK(iGrabSettings.iVideoCaptureMemoryInUseMultiDrive))
       
  1285             iSaveFileName.Copy( PathInfo::PhoneMemoryRootPath() );
       
  1286 #else
       
  1287         if (iGrabSettings.iVideoCaptureMemoryInUse == CAknMemorySelectionSettingPage::EPhoneMemory || !MemoryCardOK())
       
  1288             iSaveFileName.Copy( PathInfo::PhoneMemoryRootPath() );
       
  1289         else
       
  1290             iSaveFileName.Copy( PathInfo::MemoryCardRootPath() );
       
  1291 #endif
       
  1292 
       
  1293         iSaveFileName.Append( PathInfo::ImagesPath() );     // animated gif is actually an image, not a video
       
  1294         iSaveFileName.Append( KScreenShotsSubDirectory );
       
  1295  
       
  1296     
       
  1297         // a quick check that filename is valid
       
  1298         if (iGrabSettings.iVideoCaptureFileName.Length() > 0 && iGrabSettings.iVideoCaptureFileName.Length() <= 255) 
       
  1299             iSaveFileName.Append( iGrabSettings.iVideoCaptureFileName );
       
  1300         else
       
  1301             iSaveFileName.Append( KDefaultVideoFileName );
       
  1302 
       
  1303         iSaveFileName.Append( _L(".gif") );
       
  1304 
       
  1305         CApaApplication::GenerateFileName(iEnv->FsSession(), iSaveFileName );  // unique filename
       
  1306 
       
  1307         // create and save the gif animation
       
  1308         err = CGifAnimator::CreateGifAnimation(iSaveFileName, iVideoDimensions, iVideoFrameArray);
       
  1309         
       
  1310         // remove the saved file in case of errors since it's likely corrupted
       
  1311         if (err != KErrNone)
       
  1312             iEnv->FsSession().Delete(iSaveFileName);
       
  1313         
       
  1314         CapturingFinishedL(err);   
       
  1315         }
       
  1316         
       
  1317     else
       
  1318         CapturingFinishedL(KErrNotSupported);
       
  1319     }
       
  1320 
       
  1321 // ---------------------------------------------------------------------------
       
  1322 
       
  1323 void CScreenGrabberModel::CleanTemporaryFilesL()
       
  1324     {
       
  1325     // delete temporary files from C and D drives    
       
  1326     CFileMan* fileMan = CFileMan::NewL(iEnv->FsSession());
       
  1327 
       
  1328     TFileName delFilesPath;
       
  1329         
       
  1330     for (TInt i=0; i<1; i++)
       
  1331         {
       
  1332         delFilesPath.Copy(KNullDesC);
       
  1333         delFilesPath.Append('C'+i);
       
  1334         delFilesPath.Append(_L(":"));
       
  1335         delFilesPath.Append(KSGTemporaryDirectory);
       
  1336         delFilesPath.Append(_L("*.$$$"));
       
  1337         
       
  1338         fileMan->Delete(delFilesPath);
       
  1339         }
       
  1340 
       
  1341     delete fileMan;    
       
  1342     }
       
  1343 
       
  1344 // ---------------------------------------------------------------------------
       
  1345     
       
  1346 void CScreenGrabberModel::CapturingFinishedL(TInt aErr)
       
  1347     {
       
  1348     // display a global query to show the results
       
  1349 
       
  1350     if (aErr == KErrNone)
       
  1351         {
       
  1352         switch (iGrabSettings.iCaptureMode)
       
  1353             {
       
  1354             case ECaptureModeSingleCapture:
       
  1355                 {
       
  1356                 iSavedQuery->DisplayL(KSingleShotSaved);
       
  1357                 }
       
  1358                 break;
       
  1359             
       
  1360             case ECaptureModeSequantialCapture:
       
  1361                 {
       
  1362                 if (iNumberOfTakenShots == 1)
       
  1363                     iSavedQuery->DisplayL(KSingleShotSaved);
       
  1364                 else
       
  1365                     {
       
  1366                     TBuf<256> note;
       
  1367                     note.Format(KMultipleShotsSaved, iNumberOfTakenShots);
       
  1368                     iSavedQuery->DisplayL(note);
       
  1369                     }
       
  1370                 }
       
  1371                 break;            
       
  1372     
       
  1373             case ECaptureModeVideoCapture:
       
  1374                 {
       
  1375                 iSavedQuery->DisplayL(KVideoSaved);
       
  1376                 }
       
  1377                 break;             
       
  1378     
       
  1379             default:
       
  1380                 User::Panic(_L("Inv.capt.mode"), 51);
       
  1381                 break;
       
  1382             }            
       
  1383        
       
  1384         // notify the new file to Media Gallery
       
  1385         UpdateFileToGallery(iSaveFileName);
       
  1386         }
       
  1387     else
       
  1388         {
       
  1389         TBuf<256> errorNote;
       
  1390         errorNote.Copy( KErrorOccured );
       
  1391 
       
  1392         CTextResolver* textResolver = CTextResolver::NewLC();
       
  1393         errorNote.Append( textResolver->ResolveErrorString(aErr) );
       
  1394         CleanupStack::PopAndDestroy();  //textResolver    
       
  1395           
       
  1396         iSavedQuery->DisplayL(errorNote, ETrue);
       
  1397         }
       
  1398 
       
  1399     // reset values
       
  1400     iNumberOfTakenShots = 0;
       
  1401     iCurrentFrameNumber = 0;
       
  1402     iVideoFrameArray->Reset();
       
  1403 
       
  1404 
       
  1405     // remove the query after 2.0 secs
       
  1406     iState = EQueryDelay;
       
  1407     iTimer.After(iStatus, 2000000);
       
  1408     SetActive();
       
  1409 
       
  1410     }
       
  1411     
       
  1412 // ---------------------------------------------------------------------------
       
  1413 
       
  1414 TBool CScreenGrabberModel::MemoryCardOK()
       
  1415 	{
       
  1416 	return DriveOK(EDriveE); // hardcoding EDriveE here maybe is not so good idea..   
       
  1417 	}
       
  1418 
       
  1419 // ---------------------------------------------------------------------------
       
  1420 
       
  1421 TBool CScreenGrabberModel::DriveOK(TDriveNumber aNumber)
       
  1422 	{
       
  1423 	TBool isOK(EFalse);
       
  1424 
       
  1425     TVolumeInfo vInfo;
       
  1426 
       
  1427 	// check if we can access the drive
       
  1428 	if (iEnv->FsSession().Volume(vInfo, aNumber) == KErrNone)
       
  1429 		isOK = ETrue;
       
  1430 
       
  1431 	// returns ETrue if memory card working properly
       
  1432 	return isOK;
       
  1433 	}
       
  1434 // ---------------------------------------------------------------------------
       
  1435 
       
  1436 void CScreenGrabberModel::PlayBeepSound()
       
  1437     {
       
  1438     TMdaAudioToneUtilityState toneState = iMdaAudioToneUtility->State();
       
  1439     
       
  1440     if (toneState == EMdaAudioToneUtilityPlaying)
       
  1441         iMdaAudioToneUtility->CancelPlay();
       
  1442     else if (toneState == EMdaAudioToneUtilityNotReady)
       
  1443         iMdaAudioToneUtility->CancelPrepare();
       
  1444 
       
  1445     iMdaAudioToneUtility->PrepareToPlayTone(500, TTimeIntervalMicroSeconds(100000));
       
  1446     }
       
  1447 
       
  1448 // ---------------------------------------------------------------------------
       
  1449 
       
  1450 void CScreenGrabberModel::MatoPrepareComplete(TInt aError)
       
  1451     {
       
  1452     if (aError == KErrNone)
       
  1453         iMdaAudioToneUtility->Play();
       
  1454     }
       
  1455 
       
  1456 // ---------------------------------------------------------------------------
       
  1457 
       
  1458 void CScreenGrabberModel::MatoPlayComplete(TInt /*aError*/)
       
  1459     {
       
  1460     }
       
  1461 
       
  1462 // ---------------------------------------------------------------------------
       
  1463 
       
  1464 TInt CScreenGrabberModel::UpdateFileToGallery(const TDesC& aFullPath)
       
  1465     {
       
  1466     // first check if this feature is supported    
       
  1467     if (iGalleryUpdaterSupported)
       
  1468         {
       
  1469         // check if has been initialized
       
  1470         if (!iGalleryUpdaterInitialized)
       
  1471             {
       
  1472             // not initialized, first try to load the DLL    
       
  1473             if (iGalleryUpdaterDLL.Load(_L("MGXMediaFileAPI.dll")) == KErrNone)
       
  1474                 {
       
  1475                 // construct the object, equals:
       
  1476                 // CMGXFileManager* mgxFileManager = (MGXFileManagerFactory::NewFileManagerL)(NewFileManagerLEntry)(iEnv->FsSession());
       
  1477             
       
  1478                 typedef CMGXFileManager* (*TMyFunc)(RFs& aFs);
       
  1479                 TMyFunc theFunc = (TMyFunc)iGalleryUpdaterDLL.Lookup(1);
       
  1480                 if (theFunc)
       
  1481                     {
       
  1482                     TRAPD( err, iMGXFileManager = theFunc(iEnv->FsSession()) );
       
  1483                     if (iMGXFileManager && err == KErrNone)
       
  1484                         {
       
  1485                         // construction completed succesfully
       
  1486                         iGalleryUpdaterInitialized = ETrue;
       
  1487                         }
       
  1488                     else
       
  1489                         {
       
  1490                         // out of memory or other unknown error?    
       
  1491                         iGalleryUpdaterDLL.Close();
       
  1492                         }
       
  1493                     }
       
  1494                 else
       
  1495                     {
       
  1496                     // ordinal not found from the DLL 
       
  1497                     iGalleryUpdaterDLL.Close();
       
  1498                     }    
       
  1499                 }
       
  1500             else
       
  1501                 {
       
  1502                 // DLL does not exist in the device
       
  1503                 }
       
  1504             }
       
  1505 
       
  1506         // update the file if gallery updater has been initialized
       
  1507         if (iGalleryUpdaterInitialized)
       
  1508             {
       
  1509             TRAPD(err, iMGXFileManager->UpdateL(aFullPath));
       
  1510             return err;    
       
  1511             }
       
  1512         else
       
  1513             {
       
  1514             // gallery updater not supported if initialization failed    
       
  1515             iGalleryUpdaterSupported = EFalse;
       
  1516             return KErrNotSupported;    
       
  1517             }            
       
  1518         }
       
  1519     else
       
  1520         {
       
  1521         return KErrNotSupported;
       
  1522         }
       
  1523     }
       
  1524 
       
  1525 // ---------------------------------------------------------------------------
       
  1526 
       
  1527 /*************************************************************************************************/
       
  1528 // a class to display an info message that the screen shot was saved to disk
       
  1529 
       
  1530 CSavedQuery::CSavedQuery() : CActive(EPriorityLow)
       
  1531     {
       
  1532 	CActiveScheduler::Add(this);
       
  1533     }
       
  1534 
       
  1535 void CSavedQuery::ConstructL()
       
  1536     {
       
  1537     iGlobalConfirmationQuery = CAknGlobalConfirmationQuery::NewL();
       
  1538     }
       
  1539 
       
  1540 CSavedQuery* CSavedQuery::NewL()
       
  1541     {
       
  1542     CSavedQuery* self = new(ELeave) CSavedQuery();
       
  1543     CleanupStack::PushL(self);
       
  1544     self->ConstructL();
       
  1545     CleanupStack::Pop(self);
       
  1546     return self;
       
  1547     }
       
  1548 
       
  1549 CSavedQuery::~CSavedQuery()
       
  1550     {
       
  1551     delete iGlobalConfirmationQuery;
       
  1552     }
       
  1553 
       
  1554 void CSavedQuery::DisplayL(const TDesC &aText, TBool aDisplayErrorNote)
       
  1555     {
       
  1556     if (!iVisible)
       
  1557         {
       
  1558         TRAPD(err, DisplayWithGraphicsL(aText, aDisplayErrorNote));
       
  1559         if (err != KErrNone)
       
  1560             {
       
  1561             DisplayWithoutGraphicsL(aText);
       
  1562             }
       
  1563         iVisible = ETrue;
       
  1564         SetActive();
       
  1565         }
       
  1566     }
       
  1567 
       
  1568 void CSavedQuery::DoCancel()
       
  1569     {
       
  1570     if (iGlobalConfirmationQuery)
       
  1571         {
       
  1572         iGlobalConfirmationQuery->CancelConfirmationQuery();
       
  1573         }
       
  1574     iVisible = EFalse;
       
  1575     }
       
  1576 
       
  1577 void CSavedQuery::RunL()
       
  1578     {
       
  1579     iVisible = EFalse;
       
  1580     }
       
  1581 
       
  1582 void CSavedQuery::DisplayWithGraphicsL(const TDesC &aText, TBool aDisplayErrorNote)
       
  1583     {
       
  1584     if (aDisplayErrorNote)
       
  1585         {
       
  1586         iGlobalConfirmationQuery->ShowConfirmationQueryL
       
  1587             (iStatus, aText, R_AVKON_SOFTKEYS_EMPTY, R_QGN_NOTE_ERROR_ANIM,
       
  1588             KNullDesC, 0, 0, CAknQueryDialog::EErrorTone, ETrue);
       
  1589         }
       
  1590     else
       
  1591         {
       
  1592         iGlobalConfirmationQuery->ShowConfirmationQueryL
       
  1593             (iStatus, aText, R_AVKON_SOFTKEYS_EMPTY, R_QGN_NOTE_OK_ANIM,
       
  1594             KNullDesC, 0, 0, CAknQueryDialog::EConfirmationTone, ETrue);
       
  1595         }
       
  1596     }
       
  1597 
       
  1598 void CSavedQuery::DisplayWithoutGraphicsL(const TDesC &aText)
       
  1599     {
       
  1600 	iGlobalConfirmationQuery->ShowConfirmationQueryL
       
  1601         (iStatus, aText, R_AVKON_SOFTKEYS_OK_EMPTY);
       
  1602     }
       
  1603 
       
  1604 /*************************************************************************************************/