photosgallery/imgvwr/src/glxivwrappui.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 14 Sep 2010 21:19:17 +0300
branchRCL_3
changeset 64 34937ec34dac
parent 60 5b3385a43d68
child 75 01504893d9cb
permissions -rw-r--r--
Revision: 201033 Kit: 201035

/*
 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). 
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of "Eclipse Public License v1.0"
 * which accompanies this distribution, and is available
 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
 *
 * Initial Contributors:
 * Nokia Corporation - initial contribution.
 *
 * Contributors:
 *
 * Description: Image Viewer AppUi class 
 *
 */




#include "glxivwrappui.h"
#include "glxivwrdocument.h"

#include <apgcli.h>
#include <hal.h>
#include <oommonitorsession.h>
#include <mpxviewutility.h>
#include <mpxcollectionpath.h>

#include <glxmedialist.h>
#include <glxcollectionpluginimageviewer.hrh>
#include <glxviewpluginuids.hrh>
#include <glxuiutility.h>
#include <glxzoomstatepublisher.h>
#include <glxnavigationalstate.h>
#include <glxnavigationalstatedefs.h>
#include <glxtracer.h>
#include <glxlog.h>
#include <glxivwr.rsg>
#include <eikbtgpc.h>


//constants
const TInt KGlxFullThumbnailCount         = 1 ;       // 1 visible thumnail
#ifdef __MARM
const TInt KGlxMaxMegaPixelsSupportedByCamera = 5242880 ; // 5 MB
#else
const TInt KGlxMaxMegaPixelsSupportedByCamera = 2097152 ; // 2 MB
#endif
const TInt KGlxMaxMemoryToDecodeCapturedPicture = 2 * KGlxMaxMegaPixelsSupportedByCamera ;
const TInt KGlxMemoryForOOMFwk          = 1048576 ; // 1 MB
const TInt KGlxThumbNailRepresentation    = 4;         // Thumbnail Representation; Could be 3 also 

// UID for the application, 
// this should correspond to the uid defined in the mmp file
static const TUid KUidGlxIvwrApp = {0x200104E7};

// -----------------------------------------------------------------------------
// Constructor
// -----------------------------------------------------------------------------
//
CGlxIVwrAppUi::CGlxIVwrAppUi()
    {
    }

// -----------------------------------------------------------------------------
// ConstructL is called by the application framework
// -----------------------------------------------------------------------------
//
void CGlxIVwrAppUi::ConstructL()
    {
    TRACER("void CGlxIVwrAppUi::ConstructL()");

    // Enable Avkon skins.
    BaseConstructL( EAknEnableSkin | EAknEnableMSK | EAknSingleClickCompatible );
     
    // Hide status pane
	StatusPane()->MakeVisible(EFalse);
	// Hide Softkeys
	CEikButtonGroupContainer* cba = CEikButtonGroupContainer::Current();
	cba->MakeVisible(EFalse); 
       
    // Create navigational state 
    iNavigationalState = CGlxNavigationalState::InstanceL();
    iNavigationalState->AddObserverL( *this );
    iNavigationalState->SetBackExitStatus(EFalse);

    // Get an instance of view utility
    iViewUtility = MMPXViewUtility::UtilityL();

    iUiUtility = CGlxUiUtility::UtilityL();
    // Always start in default orientation
    iUiUtility->SetAppOrientationL(EGlxOrientationDefault);

    ReserveMemoryL(EEntryTypeStartUp);
    
    // publish zoom context, no zoom keys for now
    NGlxZoomStatePublisher::PublishStateL( EFalse );
    }

// -----------------------------------------------------------------------------
// Destructor
// -----------------------------------------------------------------------------
//
CGlxIVwrAppUi::~CGlxIVwrAppUi()
    {
    TRACER("CGlxIVwrAppUi::~CGlxIVwrAppUi()");
    if ( iNavigationalState )
        {
        iNavigationalState->RemoveObserver(*this);
        iNavigationalState->Close();
        }

    if ( iViewUtility )
        {
        iViewUtility->Close();
        }

    if ( iUiUtility )
        {
        iUiUtility->Close();
        }
    }

// -----------------------------------------------------------------------------
// HandleCommandL
// -----------------------------------------------------------------------------
//
void CGlxIVwrAppUi::HandleCommandL(TInt aCommand)
    {
    TRACER("void CGlxIVwrAppUi::HandleCommandL(TInt aCommand)");
    GLX_LOG_INFO1("void CGlxIVwrAppUi::HandleCommandL(aCommand=%d)", aCommand );
    switch (aCommand)
        {
        case EEikCmdExit:
            {
            Exit();
            }
            break;
        case EAknSoftkeyExit:
            {
            CloseImgVwr();
            GLX_LOG_INFO("CGlxIVwrAppUi::HandleCommandL: Exit() being Called");
            Exit();
            }
            break;

        case EAknSoftkeyBack:
            {
            iNavigationalState->ActivatePreviousViewL();
            }
            break;

        default:
            break;
        }
    }

// ---------------------------------------------------------------------------
// ProcessCommandParametersL
// ---------------------------------------------------------------------------
//
TBool CGlxIVwrAppUi::ProcessCommandParametersL(TApaCommand /*aCommand*/,
        TFileName& /*aDocumentName*/, const TDesC8& /*aTail*/)
    {
    TRACER("TBool CGlxIVwrAppUi::ProcessCommandParametersL()");

    // Bring the application to foreground, if not already
    if (0 != iEikonEnv->RootWin().OrdinalPosition())
        {
        iEikonEnv->RootWin().SetOrdinalPosition(0);
        }

	//To call OpenFileL in document class it must retun ETrue
    return ETrue;
    }

// ---------------------------------------------------------------------------
// Handle navigational state change
// ---------------------------------------------------------------------------
//
void CGlxIVwrAppUi::HandleNavigationalStateChangedL()
    {
    TRACER("void CGlxIVwrAppUi::HandleNavigationalStateChangedL()");
    // get current navigational state
    CMPXCollectionPath* naviState = iNavigationalState->StateLC();

    // Case: Open photos in grid, go to filemanager via menu and open any image
    if (naviState->Id() != TMPXItemId(
            KGlxCollectionPluginImageViewerImplementationUid))
        {
        /*
         * This thread chk is added for EDDG-7UUC53. In this scenario we get EPathChanged from MPX.
         * That initiates a viewnavigational change from CGlxNavigationalStateImp  HandleCollectionMessageL()
         * In these types of scenarios we don't want a view switch. So ignoring the event. 
         */
        TApaTaskList taskList(iCoeEnv->WsSession());
        TApaTask task = taskList.FindApp(KUidGlxIvwrApp);
        TApaTask taskForeGround = taskList.FindByPos(0); // get fopreground app
        if (task.Exists() && task.ThreadId() != taskForeGround.ThreadId())
            {
            GLX_LOG_INFO("CGlxIVwrAppUi ::HandleNavigationalStateChanged: Return ");
            return;
            }
        }

    CleanupStack::PopAndDestroy(naviState);

    if (TUid::Null() != iStartupViewUid)
        {
        GLX_LOG_INFO("CGlxIVwrAppUi::HandleNavigationalStateChanged:Activating startup view");
        // Activate startup view
        iViewUtility->ActivateViewL(iStartupViewUid, NULL);
        iStartupViewUid = TUid::Null();
        }
    else
        {
        GLX_LOG_INFO("CGlxIVwrAppUi::HandleNavigationalStateChanged:Activating view");

        // get ids for scoring a view
        RArray<TUid> scoringIds;
        CleanupClosePushL(scoringIds);
        GetViewScoringIdsL(scoringIds);

        GLX_LOG_INFO1("CGlxIVwrAppUi::HandleNavigationalStateChanged:Uid count %d", scoringIds.Count());
        // let view utility to select the best view based on scoring ids
        iViewUtility->ActivateViewL(scoringIds, NULL);

        CleanupStack::PopAndDestroy(&scoringIds);
        }
    }

// ---------------------------------------------------------------------------
// Populate array with view scoring ids
// ---------------------------------------------------------------------------
//
void CGlxIVwrAppUi::GetViewScoringIdsL( RArray<TUid>& aIds ) const
    {
    TRACER("void CGlxIVwrAppUi::GetViewScoringIdsL()");
    CleanupClosePushL(aIds);
    aIds.Reset(); // For maintenance safety

    // get current navigational state
    CMPXCollectionPath* naviState = iNavigationalState->StateLC();

    // no if check in needed here ,it makes the aapui aware of the list view depth
    // to be removed.added by gopa   
    if (naviState->Levels() >= 1)
        {
        if (iNavigationalState->ViewingMode()
                == NGlxNavigationalState::EBrowse)
            {
            // For image viewer collection, goto view mode
            if (naviState->Id() == TMPXItemId(
                    KGlxCollectionPluginImageViewerImplementationUid))
                {
                aIds.AppendL(TUid::Uid(KGlxViewingModeView));
                }
            else
                {
                aIds.AppendL(TUid::Uid(KGlxViewingModeBrowse));
                }
            }
        else
            {
            aIds.AppendL(TUid::Uid(KGlxViewingModeView));
            }
        }

    if (TUid::Null() != GetViewScoringIdForCollectionPlugin(*naviState))
        {
        // add scoring id for collection plugin
        aIds.AppendL(GetViewScoringIdForCollectionPlugin(*naviState));
        }

    if (TUid::Null() != ViewScoringIdForNaviStateDepth(*naviState))
        {
        // add scoring id for depth in the ui hierarchy
        aIds.AppendL(ViewScoringIdForNaviStateDepth(*naviState));
        }

    CleanupStack::PopAndDestroy(naviState);
    CleanupStack::Pop(&aIds);
    }

// ---------------------------------------------------------------------------
// Return scoring id for collection plugin
// ---------------------------------------------------------------------------
//
TUid CGlxIVwrAppUi::GetViewScoringIdForCollectionPlugin(
        const CMPXCollectionPath& aNaviState) const
    {
    TRACER("TUid CGlxIVwrAppUi::GetViewScoringIdForCollectionPluginL()");

    GLX_LOG_INFO1( "CGlxIVwrAppUi::GetViewScoringIdForCollectionPluginL:Depth %d", aNaviState.Levels() );
    // score view based on collection plugin if not on root level
    if (aNaviState.Levels())
        {
        return TUid::Uid(aNaviState.Id(0));
        }
    // return null as id to be ignored in scoring
    return TUid::Null();
    }

// ---------------------------------------------------------------------------
// Return scoring id for depth
// ---------------------------------------------------------------------------
//
TUid CGlxIVwrAppUi::ViewScoringIdForNaviStateDepth(
        const CMPXCollectionPath& aNaviState) const
    {
    TRACER("TUid CGlxIVwrAppUi::ViewScoringIdForNaviStateDepthL()");
    GLX_LOG_INFO1( "CGlxIVwrAppUi::ViewScoringIdForNaviStateDepthL: Level %d",aNaviState.Levels() );

    switch (aNaviState.Levels())
        {
        case 0:

            GLX_LOG_INFO1( "CGlxIVwrAppUi::ViewScoringIdForNaviStateDepthL:Depth  case 0 %x", TUid::Uid( KGlxDepthOne ) );
            return TUid::Uid(KGlxDepthOne);

        case 1:

            GLX_LOG_INFO1( "CGlxIVwrAppUi::ViewScoringIdForNaviStateDepthL:Depth case 1 %x", TUid::Uid( KGlxDepthTwo ) );
            return TUid::Uid(KGlxDepthTwo);

        case 2:

            GLX_LOG_INFO1( "CGlxIVwrAppUi::GetViewScoringIdForUiHieararchyDepthL:Depth case 2 %x", TUid::Uid( KGlxDepthThree ) );
            return TUid::Uid(KGlxDepthThree);

        default:
            GLX_LOG_WARNING( "CGlxIVwrAppUi::GetViewScoringIdsL:Navigational state deeper than supported" );
            // return null as an id to be ignored in scoring
            return TUid::Null();
        }
    }

// ---------------------------------------------------------------------------
// HandleOpenFileL
// ---------------------------------------------------------------------------
//
void CGlxIVwrAppUi::HandleOpenFileL()
    {
    TRACER("void CGlxIVwrAppUi::HandleOpenFileL()");
    CMPXCollectionPath* path = CMPXCollectionPath::NewL();
    CleanupStack::PushL(path);
    path->AppendL( KGlxCollectionPluginImageViewerImplementationUid );
    iNavigationalState->NavigateToL( *path );
    CleanupStack::PopAndDestroy( path );    
    }

// ---------------------------------------------------------------------------
// OOMRequestFreeMemoryL
// ---------------------------------------------------------------------------
//
TInt CGlxIVwrAppUi::OOMRequestFreeMemoryL(TInt aBytesRequested)
    {
    TRACER("TInt CGlxIVwrAppUi::OOMRequestFreeMemoryL(TInt aBytesRequested)");
    GLX_LOG_INFO1("CGlxIVwrAppUi::OOMRequestFreeMemoryL() aBytesRequested=%d",aBytesRequested);

    ROomMonitorSession oomMonitor;
    User::LeaveIfError( oomMonitor.Connect() );
    // No leaving code after this point, so no need to use cleanup stack
    // for oomMonitor
    TInt errorCode = oomMonitor.RequestFreeMemory( aBytesRequested );
    GLX_LOG_INFO1("CGlxIVwrAppUi::OOMRequestFreeMemoryL(1) errorCode=%d",errorCode);
    if ( errorCode != KErrNone )
        {
        // try one more time 
        errorCode = oomMonitor.RequestFreeMemory( aBytesRequested );
        GLX_LOG_INFO1("CGlxIVwrAppUi::OOMRequestFreeMemoryL(2) errorCode=%d",errorCode);
        }
    oomMonitor.Close();
    return errorCode;
    }

// ---------------------------------------------------------------------------
// ReserveMemoryL
// ---------------------------------------------------------------------------
//
TInt CGlxIVwrAppUi::ReserveMemoryL(TInt aCriticalMemoryRequired)
    {
    TRACER("void CGlxIVwrAppUi::ReserveMemoryL(TInt aCriticalMemoryRequired)");

    TInt memoryLeft = 0;
    TInt error = KErrNone ; 
    HAL::Get( HALData::EMemoryRAMFree, memoryLeft );
    GLX_LOG_INFO2("CGlxIVwrAppUi::ReserveMemoryL() - aCriticalMemoryRequired=%d, memoryLeft=%d", aCriticalMemoryRequired, memoryLeft);
    if ( aCriticalMemoryRequired > memoryLeft )
        {
        // Request for critical memory required 
        error = OOMRequestFreeMemoryL( aCriticalMemoryRequired);
        GLX_LOG_INFO1("CGlxIVwrAppUi::ReserveMemoryL() - OOMRequestFreeMemoryL() error=%d", error);
        }
    return error;
    }

// ---------------------------------------------------------------------------
// RamRequiredInBytesL
// ---------------------------------------------------------------------------
//
TInt CGlxIVwrAppUi::RamRequiredInBytesL(TEntryType aType)
    {
    TRACER("TInt CGlxIVwrAppUi::RamRequiredInBytesL(TEntryType aType)");
    TInt criticalRamMemory = 0 ;
    TSize displaySize = iUiUtility->DisplaySize();
    if(EEntryTypeStartUp == aType)
        {
        // This is Bare Minimum Required Memory for Photos to start 
        // For Framework to work and to do the on-the-fly decoding 
        // for the just captured picture = KGlxMemoryForOOMFwk + KGlxMaxMemoryToDecodeCapturedPicture
        // For FullScreen to Work Number of Thumbnail(s) * Width * Height * Representation
        criticalRamMemory = KGlxMemoryForOOMFwk
                + KGlxMaxMemoryToDecodeCapturedPicture
                + (KGlxFullThumbnailCount * displaySize.iWidth
                        * displaySize.iHeight * KGlxThumbNailRepresentation);

        GLX_LOG_INFO1("CGlxIVwrAppUi::RamRequiredInBytesL(EEntryTypeStartUp):criticalRamMemory=%d", criticalRamMemory);
        }
    else
        {
        GLX_LOG_INFO("CGlxIVwrAppUi::RamRequiredInBytesL():Viewer Already Running");
        }
 
    return criticalRamMemory;
    }

// ---------------------------------------------------------------------------
// ReserveMemoryL
// ---------------------------------------------------------------------------
//
void CGlxIVwrAppUi::ReserveMemoryL(TEntryType aType)
    {
    TRACER("TInt CGlxIVwrAppUi::ReserveMemoryL(TEntryType aType)");
    
    TInt error = ReserveMemoryL(RamRequiredInBytesL(aType));
    GLX_LOG_INFO1("CGlxIVwrAppUi::ReserveMemoryL() error=%d", error);
    
    if (KErrNoMemory == error)
        {
        GLX_LOG_INFO("CGlxIVwrAppUi::ReserveMemoryL():LEAVE with KErrNoMemory");
        User::Leave(KErrNoMemory);
        }
    }

// ---------------------------------------------------------------------------
// HandleApplicationSpecificEventL
// 
// ---------------------------------------------------------------------------
//
void CGlxIVwrAppUi::HandleApplicationSpecificEventL(TInt aEventType, 
        const TWsEvent& aWsEvent)
    {
    TRACER("CGlxIVwrAppUi::HandleApplicationSpecificEventL");
    CAknViewAppUi::HandleApplicationSpecificEventL(aEventType,aWsEvent);
    if(aWsEvent.Type() == KAknUidValueEndKeyCloseEvent)
        {
        CloseImgVwr();
        }
    }

// -----------------------------------------------------------------------------
// CloseImgVwr
// -----------------------------------------------------------------------------
//
void CGlxIVwrAppUi::CloseImgVwr()
    {
    TRACER("CGlxIVwrAppUi::CloseImgVwr()");
    iUiUtility->SetViewNavigationDirection(EGlxNavigationBackwards);
    iUiUtility->SetExitingState(ETrue);         
    }

// ----------------------------------------------------------------------------
// CGlxIVwrAppUi::OpenFileL
// This is called by framework when application is already open in background
// and user open other file in eg. File Browse.
// New file to been shown is passed via aFileName.
// ----------------------------------------------------------------------------
//
void CGlxIVwrAppUi::OpenFileL(const TDesC& aFileName)
    {
    TRACER("CGlxIVwrAppUi::OpenFileL()");
    GLX_LOG_URI("CGlxIVwrAppUi::OpenFileL(%S)", &aFileName);

    // File changed. Open new file with documents OpenFileL method.
    Document()->OpenFileL(EFalse, aFileName, iEikonEnv->FsSession());

    GLX_DEBUG1("CGlxIVwrAppUi::OpenFileL() *** File Changed *** ");
    MGlxCache* cacheManager = MGlxCache::InstanceL();
    CleanupClosePushL(*cacheManager);

    CMPXCollectionPath* path = CMPXCollectionPath::NewL();
    CleanupStack::PushL(path);
    path->AppendL(KGlxCollectionPluginImageViewerImplementationUid);

    MGlxMediaList* mediaList = MGlxMediaList::InstanceL(*path);
    CleanupClosePushL(*mediaList);

    if (mediaList->Count() > 0)
        {
        GLX_DEBUG1("CGlxIVwrAppUi::OpenFileL() - Cleanup & Refresh Media!");
        cacheManager->ForceCleanupMedia(mediaList->IdSpaceId(0),
                mediaList->Item(0).Id());
        cacheManager->RefreshL();
        }

    CleanupStack::PopAndDestroy(mediaList);
    CleanupStack::PopAndDestroy(path);
    CleanupStack::PopAndDestroy(cacheManager);
    }