calendarui/controller/src/calencmdlinelauncher.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 14 Sep 2010 21:17:03 +0300
branchRCL_3
changeset 31 97232defd20e
parent 30 bd7edf625bdd
permissions -rw-r--r--
Revision: 201033 Kit: 201035

/*
* Copyright (c) 2007 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:  ?Description
 *
*/


//debug
#include "calendarui_debug.h"

// INCLUDE FILES
#include <aknViewAppUi.h>               // CAknViewAppUi
#include <calenagendautils.h>
#include <calinstanceview.h>
#include <calencontext.h>
#include <caleninstanceid.h>            // TCalenInstanceId
#include <calenactionuiutils.h>
#include <aknappui.h>
#include <AknDlgShut.h>
#include <gfxtranseffect/gfxtranseffect.h>  // For transition effects
#include <akntranseffect.h>                 // For transition effects

#include "calenviewmanager.h"
#include "calencmdlinelauncher.h"
#include "calencontroller.h"            // CCalenController
#include "calencmdlineparser.h"         // CCalCmdLineParser
#include "CalenUid.h"
#include "calensend.h"
#include "calendialogshutter.h"

const TUid KCalendarUid             = {0x10005901};         // Calendar application UID

// ================= MEMBER FUNCTIONS =======================

// ---------------------------------------------------------
// CCalenCmdLineLauncher::CCalenCmdLineLauncher
// C++ default constructor
// (other items were commented in a header).
// Status : Draft/Proposal/Approved
// ---------------------------------------------------------
//
CCalenCmdLineLauncher::CCalenCmdLineLauncher( CCalenController& aController,
                                                                    CAknViewAppUi& aAppUi )
    : iController( aController ), iAppUi( aAppUi )
    {
    TRACE_ENTRY_POINT;
    TRACE_EXIT_POINT;
    }

// ---------------------------------------------------------
// CCalenCmdLineLauncher::NewL
// 1st phase of construction
// (other items were commented in a header).
// Status : Draft/Proposal/Approved
// ---------------------------------------------------------
//
CCalenCmdLineLauncher* CCalenCmdLineLauncher::NewL( CCalenController& aController,
                                                                              CAknViewAppUi& aAppUi )
    {
    TRACE_ENTRY_POINT;
    
    CCalenCmdLineLauncher* self = new( ELeave ) CCalenCmdLineLauncher( aController, aAppUi );
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self );
    
    TRACE_EXIT_POINT;
    return self;
    }

// ---------------------------------------------------------
// CCalenCmdLineLauncher::~CCalenCmdLineLauncher
// Destructor
// (other items were commented in a header).
// Status : Draft/Proposal/Approved
// ---------------------------------------------------------
//
CCalenCmdLineLauncher::~CCalenCmdLineLauncher()
    {
    TRACE_ENTRY_POINT;

    iController.CancelNotifications( this );

    if( iGlobalData )
        {
        iGlobalData->Release();
        }

    delete iCalendarLaunchCallBack;
    
    if ( iShutter )
        {
        delete iShutter;
        iShutter = NULL;
        }

    TRACE_EXIT_POINT;
    }

// ----------------------------------------------------------------------------
// CCalenCmdLineLauncher::ConstructL
// 2nd phase of construction
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CCalenCmdLineLauncher::ConstructL()
    {
    TRACE_ENTRY_POINT;
 
    // get the global data
    iGlobalData = CCalenGlobalData::InstanceL();
    
    
    RArray<TCalenNotification> exitFlags;
    exitFlags.Append(ECalenNotifyEntryDeleted);
    exitFlags.Append(ECalenNotifyInstanceDeleted);
    exitFlags.Append(ECalenNotifyDialogClosed);
    exitFlags.Append(ECalenNotifyEntryClosed);
    
    iController.RegisterForNotificationsL( this, exitFlags );
    
    exitFlags.Reset();
    iShutter = CCalenDialogShutter::NewL( CEikonEnv::Static() );
    TRACE_EXIT_POINT;
    }

// ----------------------------------------------------------------------------
// CCalenCmdLineLauncher::ProcessCommandParametersL
// takes care of commandline parameter.
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
TBool CCalenCmdLineLauncher::ProcessCommandParametersL( 
                                                                    TApaCommand /*aCommand*/,
                                                                    TFileName& /*aDocumentName*/,
                                                                    const TDesC8& aTail )
    {
    TRACE_ENTRY_POINT;

    // If aTail is set, other app starts Calendar
    if( aTail.Length() )
        {
        // If we are displaying a dialog, then Calendar is obviously already open
        // If we have been launched with cmd line parameters, we need to close the
        // open dialog and deal with the command line.  An example of this would be that
        // Calendar is in the background with an open entry editor, and is then launched from
        // the command line to open a new entry editor.  We need to close the old editor
        // using the same 'try and save whatever we can' logic that is used on a forced close
        // and then open the new editor.  We also have to prevent the focus state being updated
        // and highlighting the old entry in the day view.
        if( AppUi().IsDisplayingDialog() )
            {
            iIsExitOnDlgClose = EFalse;
            // Tell the editui that whatever it was doing, it should not alter
            // the focus state
            iController.IssueCommandL( ECalenNotifyFocusChange );
            
            iShutter->Cancel();
            //close all open dialogs in asynchronous way
            iShutter->ShutDialogsL();
            }

        // Interpret 8bit data as 16bit unicode data
        //lint -e{826} Disable the lint warning of the pointer sizes being different
        const TText* buf = reinterpret_cast<const TText*> (aTail.Ptr());
        TPtrC ptr(buf, aTail.Length() / (TInt) sizeof(TText));

        // create cmd line parser
        CCalenCmdLineParser* parser = CCalenCmdLineParser::NewL();
        CleanupStack::PushL(parser);
        // parse parameters
        parser->ParseCommandLineL(ptr);
        iCmdParameters = parser->CommandLineParameters();
        CleanupStack::PopAndDestroy(); // parser
        }

    // If we are launched to a specific view, find and activate it.
    // Any other launch types are handled in CalendarLaunchCallBack

    TBool useLaunchCallback = EFalse;
    MCalenContext &context = iGlobalData->Context();
    
    // If aUseViewerIfAvailable is ETrue then start activate Event view else Editor.
    TBool aUseViewerIfAvailable = EFalse;

    // If time variable is set we will use that as context time.
    TBool focusOnTime = iCmdParameters.iTime != Time::NullTTime() &&
                        iCmdParameters.iTime.Int64() !=  0 ; // for some reason 0 is now coming through as a null
                                                   // time during normal app start. perhaps it just hasn't been set.
    TCalTime focusTime;
    if( focusOnTime )
        {
        focusTime.SetTimeLocalL( iCmdParameters.iTime );
        }
    else
        {
        focusTime = context.DefaultCalTimeForViewsL();
        }
        
    switch( iCmdParameters.iCommandType )
        {
        case CCalenCmdLineParser::EStartTypeDate: 
        case CCalenCmdLineParser::EStartTypeDay:  
        case CCalenCmdLineParser::EStartTypeToday:
        case CCalenCmdLineParser::EStartTypeToDo:
        case CCalenCmdLineParser::EStartTypeWeek:
        case CCalenCmdLineParser::EStartTypeMonth:	
            {
            TInt command( 0 );
            TUid viewUid = TUid::Null();
            switch( iCmdParameters.iCommandType )
                {
                case CCalenCmdLineParser::EStartTypeDate: 
                case CCalenCmdLineParser::EStartTypeDay:  
                case CCalenCmdLineParser::EStartTypeToday:
                    {
                    command = ECalenDayView;
                    viewUid = KUidCalenDayView;
                    }
                    break;
                case CCalenCmdLineParser::EStartTypeToDo:
                    {
                    command = ECalenTodoView;
                    viewUid = KUidCalenTodoView;
                    }
                    break;
                case CCalenCmdLineParser::EStartTypeWeek:
                    {
                    command = ECalenWeekView;
                    viewUid = KUidCalenWeekView;
                    }
                    break;
                case CCalenCmdLineParser::EStartTypeMonth:
                    {
                    command = ECalenMonthView;
                    viewUid = KUidCalenMonthView;
                    }
                    break;             
                default:
                    {
                    ASSERT( 0 );
                    }
                }                     	
             
          	  context.SetFocusDateAndTimeL( focusTime,
                                         TVwsViewId( KUidCalendar, viewUid ) );
          	//Themes effect while launching.
          	GfxTransEffect::BeginFullScreen( AknTransEffect::EApplicationStart,TRect(), AknTransEffect::EParameterType, AknTransEffect::GfxTransParam(KCalendarUid,
          	AknTransEffect::TParameter::EActivateExplicitContinue ) );
          	
            if( iController.ViewManager().ViewsActivated() )
                {
                if(command == ECalenDayView)
                    {
                    iController.BroadcastNotification(ECalenNotifyCalenLaunchedFromExtApp);
                    }
                iController.IssueCommandL( command );
                iController.SetLaunchFromExternalApp( ETrue );
                }
            else
                {
                iController.ViewManager().ActivateDefaultViewL( viewUid );                
                // Comment the following line when the the calendar.exe file is removed
                // from the startup list.
                iController.ViewManager().ActivateLocalViewL(viewUid);                
                }            
            }
            break;
            
        case CCalenCmdLineParser::EStartTypeUid:
        case CCalenCmdLineParser::EStartTypeUidViewer:
        case CCalenCmdLineParser::EStartTypeUidAlarmViewer:
        case CCalenCmdLineParser::EStartTypeUidAlarmViewerNoSnooze:
	        {
	        
	        aUseViewerIfAvailable = ETrue;
	        iIsExitOnDlgClose = ETrue;
	        // Set context using local uid before launching this entry in the Event view or Editor 	       
            SetContextBeforeLaunchL();  
            
            if (aUseViewerIfAvailable
#ifdef RD_NO_EDIT_REPEATING_TODO_DAYNOTE    
    			 || iForceUseViewer
#endif // RD_NO_EDIT_REPEATING_TODO_DAYNOTE
        		)
        		{
		        if( iCmdParameters.iCommandType == CCalenCmdLineParser::EStartTypeUidAlarmViewer )
              		{
                    //When event viewer launched from alarm only we need to ignore tap. (ETrue)     
		            iController.BroadcastNotification(ECalenNotifyCalenLaunchedFromExtApp);
              		if(! iController.ViewManager().ViewsActivated() )                    
                        {
                        iController.ViewManager().ActivateDefaultViewL( KUidCalenEventView); 
                        }
                        // start in alarm viewer mode
                        iController.IssueCommandL( ECalenEventViewFromAlarm );
                    }
                else if( iCmdParameters.iCommandType == CCalenCmdLineParser::EStartTypeUidAlarmViewerNoSnooze )
                    {
                    //When event viewer launched from alarm only we need to ignore tap. (ETrue)     
                    iController.BroadcastNotification(ECalenNotifyCalenLaunchedFromExtApp);
                    if(! iController.ViewManager().ViewsActivated() )                    
                        {
                        iController.ViewManager().ActivateDefaultViewL( KUidCalenEventView);   
                        }                    
                    // start in alarm viewer mode (snooze key not available)
                    iController.IssueCommandL(  ECalenEventViewFromAlarmStopOnly );
                    }
                	// Activate the Event view 
                else 
                    {  
                    if( iController.ViewManager().ViewsActivated() )                    
                        {
                        iController.IssueCommandL( ECalenEventView );
                        iController.SetLaunchFromExternalApp( ETrue );
                        }
                    else
                        {
                        iController.ViewManager().ActivateDefaultViewL( KUidCalenEventView);
                        }
                    }
		        }
		    else
		        {
		        iController.IssueCommandL( ECalenEditCurrentEntry );
		        } 
		                      
		    }
            break;          
                    
       
        case CCalenCmdLineParser::EStartTypeNewMeeting:
        case CCalenCmdLineParser::EStartTypeNewMeetingRequest:
        case CCalenCmdLineParser::EStartTypeNewAnniv:
        case CCalenCmdLineParser::EStartTypeNewTodo:
            {
            // Activate the day view but send calendar to the background.  This handles the
            // case of a command line launch to a non existent entry uid.
            // A side effect of this is we will get an unwanted view activation notification
            // which we need to ignore.
            // See also StartEditorL and HandleViewActivation
            context.SetFocusDateAndTimeL( focusTime,
                                          TVwsViewId( KUidCalendar, KUidCalenDayView ) );

            if(!( iController.ViewManager().ViewsActivated()) )
                {
                iController.ViewManager().ActivateDefaultViewL( KUidCalenDayView );
                }
                
            CEikonEnv::Static()->RootWin().SetOrdinalPosition( -1, 0 );                
            useLaunchCallback = ETrue;
            } 
            break;
        default:  // Launched from app list
            {
            context.SetFocusDateAndTimeL( focusTime,
                                          TVwsViewId( KUidCalendar, KUidCalenMonthView /*uid*/ ) );

            useLaunchCallback = ETrue;
            break;
            }
        }

    if( useLaunchCallback )
        {
        // Issue the callback
        if( !iCalendarLaunchCallBack )
            {
            TCallBack callback( StaticCalendarLaunchCallBack, this );
            iCalendarLaunchCallBack = new( ELeave ) CAsyncCallBack( callback, 
                                                                                    CActive::EPriorityStandard );
            }
            // otherwise issue the callback immediately
            iCalendarLaunchCallBack->CallBack();
        }

    TRACE_EXIT_POINT;
    return ETrue;
    }

// ----------------------------------------------------------------------------
// CCalenCmdLineLauncher::StaticCalendarLaunchCallBack
// Called from processcommand parameters using CAsyncCallBack
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
TInt CCalenCmdLineLauncher::StaticCalendarLaunchCallBack( TAny* aObject )
    {
    TRACE_ENTRY_POINT;

    CCalenCmdLineLauncher* thisPtr( static_cast<CCalenCmdLineLauncher*>( aObject ) );

    TRACE_EXIT_POINT;
    return thisPtr->CalendarLaunchCallBack();
    }

// ----------------------------------------------------------------------------
// CCalenCmdLineLauncher::CalendarLaunchCallBack
// Called by StaticCalendarLaunchCallBack, traps leaving version
// of function and handles any errors.
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
TInt CCalenCmdLineLauncher::CalendarLaunchCallBack()
    {
    TRACE_ENTRY_POINT;

    TInt returnValue = 0;
    TRAPD( error, returnValue = CalendarLaunchCallBackL() );

    if ( error != KErrNone )
        {
        if ( iIsExitOnDlgClose )
           {
           // If there has been an error, gracefully exit.
           TRAPD(error,AppUi().ProcessCommandL( EAknSoftkeyExit ));
           if(error!=KErrNone)
           		{
        		// do avoid warning
        		}
           }
        }

    TRACE_EXIT_POINT;    
    return returnValue;
    }

// ----------------------------------------------------------------------------
// CCalenCmdLineLauncher::CalendarLaunchCallBack
// Called from processcommand parameters using CAsyncCallBack
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
TInt CCalenCmdLineLauncher::CalendarLaunchCallBackL()
    {
    TRACE_ENTRY_POINT;

    // When entering this function, the Calendar window group
    // should be at ordinal -1.  
    // When opening to a new entry editor, we should restore the
    // window group to ordinal 0 before calling EditNewEntryL
    
    if( iCmdParameters.iFlag )
        {
        iIsExitOnDlgClose = EFalse;
        }
    else
        {
        iIsExitOnDlgClose = ETrue;
        }

    RWindowGroup& windowGroup = CCoeEnv::Static()->RootWin(); 

    switch( iCmdParameters.iCommandType )
        {       

        case CCalenCmdLineParser::EStartTypeNewMeeting:
            // Launch a new entry editor
            windowGroup.SetOrdinalPosition( 0, 0 );
            iController.IssueCommandL( ECalenNewMeeting );
            break;

        case CCalenCmdLineParser::EStartTypeNewMeetingRequest:
            windowGroup.SetOrdinalPosition( 0, 0 );
            // Launch a new meeting request editor
            iController.IssueCommandL( ECalenNewMeetingRequest );
            break;

        case CCalenCmdLineParser::EStartTypeNewAnniv:
            windowGroup.SetOrdinalPosition( 0, 0 );
            // Launch a new anniversary editor
            iController.IssueCommandL( ECalenNewAnniv );
            break;

        case CCalenCmdLineParser::EStartTypeNewTodo:
            windowGroup.SetOrdinalPosition( 0, 0 );
            // Launch a new Todo editor
            iController.IssueCommandL( ECalenNewTodo );
            break;

        default:
            iIsExitOnDlgClose = EFalse;
            break;
        }

    TRACE_EXIT_POINT;
    return KLeaveExit;
    }

// ----------------------------------------------------------------------------
// CCalenCmdLineLauncher::HandleNotification
// Handles notifications
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
 void CCalenCmdLineLauncher::HandleNotification(const TCalenNotification aNotification )
    {
    TRACE_ENTRY_POINT;

	if( aNotification == ECalenNotifyInstanceDeleted || aNotification == ECalenNotifyEntryDeleted )
		{
		// Exit when event is deleted from EventView
		if( iCmdParameters.iCommandType == CCalenCmdLineParser::EStartTypeUid 
			|| iCmdParameters.iCommandType == CCalenCmdLineParser::EStartTypeUidViewer
			|| iCmdParameters.iCommandType == CCalenCmdLineParser::EStartTypeUidAlarmViewer
			|| iCmdParameters.iCommandType == CCalenCmdLineParser::EStartTypeUidAlarmViewerNoSnooze)
			{ 
			if(iIsExitOnDlgClose)
			    {
		   
			    PIM_TRAPD_HANDLE( AppUi().ProcessCommandL(EAknSoftkeyExit) );	
			    iIsExitOnDlgClose = EFalse;
			    }
			}
		}
	else if(iIsExitOnDlgClose && (aNotification == ECalenNotifyDialogClosed) )
	    {
            //dont do any thing
            //This scenario hits, when the application launched from device search application,
            //User issued a "Cancel" command while adding attachment. 
	    }
    else if(aNotification == ECalenNotifyEntryClosed)
    	{
        // Exit when Escape pressed in Eventview
    	if(iIsExitOnDlgClose)
            {
            PIM_TRAPD_HANDLE( AppUi().ProcessCommandL(EAknSoftkeyExit) );
           // iIsExitOnDlgClose = EFalse;
            }
        }
    else if( iIsExitOnDlgClose )
        {
        PIM_TRAPD_HANDLE( AppUi().ProcessCommandL(EAknSoftkeyExit) );
        }
    else if(aNotification == ECalenNotifySettingsClosed)
        {
        PIM_TRAPD_HANDLE( AppUi().ProcessCommandL(EAknSoftkeyExit) );
        } 
    else
        {
        
        }
    TRACE_EXIT_POINT;
    }
 
 // ----------------------------------------------------------------------------
 // CCalenCmdLineLauncher::SetExitOnDialogclose
 // (other items were commented in a header).
 // ----------------------------------------------------------------------------
 //
 void CCalenCmdLineLauncher::SetExitOnDialogclose( TBool aIsExitOnDlgClose )
     {
     iIsExitOnDlgClose = aIsExitOnDlgClose;
     }
 
 // ----------------------------------------------------------------------------
 // CCalenCmdLineLauncher::GetExitOnDialogStatus
 // (other items were commented in a header).
 // ----------------------------------------------------------------------------
 //
 TBool CCalenCmdLineLauncher::GetExitOnDialogStatus()
     {
     return iIsExitOnDlgClose; 
     }

// ----------------------------------------------------------------------------
// CCalenCmdLineLauncher::SetContextBeforeLaunchL
// Set context using local uid before lauching Event view or Editor.
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CCalenCmdLineLauncher::SetContextBeforeLaunchL()
    {
    TRACE_ENTRY_POINT;

    TCalLocalUid uid( iCmdParameters.iLocalUid );
    TCalCollectionId collectionId = iGlobalData->CalSessionL( iCmdParameters.iCalenFileName ).CollectionIdL();
    CCalEntry* entry = iGlobalData->EntryViewL( collectionId )->FetchL( uid );

    // if entry is found we will open it, otherwise we just exit.
    User::LeaveIfNull( entry );

    CleanupStack::PushL( entry );

    TTime instanceTime;
    TCalTime inscaltime;

            instanceTime = CalenAgendaUtils::EntryTimeL( *entry );
            inscaltime.SetTimeLocalL( instanceTime );
        

    // No editing of repeating todos or day notes. Always use the viewer for these.
    

#ifdef RD_NO_EDIT_REPEATING_TODO_DAYNOTE
    
    CCalEntry::TType type = entry->EntryTypeL();
    if( type == CCalEntry::ETodo || type == CCalEntry::EEvent )
        {
        TCalRRule rrule;
        if( entry->GetRRuleL( rrule ) )
            {
            iForceUseViewer = ETrue;
            }
        else
            {
            // Also repeating if has rdates.
            RArray<TCalTime> rdates;
            CleanupClosePushL( rdates );
            entry->GetRDatesL( rdates );
            if( rdates.Count() )
                {
                iForceUseViewer = ETrue;
                }
            CleanupStack::PopAndDestroy( &rdates );
            }
        }
#endif // RD_NO_EDIT_REPEATING_TODO_DAYNOTE

    MCalenContext &context = iGlobalData->Context();
    TCalenInstanceId id = TCalenInstanceId::CreateL( *entry, inscaltime );
    id.iColId = collectionId;
    context.SetInstanceIdL( id, TVwsViewId( KUidCalendar, KUidCalenEventView ) ); 

    CleanupStack::PopAndDestroy( entry );

    TRACE_EXIT_POINT;
    }

// ----------------------------------------------------------------------------
// CCalenCmdLineLauncher::AppUi
// Get reference of CAknViewAppUi
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//    
CAknViewAppUi& CCalenCmdLineLauncher::AppUi()
    {
    TRACE_ENTRY_POINT;
    
    return iAppUi;
    
    TRACE_EXIT_POINT;
    }

// End of File