calendarui/editors/src/calenunifiededitor.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 10:12:19 +0200
changeset 0 f979ecb2b13e
child 5 42814f902fe6
permissions -rw-r--r--
Revision: 201003 Kit: 201005

/*
* Copyright (c) 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 : Class description for unified editor
*
*/

// user includes
#include "calenunifiededitor.h"
#include "CalenDefaultEditors.hrh"
#include "calenglobaldata.h"
#include "calenunifiededitorcontrol.h"
#include "calendbfield.h"
#include "calenlocationutil.h"
#include "CalenEntryUpdater.h"
#include "CalenEditorDataHandler.h"
#include "calenentryutil.h"
#include "calensend.h"
#include "CalenDescription.h"
#include "calenattachmentinfo.h"
#include "calenattachmentmodel.h"
#include "CleanupResetAndDestroy.h"
#include "CalendarPrivateCRKeys.h"

// system includes
#include <coemain.h>
#include <eikdialg.h>
#include <bacntf.h>
#include <eikspane.h>
#include <akntitle.h>
#include <aknnavi.h>
#include <eikcapc.h>
#include <StringLoader.h>
#include <featmgr.h>
#include <hlplch.h>
#include <AknQueryDialog.h>
#include <AknUtils.h>
#include <AknIconUtils.h>
#include <aknlayoutscalable_apps.cdl.h>
#include <eikrted.h>
#include <txtrich.h>
#include <aknnotewrappers.h>
#include <sysutil.h>
#include <ErrorUI.h>
#include <EPos_CPosLandmark.h>
#include <lbsposition.h>
#include <calentry.h>
#include <CalenDefaultEditorsData.rsg>
#include <Calendar.rsg>
#include <calenagendautils.h> // Need to conform the access.
#include <calrrule.h>
#include <calendateutils.h>
#include <CalenInterimUtils2.h>
#include <centralrepository.h>
#include <calencommands.hrh>            // Calendar commands
#include <calencontext.h>
#include <caleninstanceid.h>            // TCalenInstanceId
#include <calenservices.h>
#include <calcalendarinfo.h>

// debug
#include "calendarui_debug.h"

const TInt KCalenMaxELAFTextEditorLength(160);
const TInt KCalenMaxAPACTextEditorLength(70);

// Custom id for command to close form without any checks.
// We need just to close form without saving, when entry is deleted from options menu
const TInt KCalenButtonIdCloseForm(-400);

_LIT(KComma, ",");
_LIT(KEmpty,"");
_LIT(KAttachmentSeparator,"; ");

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//  
CCalenUnifiedEditor* CCalenUnifiedEditor::NewL( CCalEntry& aEntry,
                                                const TAgnEntryUiInParams& aParams,
                                                MAgnEntryUiCallback& aCallback,
                                                TAgnEntryUiOutParams& aOutParams,
                                                CalCommon::TRecurrenceRange aRepeatType)
    {
    TRACE_ENTRY_POINT;
    
    CCalenUnifiedEditor* self = 
        new (ELeave) CCalenUnifiedEditor( aEntry, aParams, aCallback, aOutParams, aRepeatType );
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop();
    
    TRACE_EXIT_POINT;
    return self;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CCalenUnifiedEditor* CCalenUnifiedEditor::NewL( CCalEntry& aEntry,
                                                const TAgnEntryUiInParams& aParams,
                                                MAgnEntryUiCallback& aCallback,
                                                TAgnEntryUiOutParams& aOutParams )
    {
    TRACE_ENTRY_POINT;

    CCalenUnifiedEditor* self = 
        new (ELeave) CCalenUnifiedEditor( aEntry, aParams, aCallback, aOutParams );
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop();
    
    TRACE_EXIT_POINT;
    return self;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::~CCalenUnifiedEditor
// Destructor
// -----------------------------------------------------------------------------
//
CCalenUnifiedEditor::~CCalenUnifiedEditor()
    {
    TRACE_ENTRY_POINT;

    if( iGlobalData )
        {
        iGlobalData->Release();
        }
    
    // Remove default status pane
    if( iNaviContainer )
        {
        iNaviContainer->Pop();
        iNaviContainer = NULL;
        }
    
    if( iIdle )
        {
        delete iIdle;
        }
    iCoeEnv->RemoveFepObserver( *this );
    
    if( iServices )
        {
        iServices->CancelNotifications( this );
        }
    delete iLocaleChangeNotifier;
    delete iOriginalCalEntry;
    delete iEditorDataHandler;
    delete iEntryUpdater;
    delete iUnifiedEditorControl;
    
    iCollectionIds.Reset();

    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::CCalenUnifiedEditor
// Default constructor
// -----------------------------------------------------------------------------
//
CCalenUnifiedEditor::CCalenUnifiedEditor( CCalEntry& aEntry,
                     const TAgnEntryUiInParams& aParams,
                     MAgnEntryUiCallback& aCallback,
                     TAgnEntryUiOutParams& aOutParams,
                     CalCommon::TRecurrenceRange aRepeatType )
                : iEditedCalEntry( aEntry ), iEntryUiInParams( aParams ), 
                iEntryUiCallback( aCallback ), iEntryUiOutParams( aOutParams ),
                iRepeatType( aRepeatType ), iEntryType( aEntry.EntryTypeL() ),
                iHasChosenRepeatType( ETrue ), iIgnoreFirstLocaleChange( ETrue ),
                iCurrentDurationDay( 0 ), iTwoSeconds( 2 )


    {
    TRACE_ENTRY_POINT;
    
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::CCalenUnifiedEditor
// Default constructor
// -----------------------------------------------------------------------------
//
CCalenUnifiedEditor::CCalenUnifiedEditor( CCalEntry& aEntry,
                     const TAgnEntryUiInParams& aParams,
                     MAgnEntryUiCallback& aCallback,
                     TAgnEntryUiOutParams& aOutParams )
                : iEditedCalEntry( aEntry ), iEntryUiInParams( aParams ),
                iEntryUiCallback( aCallback ), iEntryUiOutParams( aOutParams ),
                iRepeatType( CalCommon::EThisAndAll ),
                iEntryType( aEntry.EntryTypeL() ),
                iHasChosenRepeatType( EFalse ),
                iIgnoreFirstLocaleChange( ETrue ),
                iCurrentDurationDay( 0 ), iTwoSeconds( 2 )

                
    {
    TRACE_ENTRY_POINT;
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::ConstructL
// Second phase construction
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::ConstructL()
    {
    TRACE_ENTRY_POINT;
    
    // Construct dialog
    CAknDialog::ConstructL( R_CALEN_UNIFIED_EDITOR_MENUBAR );
    
    // Take a timestamp of the editors opening time - 2 seconds
    // We use this to compare against the last database change time
    // to determine if the current entry has been deleted through
    // another CCalSession
    iTimeStamp.UniversalTime();
    
    iGlobalData = CCalenGlobalData::InstanceL( iEntryUiInParams.iCalSession );
    
    iOriginalCalEntry = CCalenUnifiedEditor::CreateCopyL( iEditedCalEntry );
    
    // Setup title and status panes
    CEikStatusPane* sp = iEikonEnv->AppUiFactory()->StatusPane();
    CAknTitlePane* tp = static_cast<CAknTitlePane*>( sp->ControlL( TUid::Uid(EEikStatusPaneUidTitle) ) );
    HBufC* titleText = StringLoader::LoadLC( R_QTN_CALE_UNIFIED_EDITOR_TITLE, iCoeEnv );
    tp->SetTextL( *titleText );
    CleanupStack::PopAndDestroy( titleText );
    
    // Put default, empty Status Pane.
    iNaviContainer = static_cast<CAknNavigationControlContainer *>( sp->ControlL(TUid::Uid(EEikStatusPaneUidNavi) ) );
    iNaviContainer->PushDefaultL();
     
    // Connect to services, and register for notifications of
    // changes to the database.
    TInt services( iEntryUiInParams.iSpare );
    iServices = reinterpret_cast< MCalenServices* >( services );
    
    RArray<TCalenNotification> notificationArray;
    notificationArray.Append( ECalenNotifyEntryDeleted );
    notificationArray.Append( ECalenNotifyInstanceDeleted );
    notificationArray.Append( ECalenNotifyDeleteFailed );
    notificationArray.Append( ECalenNotifyEntryInstanceViewCreated );
    notificationArray.Append( ECalenNotifyExternalDatabaseChanged );
    notificationArray.Append( ECalenNotifyMapClosed );
    notificationArray.Append( ECalenNotifyAttachmentAdded );
    notificationArray.Append( ECalenNotifyAttachmentRemoved );
    notificationArray.Append( ECalenNotifyCalendarFileDeleted );
    
    
    iServices->RegisterForNotificationsL( this, notificationArray );
    notificationArray.Reset();
    
    GetAllCollectionidsL(iCollectionIds);
    
    iEditorDataHandler = CCalenEditorDataHandler::NewL( iEditedCalEntry,
                                               iEntryUiInParams.iInstanceDate,
                                               IsCreatingNewEntry(),
                                               MaxTextEditorLength(),
                                               *iServices , iCollectionIds);
    iEntryUpdater = CCalenEntryUpdater::NewL( *iServices , iCollectionIds);
    
    

    //iServices->EntryViewL(iServices->Context().InstanceId().iColId);

    iUnifiedEditorControl = CCalenUnifiedEditorControl::NewL( *this,*iServices );
    
    isReplaceLocation = EFalse;
    
    iIdle = CIdle::NewL( CActive::EPriorityUserInput );
    iIdle->Start( TCallBack( KeyCallBack, this) );
    iCoeEnv->AddFepObserverL( *this );
    
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::ExecuteViewL
// Dummy implementation. Use ExecuteLD() instead.
// -----------------------------------------------------------------------------
//
TInt CCalenUnifiedEditor::ExecuteViewL( RPointerArray<CCalEntry>& /*aEntries*/,
                                        const TAgnEntryUiInParams& /*aInParams*/,
                                        TAgnEntryUiOutParams& /*aOutParams*/,
                                        MAgnEntryUiCallback& /*aCallback*/ )
    {
    TRACE_ENTRY_POINT;
    TRACE_EXIT_POINT;
    return KErrNone;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::SetHelpContext
// Sets the help context.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::SetHelpContext( const TCoeHelpContext& /*aContext*/ )
    {
    TRACE_ENTRY_POINT;
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::HandleNotification
// Handles calendar notifications
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::HandleNotification( TCalenNotification aNotification )
    {
    TRACE_ENTRY_POINT;
    
    switch( aNotification )
        {
        case ECalenNotifyExternalDatabaseChanged:
            {
            iLastDbChangeNotification.UniversalTime();
            }
            break;
        case ECalenNotifyEntryDeleted:
            {
            iEntryUiOutParams.iAction = MAgnEntryUi::EMeetingDeleted;
            PIM_TRAPD_HANDLE( CloseFormWithoutActionsL() );
            }
            break;
        case ECalenNotifyInstanceDeleted:
            {
            iEntryUiOutParams.iAction = MAgnEntryUi::EInstanceDeleted;
            PIM_TRAPD_HANDLE( CloseFormWithoutActionsL() );
            }
            break;
        case ECalenNotifyMapClosed:
            {
            // User has closed the map, store/update necessary details
            PIM_TRAPD_HANDLE( UpdateLocationInfoToFormL() );
            }
            break;
        case ECalenNotifyDeleteFailed:
            {
            iEntryUiOutParams.iAction = MAgnEntryUi::ENoAction;
            }
            break;
        case ECalenNotifyAttachmentAdded:
        case ECalenNotifyAttachmentRemoved:    
            {
            // TODO: Uncomment this when enabling attachment support
            PIM_TRAPD_HANDLE( UpdateAttachmentInfoToEditorL() );
            }
            break;
    
        case ECalenNotifyEntryInstanceViewCreated:
            break;
        case ECalenNotifyCalendarFileDeleted:
            {
            TPtrC fileNamePtr = iServices->Context().GetCalendarFileNameL();
            if(!fileNamePtr.CompareF(iUnifiedEditorControl->GetCalendarNameForEntryL()))
                {
                DisplayErrorMsgL( CCalenEditorDataHandler::EFormErrDbConflictEntryDeleted );
                iEntryUiOutParams.iAction = EMeetingDeleted;
                TryExitL( KCalenButtonIdCloseForm );
                }
            }
            break;
        default:
            break;
        }
    
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::InsertFieldL
// Inserts dialog line (form field) defined by aResourceI
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::InsertFieldL( TInt aResourceId, TInt aControlId,
                                        TInt aPrevControlId )
    {
    TRACE_ENTRY_POINT;

    CCoeControl* prevControl = Control( aPrevControlId );
    __ASSERT_DEBUG( prevControl, User::Invariant() );
    TInt pos = FindLineIndex( *prevControl );
    pos = pos + 1;
    InsertLineL( pos, aResourceId );
    
    // We need to activate line, otherwise drawing doesn't work correctly
    Line( aControlId )->ActivateL();
    
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::HasField
// Check for field exists in unified editor
// -----------------------------------------------------------------------------
//
TBool CCalenUnifiedEditor::HasField( TInt aField )
    {
    TRACE_ENTRY_POINT;
    TRACE_EXIT_POINT;
    return ControlOrNull( aField ) != NULL;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::UpdateFormL
// Update form. You can force update of form with this,
// if you modify some of the field values dynamically. 
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::UpdateFormL()
    {
    TRACE_ENTRY_POINT;
    
    UpdatePageL(ETrue);
    
    TRACE_EXIT_POINT;
    }

// --------------------------------------------------------------------------
// CreateCopyL
// Create a copy of the given entry.
// --------------------------------------------------------------------------
//
CCalEntry* CCalenUnifiedEditor::CreateCopyL( CCalEntry& aOther )
    {
    TRACE_ENTRY_POINT;

    HBufC8* guid = aOther.UidL().AllocLC();
    CCalEntry* entry;
    if( aOther.RecurrenceIdL().TimeUtcL() != Time::NullTTime() )
        {
        entry = CCalEntry::NewL( aOther.EntryTypeL(), guid,
                                 aOther.MethodL(),
                                 aOther.SequenceNumberL(),
                                 aOther.RecurrenceIdL(),
                                 aOther.RecurrenceRangeL() );
        }
    else
        {
        entry = CCalEntry::NewL( aOther.EntryTypeL(), guid,
                                 aOther.MethodL(),
                                 aOther.SequenceNumberL() );
        }
    CleanupStack::Pop( guid ); // ownership was passed
    CleanupStack::PushL( entry );
    aOther.DescriptionL();  // make sure entry is fully loaded
    entry->CopyFromL( aOther );
    entry->DescriptionL();  // make sure entry is fully copied
    CleanupStack::Pop( entry );

    TRACE_EXIT_POINT;
    return entry;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::OkToExitL
// Handles exiting of the unified editor
// -----------------------------------------------------------------------------
//
TBool CCalenUnifiedEditor::OkToExitL( TInt aButtonId )
    {
    TRACE_ENTRY_POINT;
    TBool isExitForm( ETrue );
    TBool active = EFalse;
	
    TCalCollectionId colId = iEditorDataHandler->CurrentDbCollectionId(); 
    VerifyCollectionIdL(colId);
    
	TInt newCtrlId=IdOfFocusControl();
    switch ( aButtonId )
        {
        case EAknSoftkeyChange:
            {
            isExitForm=EFalse;

            // to Handle MSK key 'Change'
			if(newCtrlId == ECalenEditorEventType || newCtrlId == ECalenEditorRepeat
			                                      || newCtrlId == ECalenEditorDBName
			                                      || newCtrlId == ECalenEditorPriority)
				{
				
	            CEikCaptionedControl* line=CurrentLine();
	            TInt type=line->iControlType;
	            TBool isPopUp=( type && EAknCtPopupField ) || ( type == EAknCtPopupFieldText );
	            if (isPopUp)
	                {
	                CAknPopupField* ctrl = static_cast<CAknPopupField*>( line->iControl );
	                ctrl->ActivateSelectionListL();
	                }
				}
			else if( newCtrlId == ECalenEditorReminder ) 
                {
                if( iUnifiedEditorControl->IsAlarmActiveInForm() )
                    { 
                    SetAlarmFieldOnOffL( EFalse );           
                    active = EFalse;
                    } 
                else
                    {
                    SetAlarmFieldOnOffL( ETrue );                
                    active = ETrue;
                    }
                iUnifiedEditorControl->CheckAlarmActive( active );
                TryChangeFocusToL( ECalenEditorReminder );
                }
            else if( newCtrlId == ECalenEditorAllDayItem )
                {
                if( iUnifiedEditorControl->IsAllDayEvent() )
                    {
                    SetAllDayFieldL( EFalse );
                    active = EFalse;
                    }
                else
                    {
                    SetAllDayFieldL( ETrue );
                    active = ETrue;
                    }
                iUnifiedEditorControl->SetAllDayEvent( active );
                
                }
            break;
            }
        case EAknSoftkeyOptions:
            {
            DisplayMenuL();
            isExitForm = EFalse;
            break;
            }
        case KCalenButtonIdCloseForm:
            {
            // Do nothing, just close.
            // This is called when entry is deleted
            // via menu or clearing texts
            isExitForm = ETrue;
            break;
            }
        case ECalenCmdCloseDialog:
             {
             // Forced close of the dialog when calendar is reopened from the 
             // command line.  We do not want to update calendars stored focus
             // in case we override any command line parameters
             // Intentional fall through to EEikBidCancel below
             iEntryUiOutParams.iAction = ENoAction;
             iEntryUiOutParams.iSpare = 0;
             // Fall through...
             }
         case ECalenEditSeries:
         case ECalenEditOccurrence:
         case EAknCmdExit:
         case EEikBidCancel:
             {
             // EEikBidCancel is called when Red End key is pressed or
             // MMC card is taken out or application is killed via Swap Window
             // EAknCmdExit is called, when user selects Options->Exit
             //   (see OnCmdExit)

             // At this point, CAknShutter fires us EEikBidCancel key events
             // offering it to our dialog control. Firing key events continues
             // until our dialog is closed, which is detected by FW.                    

             // Entry can't be stored if EntryView does not exist. 
             // Will exit and lose some data if entry was really edited.
            
             if( iServices->EntryViewL(colId) )
                 {
                 PIM_TRAPD_HANDLE( TryToSaveNoteOnForcedExitL() );
                 }
             break;
             }
         case EAknSoftkeyDone:
             {
             // Need an entry view before starting to
             // handle the done button. 
             if( iServices->EntryViewL(colId) )
                 {
                 isExitForm = HandleDoneL();
                 }
             else
                 {
                 // The entry view has not been constructed yet
                 //iCreatingEntryView = EFalse;
                 isExitForm = EFalse;
                 } 
             }
             break;
         case ECalenGetLocation:
        	{
        	// Issue command to framework to launch the map
        	isExitForm=EFalse;
        	ReadPlaceFromEditorL(); // to remove any picture characters in location string
            TBuf<ECalenAbsoluteMaxTextEditorLength> location;
            GetEdwinText(location, ECalenEditorPlace);
            CCalGeoValue* geoValue = iEditorDataHandler->Entry().GeoValueL();
            if(geoValue)
                {
                CPosLandmark* landmark = CPosLandmark::NewL();
                landmark->SetLandmarkNameL(location);
                TReal latitude;
                TReal longitude;
                geoValue->GetLatLong(latitude, longitude);
                TPosition position;
                position.SetCoordinate(latitude, longitude);
                landmark->SetPositionL(position);
                delete geoValue;
                MCalenContext& context = iServices->Context();
                context.SetLandMark(landmark);
                }
            else if(location.Length())
                {
                CPosLandmark* landmark = CPosLandmark::NewL();
                landmark->SetLandmarkNameL(location);
                MCalenContext& context = iServices->Context();
                context.SetLandMark(landmark);
                }
            iServices->IssueCommandL(ECalenGetLocation);
        	}
            break;
         default:
             isExitForm = EFalse;
             break;
        }
    TRACE_EXIT_POINT;
    return isExitForm;
    }
          
// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::OfferKeyEventL
// Handles key events
// -----------------------------------------------------------------------------
//
TKeyResponse CCalenUnifiedEditor::OfferKeyEventL( const TKeyEvent& aKeyEvent,
                                                  TEventCode aType )
    {
    TRACE_ENTRY_POINT;
    TBool isMapIconHandled = EFalse;
    TKeyResponse keyResponse( EKeyWasNotConsumed );
    TInt ctrlid=IdOfFocusControl();
   
    /* If KeyCallBack has not been called after construction 
     * (= initialization of iIdle) call it now to 
     * handle key event queue.
     */
    if ( iIdle )
        {
        KeyCallBack( this );
        }
    
    if ( aType == EEventKey )
        {
        switch ( aKeyEvent.iCode )
            {
            case EKeyOK:
                // TODO: Uncomment this when enabling attachment support
                
                if(ctrlid == ECalenEditorAttachment)
                    {
                    if(Edited().AttachmentCount() || iServices->GetAttachmentData()->NumberOfItems())
                        {
                        iServices->IssueCommandL( ECalenViewAttachmentList );
                        }
                    }
                break;
            case EKeyEscape:
                // Calendar relaunched from cmd line - close viewer
                // NOTE: This was changed from EAknCmdExit to ECalenCmdCloseDialog since launching
                // the calanedar from cmd line or opening missed alarm view while calendar editor is
                // opened is closing the application.
                TryExitL( ECalenCmdCloseDialog );
                keyResponse = EKeyWasConsumed;
                break;
            case EKeyEnter: // For Enter key
				{
				keyResponse = CAknForm::OfferKeyEventL(aKeyEvent,aType); // Let framework handle the key event
				// when enter key is pressed on subject line or on location line, call AddPictureL to recalculate the map icon position properly
				// as location field could habe moved up or down
				if(ctrlid == ECalenEditorPlace || ctrlid == ECalenEditorSubject)
					{
					CCalGeoValue* geoValue = iEditorDataHandler->Entry().GeoValueL();
					if(geoValue)
						{
						isMapIconHandled = ETrue;
						AddPictureL();
						delete geoValue;
						}
					}
				}
				break;
			case EKeyDelete:
				{
				if(ctrlid == ECalenEditorPlace)
					{
					CCalGeoValue* geoValue = iEditorDataHandler->Entry().GeoValueL();
					if(geoValue)
						{
						CEikRichTextEditor* locationControl = static_cast<CEikRichTextEditor*>(Control(ECalenEditorPlace));
						CRichText* text = locationControl->RichText();
						TPtrC ptr = text->Read(0,text->DocumentLength());
						TInt pos = ptr.Locate(TChar(CEditableText::EPictureCharacter));
						if(locationControl->CursorPos() == pos)
							{
							isMapIconHandled = ETrue;
							keyResponse = EKeyWasConsumed;
							delete geoValue;
							break;
							}
						delete geoValue;
						}
					}
					keyResponse = CAknForm::OfferKeyEventL(aKeyEvent,aType); // Let framework handle the key event
				}
				break;
			case EKeyBackspace:  // For back space character
				{
				if(ctrlid == ECalenEditorPlace)
					{
					CCalGeoValue* geoValue = iEditorDataHandler->Entry().GeoValueL();
					if(geoValue)
						{
						CEikRichTextEditor* locationControl = static_cast<CEikRichTextEditor*>(Control(ECalenEditorPlace));
						CRichText* text = locationControl->RichText();
						TPtrC ptr = text->Read(0,text->DocumentLength());
						TInt pos = ptr.Locate(TChar(CEditableText::EPictureCharacter));
						TInt curpos = locationControl->CursorPos();
						
						// When only one visible character is there and picture byte is there at second position, then
						// empty the location field and redraw the map icon
						if(text->DocumentLength() <= 2) 
							{
							TBuf<1> newLocation;
							SetEdwinTextL(ECalenEditorPlace, &newLocation);
							keyResponse = EKeyWasConsumed;
							delete geoValue;
							isMapIconHandled = ETrue;
							AddPictureL();
							break;
							}
						//  when cursor position is at the end, then since, picture byte is at the end
						// delete last but one character (for user, it looks as if last visible character is being deleted)
						// and redraw the icon
						 else if( curpos == pos + 1)
							{
							text->DeleteL(text->DocumentLength() - 2,1);
							
							AddPictureL();
							locationControl->SetCursorPosL(curpos - 1, EFalse);
							isMapIconHandled = ETrue;
							keyResponse = EKeyWasConsumed;
							delete geoValue;
							break;
							}
						delete geoValue;
						}
					}
				// This is to handle backspaces in subject field when there nore that one lines,
				// location field will move up, hence, need to redraw the map icon
				else if(ctrlid == ECalenEditorSubject)
					{
					keyResponse = CAknForm::OfferKeyEventL(aKeyEvent,aType);
					CCalGeoValue* geoValue = iEditorDataHandler->Entry().GeoValueL();
					if(geoValue)
						{
						AddPictureL();
						isMapIconHandled = ETrue;
						delete geoValue;
						}
					break;
					}
				}
            case EKeyLeftArrow:
            case EKeyRightArrow:
                {
                if( ECalenEditorEventType == IdOfFocusControl() )
                    {
                    keyResponse = EKeyWasConsumed; 
                    }
                else
                    {
                    keyResponse = CAknForm::OfferKeyEventL( aKeyEvent, aType );    
                    }
                }
                break;
 
            default:
                {
                keyResponse = CAknForm::OfferKeyEventL(aKeyEvent,aType); 
                if(!isMapIconHandled)
                    {
                    if((ctrlid == ECalenEditorPlace) || (ctrlid == ECalenEditorSubject))
                        {
                        CCalGeoValue* geoValue = iEditorDataHandler->Entry().GeoValueL();
                        if(geoValue)
                            {
                            isMapIconHandled = ETrue;
                            AddPictureL();
                            delete geoValue;
                            }
                        }
                    }
                }
                break;
            }
        }
        
    // For handling geokeys on corolla hardware
	// For Add location hard key
	if( aKeyEvent.iScanCode == EStdKeyApplication1C && aType == EEventKeyUp )
		{
		if(CCalenLocationUtil::IsMapProviderAvailableL())
			{
			TryChangeFocusToL(ECalenEditorPlace);
			ReadPlaceFromEditorL(); // to remove any picture characters in location string
			TBuf<ECalenAbsoluteMaxTextEditorLength> location;
			GetEdwinText(location, ECalenEditorPlace);
			CPosLandmark* landmark = NULL;
			if(location.Length())
				{
				landmark = CPosLandmark::NewL();
				landmark->SetLandmarkNameL(location);
				}
				CCalGeoValue* geoValue = iEditorDataHandler->Entry().GeoValueL();
				if(geoValue)
					{
					if(!landmark)
						{
						landmark = CPosLandmark::NewL();
						}
					TReal latitude;
					TReal longitude;
					geoValue->GetLatLong(latitude, longitude);
					TPosition position;
					position.SetCoordinate(latitude, longitude);
					landmark->SetPositionL(position);
					delete geoValue;
					}
				MCalenContext& context = iServices->Context();
				context.SetLandMark(landmark);	
			iServices->IssueCommandL(ECalenGetLocation);
			keyResponse = EKeyWasConsumed;
			}
		}
	// For Show location hard key
	else if( aKeyEvent.iScanCode == EStdKeyApplication1B && aType == EEventKeyUp )
		{
		ReadPlaceFromEditorL();
		TBuf<ECalenAbsoluteMaxTextEditorLength> location;
		GetEdwinText(location, ECalenEditorPlace);
		if(CCalenLocationUtil::IsMapProviderAvailableL())
			{
			TryChangeFocusToL(ECalenEditorPlace);
			MCalenContext& context = iServices->Context();
			CCalGeoValue* geoValue = iEditorDataHandler->Entry().GeoValueL();
			if(geoValue)
				{
				CPosLandmark* landmark = CPosLandmark::NewL();
				landmark->SetLandmarkNameL(location);
				TReal latitude;
				TReal longitude;
				geoValue->GetLatLong(latitude, longitude);
				TPosition position;
				position.SetCoordinate(latitude, longitude);
				landmark->SetPositionL(position);
				context.SetLandMark(landmark);
				iServices->IssueCommandL(ECalenShowLocation);
				delete geoValue;
				}
			else if(location.Length())
				{
				CPosLandmark* landmark = CPosLandmark::NewL();
				landmark->SetLandmarkNameL(location);
				context.SetLandMark(landmark);
				isReplaceLocation = ETrue;
				iServices->IssueCommandL(ECalenGetLocation);
				}
			keyResponse = EKeyWasConsumed;
			}
		}
		
		// Swallow all other keyevents to prevent the active container processing them.
    keyResponse = EKeyWasConsumed;

    TRACE_EXIT_POINT;
    return keyResponse;    
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::HandleCompletionOfTransactionL
// Is called when fep transaction has been completed. If this
// happens before key event queue has been simulated, events in 
// key buffer must be ignored. If key events are simulated after this
// result is duplicate characters or wrong order of characters.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
void CCalenUnifiedEditor::HandleCompletionOfTransactionL()
    {
    TRACE_ENTRY_POINT;
    if( iIdle )
        {
        delete iIdle;
        iIdle = NULL;
        iServices->ResetKeyEventQueue();/*ignore all events*/
        }
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::KeyCallBack
// Handles key events in key event queue
// (other items were commented in a header).
// -----------------------------------------------------------------------------
TInt CCalenUnifiedEditor::KeyCallBack( TAny *aSelf )
    {
    TRACE_ENTRY_POINT;
    CCalenUnifiedEditor *self = static_cast<CCalenUnifiedEditor*>( aSelf );
    delete self->iIdle;
    self->iIdle = NULL;

    TKeyEvent event;
    TEventCode type;

    while( self->iServices->GetQueuedKeyEvent( event, type ) )
        {
        TRAPD(err,
              self->iCoeEnv->SimulateKeyEventL( event, type );
              );
        if ( err != KErrNone )
            {
            CEikEdwin* edwin = static_cast<CEikEdwin*>( self->Control( self->IdOfFocusControl() ) );
            edwin->CancelFepTransaction(); // indispensable to avoid crash
            self->iCoeEnv->HandleError( err );
            }
        }
    TRACE_EXIT_POINT;
    return EFalse;
    }

// -----------------------------------------------------------------------------
//  CCalenUnifiedEditor::LocaleCallback
//  This function is called when a locale(or today) is changed.
// -----------------------------------------------------------------------------
//
TInt CCalenUnifiedEditor::LocaleCallback( TAny* aThisPtr ) // A CCalenFormBase pointer
    {
    TRACE_ENTRY_POINT;
    CCalenUnifiedEditor* unifiededitor = static_cast<CCalenUnifiedEditor*>( aThisPtr );

    if( unifiededitor->iIgnoreFirstLocaleChange )
        {
        // Ignore the first locale change so we don't rebuild for no reason.
        unifiededitor->iIgnoreFirstLocaleChange = EFalse;
        TRACE_ENTRY_POINT;
        return EFalse;
        }

    TRACE_EXIT_POINT;
    return unifiededitor->HandleLocaleChange( unifiededitor->iLocaleChangeNotifier->Change() );
    }

// -----------------------------------------------------------------------------
//  CCalenUnifiedEditor::HandleLocaleChange
//  CCalenUnifiedEditor::LocaleCallback() methods calls this method
// -----------------------------------------------------------------------------
//
TInt CCalenUnifiedEditor::HandleLocaleChange( TInt aChange )
    {
    TRACE_ENTRY_POINT;
    
    PIM_TRAPD_HANDLE( DoHandleLocaleChangeL( aChange ) );
    
    TRACE_EXIT_POINT;
    return FALSE;    
    }

// -----------------------------------------------------------------------------
//  CCalenUnifiedEditor::DoHandleLocaleChange
//  HandleLocaleChange calls this function
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::DoHandleLocaleChangeL( TInt aChange )
    {
    TRACE_ENTRY_POINT;

    if( aChange & EChangesSystemTime )
        {
        // System time zone change.  Recreate the handler, so that
        // the new local time is shown in the viewer.
        if( !IsCreatingNewEntry() )
            {
            if( !iEditorDataHandler->IsEditedL() )
                {
                delete iEditorDataHandler;
                iEditorDataHandler = NULL;
                iEditorDataHandler = CCalenEditorDataHandler::NewL( iEditedCalEntry,
                                                  iEntryUiInParams.iInstanceDate,
                                                  IsCreatingNewEntry(),
                                                  MaxTextEditorLength(),
                                                  *iServices ,iCollectionIds);
                }
            else
                {
                iEditorDataHandler->ResetOriginalDataL();
                }
            }
        iUnifiedEditorControl->SetDataToEditorL();
        }

    if ( aChange & EChangesLocale )
        {
        iUnifiedEditorControl->ReadDataFromEditorL( ETrue );
        iUnifiedEditorControl->UpdateLinesOnLocaleChangeL();
        }
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::PreLayoutDynInitL
// Initializes the dialog's controls before the dialog is sized
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::PreLayoutDynInitL()
    {
    TRACE_ENTRY_POINT;

    iUnifiedEditorControl->MakeUnifiedEditorL();
    // Hides Entry type and Calendar Field for exceptional entry/single
    // instance of recurrent entry.
    HideFieldsForEditSingleInstance();

    TRACE_EXIT_POINT;         
    }
        
// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::PostLayoutDynInitL
// Initializes the dialog's controls after the dialog has been sized 
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::PostLayoutDynInitL()
    {
    TRACE_ENTRY_POINT;
    
    SetEditableL(ETrue);
    CCalGeoValue* geoValue = iEditorDataHandler->Entry().GeoValueL();
	if(geoValue)
		{
		AddPictureL();	
		delete geoValue;	
		}
    TCallBack callback( LocaleCallback, this );
    iLocaleChangeNotifier =
        CEnvironmentChangeNotifier::NewL( EActivePriorityLogonA, callback );

    iLocaleChangeNotifier->Start();
    
    TRACE_EXIT_POINT;     
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::HandleControlStateChangeL
// IHandles a state change in the control with id aControlId.
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::HandleControlStateChangeL( TInt aControlId )
    {
    TRACE_ENTRY_POINT;
    
    iUnifiedEditorControl->HandleControlStateChangeL( aControlId );
    
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::PrepareForFocusTransitionL
// Tries to change focus to the specified line.
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::PrepareForFocusTransitionL()
    {
    TRACE_ENTRY_POINT;
    
    CEikDialog::PrepareForFocusTransitionL();
    
    iUnifiedEditorControl->PrepareForFocusTransitionL( IdOfFocusControl() );

    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::ActivateL
// Try to change item focus here 
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::ActivateL()
    {
    TRACE_ENTRY_POINT;
    
    CAknForm::ActivateL();
    TryChangeFocusToL( ECalenEditorSubject );
    
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::ProcessCommandL
// Handles editor menu commands
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::ProcessCommandL( TInt aCommandId )
    {
    TRACE_ENTRY_POINT;

    HideMenu();
    switch( aCommandId )
        {
        case ECalenCmdCancel:
            OnCmdCancelL();
            break;
        case ECalenDeleteCurrentEntry:
            OnCmdDeleteNoteL();
            break;
        case EAknCmdExit:
            OnCmdExitL();
            break;
        case EAknCmdHelp:
            OnCmdHelpL();
            break;
        case ECalenSend:
            OnCmdSendL( aCommandId );
            break;
        case ECalenGetLocation:
          {
            ReadPlaceFromEditorL(); // to remove any picture characters in location string
        	TBuf<ECalenAbsoluteMaxTextEditorLength> location;
    		GetEdwinText(location, ECalenEditorPlace);
        	CCalGeoValue* geoValue = iEditorDataHandler->Entry().GeoValueL();
        	if(geoValue)
        		{
        		CPosLandmark* landmark = CPosLandmark::NewL();
        		landmark->SetLandmarkNameL(location);
        		TReal latitude;
				TReal longitude;
				geoValue->GetLatLong(latitude, longitude);
        		TPosition position;
        		position.SetCoordinate(latitude, longitude);
        		landmark->SetPositionL(position);
        		delete geoValue;
        		MCalenContext& context = iServices->Context();
        		context.SetLandMark(landmark);
        		}
        	else if(location.Length())
        	    {
        	    CPosLandmark* landmark = CPosLandmark::NewL();
                landmark->SetLandmarkNameL(location);
                MCalenContext& context = iServices->Context();
                context.SetLandMark( landmark );
                }
                iServices->IssueCommandL( ECalenGetLocation );
            } 
          break;
        case ECalenCmdAddAttachment:
            {
            // TODO: Uncomment this when enabling attachment support
            iServices->IssueCommandL( ECalenAddAttachment );
            }
            break;
        case ECalenCmdViewAttachmentList:
            {
            iServices->IssueCommandL(ECalenViewAttachmentList);
            }
            break;
        case ECalenCmdRemoveAttachment:
            {
            // TODO: Uncomment this when enabling attachment support
            
            TInt attachmentCount = iServices->GetAttachmentData()->NumberOfItems();            
            
            if(Edited().AttachmentCount() || attachmentCount)
                {                                
                iServices->IssueCommandL( ECalenRemoveAttachment );                               
                }
            }
            break;
        default:
            {
            if( iUnifiedEditorControl->Description() )
                {
                iUnifiedEditorControl->Description()->ProcessCommandL( aCommandId );
                } 
            }
            // NOP, pass command through (for FEP etc.)
            break;
        }

    TRACE_EXIT_POINT;     
    }
        
//Single click integration
// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::HandleDialogPageEventL
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::HandleDialogPageEventL( TInt aEventID )
    {
    CAknForm::HandleDialogPageEventL( aEventID );
    if ( aEventID == MEikDialogPageObserver::EDialogPageTapped )
        {
        TInt focusControl( IdOfFocusControl() );
        if ( focusControl == ECalenEditorAttachment
                || focusControl == ECalenEditorDescription )
            {
            
            
                switch ( focusControl )
                    {
                    case ECalenEditorAttachment:
                        {
                        
                        if(Edited().AttachmentCount() || iServices->GetAttachmentData()->NumberOfItems())
                            {
                                ProcessCommandL( ECalenCmdViewAttachmentList );
                            }
                        else
                            {
                                ProcessCommandL( ECalenCmdAddAttachment );
                            }
                        break;
                        }
                    case ECalenEditorDescription:
                        {
                        CEikEdwin* edwin = static_cast<CEikEdwin*>( Control( focusControl ) );  
                        if ( edwin && edwin->Text()->DocumentLength() == 0 )
                            {
                                ProcessCommandL( ECalenCmdAddDescription );
                            }
                        else
                            {
                                ProcessCommandL( ECalenCmdShowDescription );
                            }
                        break;
                        }
                    default:
                        {
                        break;
                        }
                    }
                
            }
        else if ( focusControl == ECalenEditorAllDayItem )
            {
            // Tap on AllDay field, Switch the status of AllDay field  
            iUnifiedEditorControl->SetAllDayEvent(
                    !( iUnifiedEditorControl->IsAllDayEvent() ) );
            }
        else if ( focusControl == ECalenEditorReminder )
            {
            TBool active;
            if( iUnifiedEditorControl->IsAlarmActiveInForm() )
                { 
                SetAlarmFieldOnOffL( EFalse );           
                active = EFalse;
                } 
            else
                {
                SetAlarmFieldOnOffL( ETrue );                
                active = ETrue;
                }
            iUnifiedEditorControl->CheckAlarmActive( active );
            TryChangeFocusToL( ECalenEditorReminder );
            }
        }
    }

// -----------------------------------------------------------------------------
//  CCalenUnifiedEditor::HandleResourceChange
//  Handdles the resource change
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::HandleResourceChange( TInt aType )
    {
    TRACE_ENTRY_POINT;
    
    if( aType == KEikDynamicLayoutVariantSwitch )
        {
        CAknForm::HandleResourceChange( aType );
        }

    CCoeControl::HandleResourceChange( aType );
    
    CCalGeoValue* geoValue = NULL;
	TRAP_IGNORE(geoValue = iEditorDataHandler->Entry().GeoValueL());	
	if(geoValue)
		{
		TRAP_IGNORE(AddPictureL());	
		delete geoValue;	
		}
		
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::DynInitMenuPaneL
// Dynamic initialistaion of menu pane
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::DynInitMenuPaneL( 
        TInt aResourceId, 
        CEikMenuPane* aMenuPane )
    {
    TInt ctrlid=IdOfFocusControl();
    
    switch ( aResourceId )
        {
        case R_CALEN_UNIFIED_EDITOR_MENUPANE:
            {
            // Here we have to call other classes DynInitMenuPaneL
            // in that order that we want items to appear!
            if( ctrlid == ECalenEditorDescription )
                {
                iUnifiedEditorControl->Description()->DynInitMenuPaneL( 
                        aResourceId, 
                        aMenuPane );
                }

            // TODO: Uncomment this when enabling attachment support
            
            if( ctrlid == ECalenEditorAttachment )
                {
                aMenuPane->AddMenuItemsL( R_CALEN_EDITOR_ATTACHMENTS_MENUPANE );
                if( !EntryHasAttachments() )
                    {
                    aMenuPane->DeleteMenuItem( ECalenCmdRemoveAttachment );
                    }
                }
            
            aMenuPane->AddMenuItemsL( R_CALEN_UNIFIED_EDITOR_DEFAULT_MENUPANE );

            if( ( ctrlid != ECalenEditorPlace ) || 
                    ( !CCalenLocationUtil::IsMapProviderAvailableL() ) )
                {
                aMenuPane->DeleteMenuItem( ECalenGetLocation );
                }
            
            if( IsCreatingNewEntry() )
                {
                // Always remove the `Discard Changes' option from the menu-
                // pane when a new entry is being created.
                aMenuPane->DeleteMenuItem( ECalenCmdCancel );
                }
            else
                {
                // While editing, first check if any of the fields have changed.
                // Then check if the entry type field has changed.
                if( !EditorDataHandler().IsEditedL() )
                    {
                    if( !EditorDataHandler().IsEntryTypeEdited() )
                        {
                        aMenuPane->DeleteMenuItem( ECalenCmdCancel );
                        }
                    }
                }
                
            if( !FeatureManager::FeatureSupported( KFeatureIdHelp ) )
                {
                aMenuPane->DeleteMenuItem( EAknCmdHelp );
                }
            
            if( ctrlid != ECalenEditorPeople )
                {
                aMenuPane->DeleteMenuItem( ECalenCmdAddPeople );
                }
            
            TryInsertSendMenuL( aResourceId, aMenuPane );
            }
            break;

        default:
            {
            break;
            }
        }

    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::OnCmdCancelL
// Handles cancel command.
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::OnCmdCancelL()
    {
    TRACE_ENTRY_POINT;

    CAknQueryDialog* dlg = CAknQueryDialog::NewL();
    if( dlg->ExecuteLD( R_CALEN_CANCEL_CHANGES_QUERY ) )
        {
        CloseFormWithoutActionsL();
        }

    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::OnCmdDeleteNoteL
// Handles delete command.
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::OnCmdDeleteNoteL()
    {
    TRACE_ENTRY_POINT;

    TryToDeleteNoteL( ETrue );
    
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::OnCmdSendL
// Handles the send command. This function differs from the ViewerBase version
// in that the ViewerBase does not attempt to save or delete the entry first.
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::OnCmdSendL( TInt aCommandId )
    {
    TRACE_ENTRY_POINT;

    // Show menu to user 
    // CCalenSend handles selection internally, so we don't get anything in return
    iGlobalData->CalenSendL().DisplaySendCascadeMenuL();

    // Try to send
    if ( iGlobalData->CalenSendL().CanSendL(aCommandId) )
        {
        TBool canSend(ETrue);

        const TBool continueOnError = EFalse;
        iUnifiedEditorControl->ReadDataFromEditorL( continueOnError );
        CCalenEditorDataHandler::TAction action =
            EditorDataHandler().ShouldSaveOrDeleteOrDoNothingL();
        if(  action == CCalenEditorDataHandler::EActionSave )
            {
            canSend = TryToSaveNoteL();
            }

        if ( canSend )
            {
            iGlobalData->CalenSendL().SendAsVCalendarL( aCommandId, EditorDataHandler().Entry() );
            }
        }
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::OnCmdHelpL
// Handles help command.
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::OnCmdHelpL()
    {
    TRACE_ENTRY_POINT;

    if( FeatureManager::FeatureSupported( KFeatureIdHelp ) )
        {
        HlpLauncher::LaunchHelpApplicationL(
            iCoeEnv->WsSession(),
            static_cast<CCoeAppUi*>( iCoeEnv->AppUi() )->AppHelpContextL() );
        }

    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::OnCmdExitL
// Handles exit command.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::OnCmdExitL()
    {
    TRACE_ENTRY_POINT;

    TryExitL( EAknCmdExit );

    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::TryToDeleteNoteL
// Deletes the note from agenda.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::TryToDeleteNoteL( TBool /* aIsViaDeleteMenu */ )
    {
    TRACE_ENTRY_POINT;    
    if (IsCreatingNewEntry())
        {
        iEntryUpdater->TryDeleteInstanceWithUiL( EditorDataHandler().Entry() ,
                                        EditorDataHandler().InstanceDateTime() ,
                                        *iServices );
        }
    else 
        {
        // FIXME. With new MAgnEntryUi we could use MAgnEntryUi::EInstanceDeleted
        iEntryUpdater->TryDeleteInstanceWithUiL( EditorDataHandler().Entry() ,
                                    EditorDataHandler().InstanceDateTime() ,
                                   iRepeatType, *iServices );
        }
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::TryInsertSendMenuL
// Inserts the send menu, if needed.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::TryInsertSendMenuL( TInt aResourceId, CEikMenuPane* aMenuPane )
    {
    TRACE_ENTRY_POINT;

    // Only insert if there is some summary (or location)
    if( !EditorDataHandler().AreTextFieldsEmptyL() )
        {
        // Insert Send menu item
        iServices->OfferMenuPaneL( aResourceId, aMenuPane );
        }
    else
        {// Delete Send Menu item if exists
        aMenuPane->DeleteMenuItem( ECalenSend );
        }    

    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::CloseFormWithoutActionsL
// Closes the form. We have to do it via dialog's exit mechanism
// with custom id (KCalenButtonIdCloseForm).
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::CloseFormWithoutActionsL()
    {
    TRACE_ENTRY_POINT;

    TryExitL( KCalenButtonIdCloseForm );

    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::CreateCustomControlL
// Returns a new custom control.
// -----------------------------------------------------------------------------
//
SEikControlInfo CCalenUnifiedEditor::CreateCustomControlL( TInt aControlType )
    {
    TRACE_ENTRY_POINT;

    __ASSERT_ALWAYS( aControlType==ECalenCtDescriptionField, User::Invariant() );

    TRACE_EXIT_POINT;
    return iUnifiedEditorControl->Description()->CreateFieldL();
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::ConvertCustomControlTypeToBaseControlType
// This method has to be implemented, otherwise custom components do not work with forms.
// -----------------------------------------------------------------------------
//
MEikDialogPageObserver::TFormControlTypes 
    CCalenUnifiedEditor::ConvertCustomControlTypeToBaseControlType( TInt aControlType ) const
    {
    TRACE_ENTRY_POINT;

    if( aControlType == ECalenCtDescriptionField )
        {
        TRACE_EXIT_POINT;
        return MEikDialogPageObserver::EEdwinDerived;
        }

    TRACE_EXIT_POINT;
    return MEikDialogPageObserver::EUnknownType;
    }


// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::AskRepeatingNoteQueriesL
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
CCalenEditorDataHandler::TError CCalenUnifiedEditor::AskRepeatingNoteQueriesL(
    CalCommon::TRecurrenceRange& aRepeatType )
    {
    TRACE_ENTRY_POINT
    CCalenEditorDataHandler::TError error = CCalenEditorDataHandler::EFormErrNone;

    switch( GetEntryType() )
        {
        case CCalEntry::EAnniv:
            {

            if ( ShouldQueryForStartDateChange() )
                {
                // Query for StartDate change
                error = QueryStartDateChangeL();
                }

            TRACE_EXIT_POINT;
            return error;
            }
            //break;           
            
        case CCalEntry::EAppt:
            {
            if ( ShouldQueryForStartDateChange() )
                {
                if ( EditorDataHandler().IsStartDateChanged() )
                    {
                    TRACE_EXIT_POINT;

                    // Query for StartDate change
                    return QueryStartDateChangeL();
                    }
                }

            if( iHasChosenRepeatType )
                {
                // Don't ask the "this/series" question when we have chosen already.
                return error;
                }
            TRACE_EXIT_POINT;
            return iUnifiedEditorControl->AskRepeatingNoteQueriesL(aRepeatType);
            }
            //break;

        case CCalEntry::ETodo:
        case CCalEntry::EEvent:
            {
            TRACE_EXIT_POINT;
            return error;
            }
            //break;  

        default:
            break;
        }
	return error;
    }



TBool CCalenUnifiedEditor::ShouldQueryForStartDateChange()
    {
    TBool shouldQuery = EFalse;
    // For Meeting entry type.
    if( GetEntryType() == CCalEntry::EAppt )
        {
        TRACE_EXIT_POINT;
		shouldQuery = ! IsCreatingNewEntry() &&
            ( Edited().IsRepeating() && EditorDataHandler().Original().IsRepeating() );
        }
    
    // For Anniversary enty type
    if( GetEntryType() == CCalEntry::EAnniv )
        {
        TRACE_EXIT_POINT;
        shouldQuery = ! IsCreatingNewEntry();
        }
	return shouldQuery;
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::QueryStartDateChangeL
// If the entry is repeating, and the edited start date is different from the
// original start date, prompt the user and ask if they are sure they want to
// change the start date of the repeating entry.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
CCalenEditorDataHandler::TError CCalenUnifiedEditor::QueryStartDateChangeL()
    {
    TRACE_ENTRY_POINT;
    TTime oldStartDate = EditorDataHandler().Original().StartDateTime();
    TTime newStartDate = Edited().StartDateTime();

    // The "Are you sure you want to change start date of repeating note?"
    // query should only be shown for repeating notes.
    if ( iRepeatType == CalCommon::EThisAndAll
        && ! CalenDateUtils::OnSameDay( oldStartDate, newStartDate ) )
        {
        CAknQueryDialog* queryDlg = CAknQueryDialog::NewL();
        TInt answer = queryDlg->ExecuteLD( R_CALEN_REPEAT_NOTE_START_CHANGED );
        if (!answer) // Answer "No"
            {
            TRACE_EXIT_POINT;
            return CCalenEditorDataHandler::EFormErrCancelSaveRepNoteWhenStartChange;
            }
        }
    TRACE_EXIT_POINT;
    return CCalenEditorDataHandler::EFormErrNone;
    }
// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::IsCreatingNewEntry
// Returns ETrue if the entry has just been created, EFalse if the entry
// already existed in agenda.
// -----------------------------------------------------------------------------
//
TBool CCalenUnifiedEditor::IsCreatingNewEntry() const
    {
    TRACE_ENTRY_POINT;

    TRACE_EXIT_POINT;
    return iEntryUiInParams.iEditorMode == MAgnEntryUi::ECreateNewEntry;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::MaxTextEditorLength
// Returns the maximum length the text editor can be.
// -----------------------------------------------------------------------------
//
TInt CCalenUnifiedEditor::MaxTextEditorLength() const
    {
    TRACE_ENTRY_POINT;

    switch ( AknLayoutUtils::Variant() )
        {
        case EEuropeanVariant:
            {
            TRACE_EXIT_POINT;
            return KCalenMaxELAFTextEditorLength;
            }
        case EApacVariant:
            {
            TRACE_EXIT_POINT;
            return KCalenMaxAPACTextEditorLength;
            }
        }

    TRACE_EXIT_POINT;
    return 0;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::EditorDataHandler
// Returns the editor data handler.
// -----------------------------------------------------------------------------
//
CCalenEditorDataHandler& CCalenUnifiedEditor::EditorDataHandler()
    {
    TRACE_ENTRY_POINT;

    TRACE_EXIT_POINT;
    return *iEditorDataHandler;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::Edited
// Returns the data being edited.
// -----------------------------------------------------------------------------
//
CCalenEntryUtil& CCalenUnifiedEditor::Edited()
    {
    TRACE_ENTRY_POINT;

    TRACE_EXIT_POINT;
    return iEditorDataHandler->Edited();
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::Original
// Returns the original data.
// -----------------------------------------------------------------------------
//
const CCalenEntryUtil& CCalenUnifiedEditor::Original() const
    {
    TRACE_ENTRY_POINT;

    TRACE_EXIT_POINT;
    return iEditorDataHandler->Original();
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::SetEditorTextL
// Sets editor text
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::SetEditorTextL( TInt aControlId, const TDesC* aDes )
    {
    TRACE_ENTRY_POINT;
    
    SetEdwinTextL( aControlId, aDes );
    
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::ReadSubjectFromEditorL
//  Reads subject field from unified editor
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::ReadSubjectFromEditorL()
    {
    TRACE_ENTRY_POINT;
    
    TBuf<ECalenAbsoluteMaxTextEditorLength> editorText;
    GetEdwinText( editorText,ECalenEditorSubject );
    Edited().SetSummaryL( editorText );
    
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::ReadPlaceFromEditorL
// Reads "Place" item from unified editor
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::ReadPlaceFromEditorL()
    {
    TRACE_ENTRY_POINT;
    
    // Location
    TBuf<ECalenAbsoluteMaxTextEditorLength> location;
    GetEdwinText(location, ECalenEditorPlace);

    TInt pos = location.Locate(TChar(CEditableText::EPictureCharacter));
    while(pos != KErrNotFound)
        {
        location.Delete(pos, 1);
        pos = location.Locate(TChar(CEditableText::EPictureCharacter));
        }

    Edited().SetLocationL( location );
    SetEdwinTextL( ECalenEditorPlace, &location );
    
    TRACE_EXIT_POINT;    
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::SetEntryType
// Sets the unified editor's entry type
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::SetEntryType( CCalEntry::TType aEntryType )
    {
    TRACE_ENTRY_POINT;
    iEntryType = aEntryType;
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::GetEntryType
// Gets unified editor entry type
// -----------------------------------------------------------------------------
//
CCalEntry::TType CCalenUnifiedEditor::GetEntryType()
    {
    TRACE_ENTRY_POINT;
    TRACE_EXIT_POINT;
    return iEntryType;
    }


// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::EditorFields
// Access to the unified editor's fields
// -----------------------------------------------------------------------------
//
CCalenUnifiedEditorControl& CCalenUnifiedEditor::EditorFields()
    {
    TRACE_ENTRY_POINT;
    TRACE_EXIT_POINT;
    return *iUnifiedEditorControl;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::SetAlarmFieldOnOffL
// Set alarm field on or off
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::SetAlarmFieldOnOffL( TBool aOnOff )
    {
    TRACE_ENTRY_POINT;
    
    HBufC* String;
    CEikEdwin* alarmFieldText =( CEikEdwin* )Control( ECalenEditorReminder );
    if( aOnOff )
        {
        // load string 'ON'
        String = StringLoader::LoadLC( R_QTN_ALARM_ACTIVE, iCoeEnv );
        }
    else
        {
        // load string 'OFF'
        String = StringLoader::LoadLC( R_QTN_ALARM_OFF,iCoeEnv );
        }
    // set Alarm field string as 'ON'/'OFF'
    alarmFieldText->SetTextL(String);
    CleanupStack::PopAndDestroy(String);
    
    TRACE_EXIT_POINT;
    } 

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::SetAllDayFieldL
// Set alarm field on or off
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::SetAllDayFieldL(TBool aYesNo)
    {
    TRACE_ENTRY_POINT;
    
    HBufC* String;
    CEikEdwin* allDayFieldText =( CEikEdwin* )ControlOrNull( ECalenEditorAllDayItem );
    if( aYesNo )
        {
        // load string 'YES'
        String = StringLoader::LoadLC( R_QTN_ALLDAY_EVENT_YES,iCoeEnv );
        }
    else
        {
        // load string 'NO'
        String = StringLoader::LoadLC( R_QTN_ALLDAY_EVENT_NO,iCoeEnv );
        }
    if( allDayFieldText )
        {
        // Set AllDay field text as 'YES'/'NO'
        allDayFieldText->SetTextL( String );
        }
    CleanupStack::PopAndDestroy( String );
    
    TRACE_EXIT_POINT;
    } 

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::IdOfFocusedControl
// For getting Id of the focused control
// -----------------------------------------------------------------------------
//
TInt CCalenUnifiedEditor::IdOfFocusedControl()
    {
    TRACE_ENTRY_POINT;
    TRACE_EXIT_POINT;
    return IdOfFocusControl();
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::HandleDoneL
// Handle pressing of Done (LSK). Entry is saved or deleted, or if not edited
// nothing is done.
// -----------------------------------------------------------------------------
//
TBool CCalenUnifiedEditor::HandleDoneL()
    {
    TRACE_ENTRY_POINT;

    const TBool continueOnError = EFalse;
    iUnifiedEditorControl->ReadDataFromEditorL( continueOnError );
    
    TEntryExistenceStatus status = EntryStillExistsL();
    TTimeIntervalDays aDay(0);
    if( iCurrentDurationDay<aDay )
        {
        DisplayErrorMsgL( CCalenEditorDataHandler::EFormErrStopTimeEarlierThanStartTime );
        return EFalse;
        }
    
    if ( status == EEntryOk )
        {
        
        TTime startDate = Edited().StartDateTime();
        TTime endDate = Edited().EndDateTime();
        
        if( startDate == CalenDateUtils::BeginningOfDay( startDate ) &&
                endDate == CalenDateUtils::BeginningOfDay( endDate ) )
            {
            if( CCalEntry::EAppt == Edited().EntryType() && startDate != endDate )
                {
                Edited().SetEntryType( CCalEntry::EEvent );
                }
            }
        
        switch ( EditorDataHandler().ShouldSaveOrDeleteOrDoNothingL() ) 
            {
            case CCalenEditorDataHandler::EActionSave:
                {
                TRACE_EXIT_POINT;
                return TryToSaveNoteL();
                }
            case CCalenEditorDataHandler::EActionDelete:
                {
                TryToDeleteNoteL( EFalse );
                TRACE_EXIT_POINT;
                // don't exit from the editor dialog here
                // wait for the delete success/ delete failed notification
                // exit from CCalenFormBase::HandleNotification( aNotification );
                // return ETrue;
                return EFalse;
                }
            case CCalenEditorDataHandler::EActionNothing:
                {
                TRACE_EXIT_POINT;
                return ETrue;
                }
            }
        }
    else
        {
        if( status == EEntryModifiedByAnotherProcess )
            {
            // Entry no longer exists. Show an error message then return to the viewer.
            DisplayErrorMsgL( CCalenEditorDataHandler::EFormErrDbConflictEntryModified );
            // Other process may have changed start day/time.

            // FIXME
            // Assumes the entry view is not null
            CCalEntry *newEntry = NULL;
            for(TInt i = 0 ; i < iCollectionIds.Count() ; i++)
                {
                newEntry = ( *( iServices->EntryViewL(iCollectionIds[i]) ) )
                                                                .FetchL( iOriginalCalEntry->LocalUidL() );
                }
            
            if(newEntry)
                {
                CleanupStack::PushL( newEntry );
                iEntryUiOutParams.iNewInstanceDate = newEntry->StartTimeL();
                iEntryUiOutParams.iSpare = (TUint32) newEntry->LocalUidL();
                CleanupStack::PopAndDestroy(newEntry);
                iEntryUiOutParams.iAction = EMeetingSaved;
                }
            }
        else
            {
            if( status == EEntryDeletedByAnotherProcess )
                {
                // Entry no longer exists. Show an error message then close the form.
                DisplayErrorMsgL( CCalenEditorDataHandler::EFormErrDbConflictEntryDeleted );
                iEntryUiOutParams.iAction = EMeetingDeleted;
                }            
            }

        TRACE_EXIT_POINT;
        return ETrue;
        }

    // All cases should be handled above
    __ASSERT_ALWAYS( EFalse, User::Invariant() );
    TRACE_EXIT_POINT;
    return EFalse;
    }

// -----------------------------------------------------------------------------
// CheckSpaceBelowCriticalLevelL
// Checks if the Flash File System storage will fall below critical level. 
// If there is not enough space, display an error message and return EFalse.
// Return ETrue otherwise.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TBool CCalenUnifiedEditor::CheckSpaceBelowCriticalLevelL()
    {
    TRACE_ENTRY_POINT;
    // FIXME: Could be moved to commonui 
    TBool retcode(EFalse);

    if ( SysUtil::FFSSpaceBelowCriticalLevelL( &( iCoeEnv->FsSession() ) ) )
        {
        CErrorUI* errorUi = CErrorUI::NewLC();
        errorUi->ShowGlobalErrorNoteL( KErrDiskFull );
        CleanupStack::PopAndDestroy( errorUi ); 
        retcode = ETrue;
        }
    TRACE_EXIT_POINT;
    return retcode;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::TryToSaveNoteL
// Save form data. Return ETrue if saving is successful, EFalse otherwise.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TBool CCalenUnifiedEditor::TryToSaveNoteL()
    {
    TRACE_ENTRY_POINT;
    
    if( CheckSpaceBelowCriticalLevelL() )
        {
        TRACE_EXIT_POINT;
        return EFalse; 
        }
    
    // Check if location field is edited manually
    CheckManualEditionOfLocationL();
    
    
    CCalenEditorDataHandler::TError error = CCalenEditorDataHandler::EFormErrNone;
    
    if( ( !iHasChosenRepeatType && ! EditorDataHandler().IsChildL() ) || 
         (iHasChosenRepeatType && iRepeatType == CalCommon::EThisAndAll ) )
        {
        // Check for the errors, with the entered data
        error = EditorDataHandler().CheckErrorsForThisAndAllL();
        }
    else if( EditorDataHandler().IsChildL() || iRepeatType == CalCommon::EThisOnly )
        {
        // Check for the errors, for editing Child entry.
        error = EditorDataHandler().CheckErrorsForThisOnlyL( ParentEntryL(), *(iServices->InstanceViewL(iCollectionIds) ));
        }

    if ( error == CCalenEditorDataHandler::EFormErrNone )
        {
        error = AskRepeatingNoteQueriesL(iRepeatType);
        if(error == CCalenEditorDataHandler::EFormErrNone)
            {
             iHasChosenRepeatType = ETrue;
            }
        }

    if ( error == CCalenEditorDataHandler::EFormErrNone ) 
        {
		ModifyDbField();//default calendar code
        EditorDataHandler().WriteChangesToEntryL( iRepeatType );
        
        TCalTime newInstanceStartDate, newInstanceEndDate;
        CalculateNewInstanceStartAndEndDateL( newInstanceStartDate, newInstanceEndDate );

        TInt saveErr( 0 );
        TBool dbChange = iEditorDataHandler->IsCalendarEditedL();
        if( iEditedCalEntry.EntryTypeL() != Edited().EntryType() || dbChange )
            {
            // If calendar EntryType is changed,
            // Entry should be re-created with new EntryType and Save.
            saveErr = TryToSaveEntryWithEntryChangeL( EFalse );
            }
        else
            {
            TRAP( saveErr, iEntryUpdater->UpdateInstanceL( 
                       EditorDataHandler().Entry(),
                       *iOriginalCalEntry,
                       EditorDataHandler().InstanceDateTime(),
                       iRepeatType,
                       newInstanceStartDate,
                       newInstanceEndDate,
                       iUnifiedEditorControl->GetCalendarNameForEntryL() ) );

            iEntryUiOutParams.iSpare
                    = (TUint32) EditorDataHandler().Entry().LocalUidL();
            }

        if ( saveErr != KErrNone )
            {
            iEikonEnv->ResolveError( saveErr );
            }
        else
            {
            iEntryUiOutParams.iAction = MAgnEntryUi::EMeetingSaved;
            iEntryUiOutParams.iNewInstanceDate = newInstanceStartDate;
            }
        TRACE_EXIT_POINT;
        return ETrue;
        }

    else
        {
        // If save error occurs, display error message.
        DisplayErrorMsgL( error );
       // HandleErrorL(error);
        TRACE_EXIT_POINT;
        return EFalse;
        }
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::TryToSaveEntryWithEntryTypeChangeL
// Save form data. Return EErrNone if saving is successful, error value otherwise.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//

TInt CCalenUnifiedEditor::TryToSaveEntryWithEntryChangeL( TBool aForcedExit)
    {
    CCalEntry* entry;
    
    //Get the guid from original entry and set it to new entry.
    HBufC8* guid = iOriginalCalEntry->UidL().AllocL();
    

    if( iEditedCalEntry.RecurrenceIdL().TimeUtcL() != Time::NullTTime() )
        {
        entry = CCalEntry::NewL( Edited().EntryType(), 
                                 guid,
                                 iEditedCalEntry.MethodL(),
                                 iEditedCalEntry.SequenceNumberL(),
                                 iEditedCalEntry.RecurrenceIdL(),
                                 iEditedCalEntry.RecurrenceRangeL() );
    
        }
    else
        {
        entry = CCalEntry::NewL( Edited().EntryType(),
                                 guid,
                                 iEditedCalEntry.MethodL(),
                                 iEditedCalEntry.SequenceNumberL() );
    
        }

     //   CleanupStack::Pop( guid ); // ownership was passed

    CleanupStack::PushL( entry );
    iEditedCalEntry.DescriptionL();  // make sure entry is fully loaded
    entry->CopyFromL(iEditedCalEntry, CCalEntry::EDontCopyId);
    entry->DescriptionL();  // make sure entry is fully copied
    
    TCalTime newInstanceStartDate, newInstanceEndDate;
    CalculateNewInstanceStartAndEndDateL( newInstanceStartDate, newInstanceEndDate );
    entry->SetStartAndEndTimeL( newInstanceStartDate, newInstanceEndDate );
    if(iEditedCalEntry.EntryTypeL() != GetEntryType())
        {
        if( entry->EntryTypeL() == CCalEntry::EAnniv )
            {
            // Set yearly rule to Anniversary entry, to create Annaiversary instance yearly 
            TCalRRule rrule( TCalRRule::EYearly );
            TCalTime startDate;
            rrule.SetDtStart( newInstanceStartDate );
            rrule.SetInterval( 1 ); // once a year
            entry->SetRRuleL( rrule );
            }
		}
    
    if(!IsCreatingNewEntry())
        {
        iServices->EntryViewL(iEditorDataHandler->PreviousDbCollectionId())
                                                ->DeleteL(*iOriginalCalEntry);
        }
    
    TInt saveErr( KErrNone );
    if( aForcedExit )
        {
        iEntryUpdater->UpdateInstanceL( 
                *entry,
                *iOriginalCalEntry,
                EditorDataHandler().InstanceDateTime(),
                iRepeatType,
                newInstanceStartDate,
                newInstanceEndDate,
                iUnifiedEditorControl->GetCalendarNameForEntryL() );

        }
    else
        {
        TRAP( saveErr, iEntryUpdater->UpdateInstanceL( 
                   *entry,
                   *iOriginalCalEntry,
                   EditorDataHandler().InstanceDateTime(),
                   iRepeatType,
                   newInstanceStartDate,
                   newInstanceEndDate,
                   iUnifiedEditorControl->GetCalendarNameForEntryL() ) );
        }

    iEntryUiOutParams.iSpare = (TUint32) entry->LocalUidL();

    CleanupStack::PopAndDestroy(entry);
    return saveErr;
    
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::TryToSaveNoteOnForcedExitL
// Try to save note when editors are forced to exit.
// This can happen when the user presses the red key, power off, Options->Exit,
// or in out-of-memory situations.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::TryToSaveNoteOnForcedExitL()
    {
    TRACE_ENTRY_POINT;
    
    if( EntryStillExistsL() == EEntryOk )
        {
        if( CheckSpaceBelowCriticalLevelL() )
            {
            TRACE_EXIT_POINT;
            return;
            }
        
        // Check if location field is edited manually
        CheckManualEditionOfLocationL();

        const TBool continueOnError = ETrue;
        iUnifiedEditorControl->ReadDataFromEditorL( continueOnError );

        CCalenEditorDataHandler::TAction action =
            EditorDataHandler().ShouldSaveOrDeleteOrDoNothingL();
        
        if( iHasChosenRepeatType && iRepeatType == CalCommon::EThisAndAll ) 
        {
        // Check for the errors, with the entered data
            if ( EditorDataHandler().CheckErrorsForThisAndAllL() != KErrNone )
                return;
        }
        if ( action == CCalenEditorDataHandler::EActionSave )
            {
            EditorDataHandler().ForceValidValuesL( iHasChosenRepeatType? iRepeatType 
                                                                                  : CalCommon::EThisAndAll );
            ModifyDbField();//Default Calendar code
            EditorDataHandler().WriteChangesToEntryL( iHasChosenRepeatType? iRepeatType
                                                                                  : CalCommon::EThisAndAll );

            TCalTime newInstanceStartDate, newInstanceEndDate;
            CalculateNewInstanceStartAndEndDateL( newInstanceStartDate, 
                                                                    newInstanceEndDate );
            
            TBool onDbChange = iEditorDataHandler->IsCalendarEditedL();
            if( iEditedCalEntry.EntryTypeL() != GetEntryType() || onDbChange)
                {
                TryToSaveEntryWithEntryChangeL( ETrue );
                }
            else
                {
                iEntryUpdater->UpdateInstanceL( EditorDataHandler().Entry(),
                                                   *iOriginalCalEntry,
                                                   EditorDataHandler().InstanceDateTime(),
                                                   iRepeatType,
                                                   newInstanceStartDate,
                                                   newInstanceEndDate,
                                                   iUnifiedEditorControl->GetCalendarNameForEntryL() );
                }
            }
        else
            {
            if ( action == CCalenEditorDataHandler::EActionDelete )
                {
                // FIXME, should we write date/time changes to entry?
                if ( !IsCreatingNewEntry() )
                    {				
                    if( iHasChosenRepeatType && iRepeatType == CalCommon::EThisOnly )
                        {					
                        iEntryUpdater->DeleteInstanceL( EditorDataHandler().Entry(), EditorDataHandler().CalenInstanceId() );
                        }
                    else
                        {						
                        iEntryUpdater->DeleteEntryL( EditorDataHandler().Entry(), EditorDataHandler().CalenInstanceId() );
                        }
                    }
                }            
            }            
        }
    TRACE_EXIT_POINT;
    }


// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::CalculateNewInstanceStartAndEndDateL
// Calculate the new start and end time and date of the instance.
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::CalculateNewInstanceStartAndEndDateL( TCalTime& aNewInstanceStartDate,
                                                             TCalTime& aNewInstanceEndDate )
    {
    TRACE_ENTRY_POINT;
   
    // Use floating time for non-timed entries 
    if (EditorDataHandler().UseFloatingTimeL())
        {
        aNewInstanceStartDate.SetTimeLocalFloatingL( EditorDataHandler().Edited().StartDateTime() );
        aNewInstanceEndDate.SetTimeLocalFloatingL( EditorDataHandler().Edited().EndDateTime() );
        }
    else
        {
        aNewInstanceStartDate.SetTimeLocalL( EditorDataHandler().Edited().StartDateTime() );
        aNewInstanceEndDate.SetTimeLocalL( EditorDataHandler().Edited().EndDateTime() );
        }
    
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::DisplayErrorMsgL
// Display the given error message.
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::DisplayErrorMsgL( const TInt& aError )
    {
    TRACE_ENTRY_POINT;
    TBool toContinue( ETrue );
    TInt resourceId( -1 );

    switch ( aError )
        {
        case CCalenEditorDataHandler::EFormErrStopTimeEarlierThanStartTime:
            {
            resourceId = R_QTN_CALE_INFO_NOTE_ENDS_BEFORE;
            break;
            }
        case CCalenEditorDataHandler::EFormErrAlarmTimeLaterThanNote:
            {
            resourceId = R_QTN_CALE_LATER_DATE;
            break;
            }
        case CCalenEditorDataHandler::EFormErrAlarmTimePast:
            {
            resourceId = R_QTN_CALE_NOT_EXPIRED;
            break;
            }
        case CCalenEditorDataHandler::EFormErrAlarmDateTooManyDaysBeforeNote:
            {
            resourceId = R_QTN_CALE_DATE_ALARM_PAST;
            break;
            }
        case CCalenEditorDataHandler::EFormErrRepeatUntilEarlierThanNote:
            {
            resourceId = R_QTN_CALE_INFO_REPEAT_INVALID;
            break;
            }
        case CCalenEditorDataHandler::EFormErrDbConflictEntryModified:
            {//"Calendar database conflict. This entry has been modified by another application."
            DisplayErrorMsgInNoteDlgL( R_QTN_CALE_NOTE_DB_MODIFIED );
            toContinue = EFalse;
            break;
            }
        case CCalenEditorDataHandler::EFormErrDbConflictEntryDeleted:
            {//"Calendar database conflict. This entry has been deleted by another application."
            DisplayErrorMsgInNoteDlgL( R_QTN_CALE_NOTE_DB_CONFLICT );
            toContinue = EFalse;
            break;
            }
        case CCalenEditorDataHandler::EFormErrDurationGreaterThanRepeatInterval:
            {
            DispalyErrorMsgByRepeatTypeL();
            toContinue = EFalse;
            break;
            }
        case CCalenEditorDataHandler::EFormErrOverlapsExistingInstance:
            {
            resourceId = R_QTN_CALE_NOTE_CHILD_OVERLAP;
            break;
            }
        case CCalenEditorDataHandler::EFormErrOutOfSequence:
            {
            resourceId = R_QTN_CALE_NOTE_CHILD_OUT_OF_SEQUENCE;
            break;
            }
        case CCalenEditorDataHandler::EFormErrInstanceAlreadyExistsOnThisDay:
            {
            resourceId = R_QTN_CALE_NOTE_CHILD_SAME_DAY;
            break;
            }
        default:
            {
            toContinue = EFalse;
            }
        }
    if( toContinue )
        {
        CAknInformationNote* dialog = new ( ELeave ) CAknInformationNote();
        HBufC* buf = StringLoader::LoadLC( resourceId, iEikonEnv );
        dialog->ExecuteLD( *buf );
        CleanupStack::PopAndDestroy( buf );
        }

    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::ParentEntryL
// Returns the parent entry of the entry being edited.
// -----------------------------------------------------------------------------
//
CCalEntry& CCalenUnifiedEditor::ParentEntryL()
    {
    TRACE_ENTRY_POINT;
    TCalCollectionId colId = iEditorDataHandler->CurrentDbCollectionId(); 
    VerifyCollectionIdL(colId);

    if( iFetchedEntries.Count() == 0 )
        {
        iServices->EntryViewL(colId)
                    ->FetchL( EditorDataHandler().Entry().UidL(), iFetchedEntries );
        }

    TRACE_EXIT_POINT;
    return *iFetchedEntries[0];
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::DisplayErrorMsgInNoteDlgL
// Display conflict error message.
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::DisplayErrorMsgInNoteDlgL( TInt resourceId )
    {
    TRACE_ENTRY_POINT;

    CAknNoteDialog *note = new(ELeave) CAknNoteDialog( CAknNoteDialog::EWarningTone,
                                                       CAknNoteDialog::ENoTimeout );
    HBufC* buf = StringLoader::LoadLC( resourceId, iEikonEnv );
    note->SetTextL( *buf );
    note->ExecuteLD( R_CALEN_DB_CONFLICT_DIALOG );
    CleanupStack::PopAndDestroy( buf );

    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::DisplayErrorMsgByRepeatTypeL
// Display conflict error message.
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::DispalyErrorMsgByRepeatTypeL()
    {
    TRACE_ENTRY_POINT;

    TTimeIntervalDays dur = Edited().EndDateTime().DaysFrom( Edited().StartDateTime() );
    CAknInformationNote* dialog = new (ELeave) CAknInformationNote();
    TInt resourceId( -1 );
    TBool toContinue( ETrue );
    // to find total num of days entry span . 
    TInt numDaysEntrySpan = dur.Int() + 1 ; 
    
    switch( Edited().RepeatType() )
        {
        case ERepeatDaily:
        case ERepeatWorkdays:
            {
            resourceId = R_QTN_CALE_INFO_NOTE_DURATION_TOO_LONG_FOR_DAILY;
            }
            break;
        case ERepeatWeekly:
            {
            resourceId = R_QTN_CALE_INFO_NOTE_DURATION_TOO_LONG_FOR_WEEKLY;
            }
            break;
        case ERepeatBiWeekly:
            {
            resourceId = R_QTN_CALE_INFO_NOTE_DURATION_TOO_LONG_FOR_BIWEEKLY;
            }
            break;
        case ERepeatMonthly:
            {
            resourceId = R_QTN_CALE_INFO_NOTE_DURATION_TOO_LONG_FOR_MONTHLY;
            }
            break;
        case ERepeatYearly:
            {
            resourceId = R_QTN_CALE_INFO_NOTE_DURATION_TOO_LONG_FOR_YEARLY;
            }
            break;
        default:
            toContinue = EFalse;
        }
    if( toContinue )
        {
        HBufC* buf = StringLoader::LoadLC( resourceId,numDaysEntrySpan, iEikonEnv );
        dialog->ExecuteLD( *buf );        
        CleanupStack::PopAndDestroy( buf );
        }
    else
        {
        CleanupStack::PopAndDestroy( dialog );
        }

    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::EntryStillExistsL
// Checks the entry still exists in the database. If the entry has been
// removed or modified, the appropriate action is returned.
// -----------------------------------------------------------------------------
//
CCalenUnifiedEditor::TEntryExistenceStatus CCalenUnifiedEditor::EntryStillExistsL()
    {
    TRACE_ENTRY_POINT;
    TEntryExistenceStatus status = EEntryOk;

    // Check to see if the entry open in the editor still exists
    if ( iLastDbChangeNotification >= iTimeStamp )
        {
        // The database was changed through another session while the editor was open.
        // Search for our entry to check it still exists.
        
        CCalEntry* dbEntry = NULL;
        for(TInt i = 0 ;i < iCollectionIds.Count() ; i++)
            {
            //check the exsists in one of the calendars
            PIM_TRAPD_HANDLE( ( dbEntry = iServices->EntryViewL(iCollectionIds[i])
                                               ->FetchL( iOriginalCalEntry->LocalUidL() ) ) );
            if(dbEntry)
                {
                break;
                }
            }
        
        // I would have thought we could check for KErrNotFound here, but we just get a NULL
        // entry returned if it doesn't exist anymore.
        if ( !dbEntry )
            {
            // The entry we are editing has been deleted.
            status = EEntryDeletedByAnotherProcess;
            }
        else
            {
            CleanupStack::PushL( dbEntry );
            //Check the last modified time of the entry we retrieved from the database
            if ( dbEntry->LastModifiedDateL().TimeUtcL() >= iTimeStamp )
                {
                // This entry has been modified in some way, but not by us.
                // Abandon our changes
                status = EEntryModifiedByAnotherProcess;
                }
            CleanupStack::PopAndDestroy( dbEntry );
            }
        }

    TRACE_EXIT_POINT;
    return status;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::UpdateLocationInfoToFormL
// Updates the user selected landmark details into current meeting editor form 
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::UpdateLocationInfoToFormL()
    {
    TRACE_ENTRY_POINT;
	
	// Get location details from context
	MCalenContext& context = iServices->Context();
	CPosLandmark* landmark = context.GetLandMark();
	TBuf<ECalenAbsoluteMaxTextEditorLength> locationInfo;
	GetEdwinText(locationInfo, ECalenEditorPlace);
	if(landmark) // If user has selected location from Map
		{
		TBuf<ECalenAbsoluteMaxTextEditorLength> location;
		GetEdwinText(location, ECalenEditorPlace);
		CCalGeoValue* geoValue = iEditorDataHandler->Entry().GeoValueL();
		if(geoValue || isReplaceLocation)
			{
			isReplaceLocation = EFalse;
            HandleEntryWithGeoValueEditionL(landmark);
            delete geoValue;	
			}
		else if(locationInfo.Length() && !isReplaceLocation)
		    {
		    HandleEntryWithLocationEditionL(landmark);
		    }
		else // This is the new entry being created and nothing is there in location field
			{
			isReplaceLocation = EFalse;
			StoreLocationDetailsToEntryL(landmark);
			AddPictureL(0);
			}
		}
		
	TRACE_EXIT_POINT;
	}

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::HandleEntryWithGeoValueEditionL
// Shows suery to the user to replace gthe exisitng saved address
// -----------------------------------------------------------------------------
//	
void CCalenUnifiedEditor::HandleEntryWithGeoValueEditionL(CPosLandmark* landmark)
	{
	TRACE_ENTRY_POINT;

	// User is tyring to update the location field of an entry which 
	// already has location text as well as geo coordinates
	TPtrC locationName;
	landmark->GetLandmarkName(locationName);
	TInt userResponse = ShowLocationReplaceNoticeL(locationName);
	if(userResponse)
		{
		StoreLocationDetailsToEntryL(landmark);
		AddPictureL();
		}
		
	TRACE_EXIT_POINT;	
	}

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::HandleEntryWithLocationEditionL
// Shows suery to the user to replace gthe exisitng saved address
// -----------------------------------------------------------------------------
//  
void CCalenUnifiedEditor::HandleEntryWithLocationEditionL(CPosLandmark* landmark)
    {
    TRACE_ENTRY_POINT;

    // User is tyring to update the location field of an entry which 
    // already has location text as well as geo coordinates
    TBuf<ECalenAbsoluteMaxTextEditorLength> locationInfo;
    GetEdwinText(locationInfo, ECalenEditorPlace);
    TPtrC landmarkname;
        landmark->GetLandmarkName(landmarkname);
    RPointerArray<HBufC> locationStrings;
    HBufC* oldLocation = HBufC::NewL(MaxTextEditorLength());
    oldLocation->Des().Copy(locationInfo);
    
    HBufC* oldNewLocation = HBufC::NewL(MaxTextEditorLength());
    TBuf<2*ECalenAbsoluteMaxTextEditorLength> combLocation;
    combLocation.Append(locationInfo);
    combLocation.Append(KComma);
    combLocation.Append(landmarkname);
    oldNewLocation->Des().Copy(combLocation.Left(MaxTextEditorLength()));
    
    HBufC* newLocation = HBufC::NewL(MaxTextEditorLength());
    newLocation->Des().Copy(landmarkname);
    locationStrings.Append(oldNewLocation);
    locationStrings.Append(newLocation);
    locationStrings.Append(oldLocation);
    TInt userResponse = CCalenLocationUtil::ShowLocationAppendOrReplaceL(locationStrings);
    locationStrings.ResetAndDestroy();
    if(userResponse == KErrCancel)
        {
        return;
        }
    switch(userResponse)
        {
        case 0:
            {
            landmark->SetLandmarkNameL(combLocation.Left(MaxTextEditorLength()));
            }
            break;
        case 1:
            {
            landmark->SetLandmarkNameL(landmarkname);
            }
            break;
        case 2:
            {
            landmark->SetLandmarkNameL(locationInfo);
            }
            break;
        default:
            break;
        }
        StoreLocationDetailsToEntryL(landmark);
        AddPictureL(0);
        
    TRACE_EXIT_POINT;   
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::StoreLocationDetailsToEntryL
// Stores landmark details and displays selected location details on the 
// currently shown editor form
// -----------------------------------------------------------------------------
//	
void CCalenUnifiedEditor::StoreLocationDetailsToEntryL(CPosLandmark* landmark)
	{
	TRACE_ENTRY_POINT;
	
	TLocality position;
    landmark->GetPosition(position);
    
    TBuf<ECalenAbsoluteMaxTextEditorLength> existingLocationInfo;
    GetEdwinText(existingLocationInfo, ECalenEditorPlace);
    
     //Store the geo coordinates
    CCalGeoValue* geoValue = CCalGeoValue::NewL();
    geoValue->SetLatLongL( position.Latitude(), position.Longitude() );
    EditorDataHandler().Entry().SetGeoValueL( *geoValue );
    delete geoValue;
    
    TBuf<ECalenAbsoluteMaxTextEditorLength> locationDetails;
    TPtrC landmarkname;
    landmark->GetLandmarkName( landmarkname );
    locationDetails.Append( landmarkname );
    
    TPtrC landmarkDesc;
    landmark->GetLandmarkDescription( landmarkDesc );
    if( landmarkDesc.Size() )
        {
        locationDetails.Append( KComma );
        locationDetails.Append( landmarkDesc );
        }
    
    Edited().SetLocationL( locationDetails.Left( MaxTextEditorLength()) );

    TPtrC location = Edited().Location().Left( MaxTextEditorLength() );
    EditorDataHandler().Entry().SetLocationL( location );

	SetEdwinTextL(ECalenEditorPlace, &location);
	if(existingLocationInfo.Length())
        {
        ShowAddressUpdatedNoticeL();
        }
	 
	PreLayoutDynInitL();
	
	TRACE_EXIT_POINT;	
	}
	
// ----------------------------------------------------------------------------
// CCalenUnifiedEditor::ShowLocationReplaceNoticeL
// Function to query user whether to replace or keep existing location details
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
TInt CCalenUnifiedEditor::ShowLocationReplaceNoticeL(TPtrC aLocationName)
	{
	TRACE_ENTRY_POINT;
	
	CAknQueryDialog *dialog = CAknQueryDialog::NewL( );
    CleanupStack::PushL( dialog );
    TInt resID = R_CALEN_QTN_REPLACE_LOCATION;
    
    TBuf<ECalenAbsoluteMaxTextEditorLength> location;
    TChar quote = '"';
    location.Append(quote);
    location.Append(aLocationName);
    location.Append(quote);
    
    CEikonEnv* eikEnv = CEikonEnv::Static();
    
     HBufC* prompt = StringLoader::LoadLC( resID, location, eikEnv );
	
	dialog->SetPromptL( *prompt );
    CleanupStack::PopAndDestroy( prompt );

    CleanupStack::Pop( dialog );
	
	return dialog->ExecuteLD( R_CALEN_LOCATION_REPLACE_NOTE );
	
	TRACE_EXIT_POINT;	
	}
	
// ----------------------------------------------------------------------------
// CCalenUnifiedEditor::ShowAddressUpdatedNoticeL
// Displays "Address Updated" transient notice
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//  
void CCalenUnifiedEditor::ShowAddressUpdatedNoticeL()
    {
    HBufC* buf = StringLoader::LoadLC( R_CALEN_QTN_ADDRESS_UPDATED, CEikonEnv::Static() );
    CAknConfirmationNote* dialog = new( ELeave ) CAknConfirmationNote();
    dialog->ExecuteLD(*buf);
    CleanupStack::PopAndDestroy( buf );     
    }

// -----------------------------------------------------------------------------
//  CCalenUnifiedEditor::CheckManualEditionOfLocationL
//  Checks if user has edited location field manually
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::CheckManualEditionOfLocationL()
    {
    TRACE_ENTRY_POINT;
    
    CCalEntry& entry = EditorDataHandler().Entry();
    CCalGeoValue* geoValue = entry.GeoValueL();
    if( !geoValue )
        {
        return;
        }
    delete geoValue;
    
    TPtrC entryLocation = entry.LocationL();    
    TBuf<ECalenAbsoluteMaxTextEditorLength> location;
    location.Copy(Edited().Location());
    
    if( entryLocation != location )
        {
        // USer has manually edited the location field
        TInt response = ShowLocationChangeNoticeL();
        if( !response )
            {
            // Clear the geo coordinates for the entry
            entry.ClearGeoValueL();
            Edited().SetLocationL( location );
            EditorDataHandler().Entry().SetLocationL(location);
            SetEdwinTextL(ECalenEditorPlace, &location);
            }
        else
            {
            EditorDataHandler().Entry().SetLocationL(location);   
            }
        }
        
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
//  CCalenUnifiedEditor::ShowLocationChangeNoticeL
//  Queries user whether to keep the exisiting coordianates or not
// -----------------------------------------------------------------------------
//  
TInt CCalenUnifiedEditor::ShowLocationChangeNoticeL()
    {
    TRACE_ENTRY_POINT;
    
    CAknQueryDialog *dialog = CAknQueryDialog::NewL( );
    CleanupStack::PushL( dialog );
    TInt resID = R_CALEN_QTN_GEOVALUES_REMOVAL;
    
    HBufC* prompt;
    prompt = StringLoader::LoadLC( resID, iCoeEnv );
    dialog->SetPromptL( *prompt );
    CleanupStack::PopAndDestroy( prompt );
    CleanupStack::Pop( dialog );
    
    return dialog->ExecuteLD( R_CALEN_GEOVALUES_REMOVAL_NOTE ); 
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::UpdateAttachmentInfoToEditorL
// Update attachment info to editor whenever an file is selected
// -----------------------------------------------------------------------------
// 
void CCalenUnifiedEditor::UpdateAttachmentInfoToEditorL()
    {
    TRACE_ENTRY_POINT;
    const TDesC& emptyText = KEmpty;
    SetEdwinTextL(ECalenEditorAttachment, &emptyText);
    
    TInt attachmentCount = iServices->GetAttachmentData()->NumberOfItems();
    if( attachmentCount )
        {
        RPointerArray<CCalenAttachmentInfo> attachmentInfoList;      
        iServices->GetAttachmentData()->GetAttachmentListL(attachmentInfoList);
        
        TInt attachmentLength(0);
        for( TInt index =0; index<attachmentCount; index++ )
            {
            if(index>0)
                {
                attachmentLength++;
                }
            CCalenAttachmentInfo* attachmentInfo = attachmentInfoList[index];
            TParsePtrC fileNameParser( attachmentInfo->FileName() );
            attachmentLength += fileNameParser.NameAndExt().Length();
            }
        
        // Additional space is for appending "; " after each attachment to separate multiple attachments
        HBufC* attachmentNames = HBufC::NewLC( attachmentLength + 
                                             ( attachmentCount - 1 ) * KAttachmentSeparator.iTypeLength );
        CleanupStack::Pop( attachmentNames );
        TPtr ptr( attachmentNames->Des() );
        for( TInt index=0; index<attachmentCount; index++ )
            { 
            if( index>0 )
                {
                ptr.Append( KAttachmentSeparator );
                }
            CCalenAttachmentInfo* attachmentInfo = attachmentInfoList[index];
            TParsePtrC fileNameParser( attachmentInfo->FileName()) ;
            ptr.Append( fileNameParser.NameAndExt() );
            }
        
        SetUnderLineForAttachmentL( EUnderlineOn );
        SetEdwinTextL( ECalenEditorAttachment, &ptr );
        delete attachmentNames;
        
        attachmentInfoList.Close();
        UpdateFormL();
        }
    
    // Update the attachment cound in editedentryutil as attachment would have added or deleted
    CheckForAttachmentsInEditorL();
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::SetUnderLineForAttachmentL
// Sets the undeline for the attachment field's text
// -----------------------------------------------------------------------------
// 
void CCalenUnifiedEditor::SetUnderLineForAttachmentL( TFontUnderline aUnderLine )
    {
    TRACE_ENTRY_POINT;
    
    CEikRichTextEditor* attachmentControl = static_cast<CEikRichTextEditor*>(
                                                Control( ECalenEditorAttachment ) );
    TCharFormat charFormat;
    TCharFormatMask charFormatMask;
    charFormatMask.SetAttrib( EAttFontUnderline );
    charFormat.iFontPresentation.iUnderline = aUnderLine;
    
    attachmentControl->ApplyCharFormatL( charFormat,charFormatMask );
    attachmentControl->HandleTextChangedL();
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::GetAttachmentNamesString
// Merges individual attachment names into a single string
// -----------------------------------------------------------------------------
// 
void CCalenUnifiedEditor::GetAttachmentNamesString( RPointerArray<HBufC>& aAttachmentNames,
                                                    HBufC& aAttachmentNamesString)
    {
    TRACE_ENTRY_POINT;
   TInt attachmentCount = aAttachmentNames.Count();        
   TPtr ptr( aAttachmentNamesString.Des() );
   for( TInt index=0; index<attachmentCount; index++ )
       { 
       if( index>0 )
           {
           ptr.Append( KAttachmentSeparator );
           }
       ptr.Append( aAttachmentNames[index]->Des() );
       }
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::CheckForAttachmentsInEditorL
// Check for attachments in editor,if present save the attachment count which is
// used while saving the attachments to the calentry
// -----------------------------------------------------------------------------
// 
void CCalenUnifiedEditor::CheckForAttachmentsInEditorL()
    {
    TRACE_ENTRY_POINT;
    
    TInt attachmentCount = iServices->GetAttachmentData()->NumberOfItems();
    Edited().SetAttachmentCount( attachmentCount );
    
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::SetAttachmentNamesToEditorL
// Set attachment names to the editor,if entry is already having the attachments
// and is being opened in editor
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::SetAttachmentNamesToEditorL()
    {
    TRACE_ENTRY_POINT;
    TInt attachmentCount = Edited().AttachmentCount();
    if( attachmentCount )
        {
        RPointerArray<HBufC> attachmentNames;
        Edited().AttachmentNamesL(attachmentNames);
        TInt attachmentCount = attachmentNames.Count();
        TInt attachmentLength(0);
        for( TInt index =0; index<attachmentCount; index++ )
            {
            if(index>0)
                {
                attachmentLength++;
                }
            
            attachmentLength += attachmentNames[index]->Length();
            // We need two extra spaces for adding "; " between multiple attachments
            attachmentLength += KAttachmentSeparator.iTypeLength;
            }
        
        HBufC* attachmentNamesString = HBufC::NewLC( attachmentLength );
        CleanupStack::Pop( attachmentNamesString );
        GetAttachmentNamesString(attachmentNames, *attachmentNamesString);
        
        SetUnderLineForAttachmentL( EUnderlineOn );
        SetEdwinTextL( ECalenEditorAttachment, attachmentNamesString );
        
        // Cleanup
        delete attachmentNamesString;
        attachmentNames.ResetAndDestroy();
        }
    
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::EntryHasAttachments
// check whether the entry has attachments or not
// -----------------------------------------------------------------------------
//
TBool CCalenUnifiedEditor::EntryHasAttachments()
    {
    TRACE_ENTRY_POINT;
    TBool attachmentExists(EFalse);
    TInt attachmentCountFromModel = iServices->GetAttachmentData()->NumberOfItems();
    if( Edited().AttachmentCount() || attachmentCountFromModel )
        {
        attachmentExists = ETrue;
        }
    TRACE_EXIT_POINT;
    
    return attachmentExists;
    }

// -----------------------------------------------------------------------------
// CCalenController::GetAllCollectionidsL
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::GetAllCollectionidsL(
                                           RArray<TInt>& aCollectionIds)
    {
    TRACE_ENTRY_POINT
    RPointerArray<CCalCalendarInfo> calendarInfoList;
    CleanupClosePushL(calendarInfoList);
    iServices->GetAllCalendarInfoL(calendarInfoList);
    
    for(TInt index=0;index<calendarInfoList.Count();index++)
        {
        aCollectionIds.Append( iServices->SessionL( 
               calendarInfoList[index]->FileNameL() ).CollectionIdL() );
        }
    
    CleanupStack::PopAndDestroy(&calendarInfoList);
    TRACE_EXIT_POINT
    }
// -----------------------------------------------------------------------------
// From CEikDialog
// We will hit this event each time a line has changed in the form
// -----------------------------------------------------------------------------
// 
void CCalenUnifiedEditor::LineChangedL( TInt /* aControlId */ )
    {
    TRACE_ENTRY_POINT;
    
    CCalGeoValue* geoValue = iEditorDataHandler->Entry().GeoValueL();
	if(geoValue)
		{
		AddPictureL();	
		delete geoValue;	
		}
		
    SetMskFromResourceL();
    TRACE_EXIT_POINT;
    }


// -----------------------------------------------------------------------------
// Update CBA with corresponding MSK button.
// This function is e.g. called from HanleControlEvent()
// Will issue HandleControlStateChangeL() call.
// -----------------------------------------------------------------------------
// 
void CCalenUnifiedEditor::SetMskFromResourceL()
    {
    TRACE_ENTRY_POINT;
    CEikButtonGroupContainer&  cba = ButtonGroupContainer ();
        TInt resid=0;
        TInt ctrlid=IdOfFocusControl();

        switch( ctrlid )
            {

            // for these fields we use change button
            case ECalenEditorReminder:    /* fall through... */
            case ECalenEditorRepeat:     /* fall through... */
                
                resid=R_CALEN_MSK_CHANGE_CBA;
                break;
            // for description field it is open
            case ECalenEditorDescription:
               // resid=R_CALEN_MSK_OPEN_CBA;
               // break;
            // for location field
            case ECalenEditorPlace:
                if(CCalenLocationUtil::IsMapProviderAvailableL())
                    {
                    resid = R_CALEN_MSK_FROMMAP_CBA;    
                    }
                else
                    {
                    resid=R_CALEN_MSK_EMPTY_CBA;    
                    }
                break;
            // otherwise use empty MSK
            case ECalenEditorSubject:            /* fall through... */
            case ECalenEditorReminderDate:    
            case ECalenEditorReminderTime:    /* fall through... */
            case ECalenEditorEndDate:          /* fall through... */
            case ECalenEditorEndTime:
            case ECalenEditorDueDate:
            case ECalenEditorStartDate:
            case ECalenEditorStartTime:
            case ECalenEditorBirthDayYear:                
            default:
                resid=R_CALEN_MSK_EMPTY_CBA;
                break;

            case ECalenEditorRepeatUntil:      
			case ECalenEditorAllDayItem:
			case ECalenEditorEventType:
			case ECalenEditorDBName:
			case ECalenEditorPriority:
				resid=R_CALEN_MSK_CHANGE_CBA;
				
            }
        
        
        // set desired CBA
        cba.SetCommandSetL(resid);
        cba.DrawNow();

    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::VerifyCollectionId
// Verify if the collectionid exsists in the array of collecteids
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::VerifyCollectionIdL(const TCalCollectionId aColId)
    {
    TRACE_ENTRY_POINT
    TInt errVal = KErrNotFound;
    errVal = iCollectionIds.Find((TInt)aColId);
    User::LeaveIfError(errVal);
    TRACE_EXIT_POINT
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::ModifyDbField
// modifies the DB filed in cenrep if user has edited it.
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::ModifyDbField()
    {
    if(IsCreatingNewEntry())
        {                
        RPointerArray<CCalCalendarInfo> calendarInfoList; 
        iServices->GetAllCalendarInfoL(calendarInfoList);
        CleanupClosePushL( calendarInfoList );
        TInt pos = iUnifiedEditorControl->GetCalendarIndexForEntryL();
        TPtrC  lastUsedCalendarName = calendarInfoList[pos]->FileNameL();
        CleanupStack::PopAndDestroy( &calendarInfoList );
        
        CRepository* cenRep = CRepository::NewLC(KCRUidCalendar); 
        User::LeaveIfError( cenRep->Set( KCalendarLastUsedCalendar, lastUsedCalendarName ) );
        CleanupStack::PopAndDestroy( cenRep );
        }       
    }
// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::HideFieldsForEditSingleInstance
// Hides Entry type and Calendar Field for exceptional entry/single
// instance of recurrent entry.
// -----------------------------------------------------------------------------
//
void CCalenUnifiedEditor::HideFieldsForEditSingleInstance()
    {
    TRACE_ENTRY_POINT;
    
    if( !IsCreatingNewEntry() )
        {
        if((CalenAgendaUtils::IsRepeatingL(*iOriginalCalEntry) 
                && iRepeatType == CalCommon::EThisOnly)
                || iOriginalCalEntry->RecurrenceIdL().TimeUtcL() != Time::NullTTime())
            {
            //Hides Entry Type Filed            
            CCoeControl* entryTypeControl = ControlOrNull( ECalenEditorEventType );
            if( entryTypeControl )
                {
                DeleteLine(ECalenEditorEventType);
                }
            //Hides All Day Event Field
            CCoeControl* allDayEventControl = ControlOrNull( ECalenEditorAllDayItem );
            if( allDayEventControl )
                {
                DeleteLine(ECalenEditorAllDayItem);
                }
            //Hides Calendar Field
            CCoeControl* calendarControl = ControlOrNull( ECalenEditorDBName );
            if( calendarControl )
                {  
                DeleteLine(ECalenEditorDBName);
                }       
            //Hides Repeat Field
            CCoeControl* repeatControl = ControlOrNull( ECalenEditorRepeat );
            if( repeatControl )
                {
                DeleteLine(ECalenEditorRepeat);
                }            
            //Hides Repeatuntil Field
            CCoeControl* repeatUntilControl = ControlOrNull( ECalenEditorRepeatUntil );
            if( repeatUntilControl )
                {       
                DeleteLine(ECalenEditorRepeatUntil);
                }            
            }
        }
    UpdateFormL();
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenUnifiedEditor::AddPictureL
// Adds Map icon onto the editors
// -----------------------------------------------------------------------------
//      
void CCalenUnifiedEditor::AddPictureL(TInt isNotFirstTime)
    {
    TRACE_ENTRY_POINT;
    
    // Instantiate CMapIconPicture object 300x300 twips in size
    CEikRichTextEditor* locationControl = static_cast<CEikRichTextEditor*>(Control(ECalenEditorPlace));
    
    CRichText* text = locationControl->RichText();
    if(isNotFirstTime)
        {
        TPtrC ptr = text->Read(0,text->DocumentLength());
        TInt pos = ptr.Locate(TChar(CEditableText::EPictureCharacter));
        if(pos != -1) // If picture found, delete it so that it cna be drawn at new place
            {
            TRAP_IGNORE(text->DeleteL(pos,1));
            }
        }
    
    // Get the rect of the caption of ECalenEditorPlace control
    CEikLabel* label = this->ControlCaption(ECalenEditorPlace);
    TRect rect = label->Rect();
    
    CMapsIconPicture* picture = new( ELeave )CMapsIconPicture(/* TSize( 300, 300 )*/ *iServices, rect );
    CleanupStack::PushL(picture);
    //Prepare the picture header, which will be inserted into the rich text
    TPictureHeader header;
    header.iPicture = TSwizzle<CPicture>(picture);
    
    // Position where we insert picture is not valid as it always draws icon depending the rect we provide
    
        text->InsertL(text->DocumentLength(), header);
        
    locationControl->HandleTextChangedL();
    CleanupStack::Pop(); // picture
    
    Control(ECalenEditorPlace)->DrawNow();
    
    TRACE_EXIT_POINT;   
    }
	
// -----------------------------------------------------------------------------
// CMapsIconPicture::CMapsIconPicture
// C++ Constructor
// -----------------------------------------------------------------------------
//
CMapsIconPicture::CMapsIconPicture( MCalenServices& aServices, TRect aRect ) 
: iServices( aServices ), 
  iRect( aRect ) 
    {
    TRACE_ENTRY_POINT;
    TRACE_EXIT_POINT;   
    }

// -----------------------------------------------------------------------------
// CMapsIconPicture::ExternalizeL
// Pure virtual from CPicture, intentionally empty.
// -----------------------------------------------------------------------------
//  
void CMapsIconPicture::ExternalizeL( RWriteStream& /*aStream*/ ) const 
    {
    TRACE_ENTRY_POINT;
    TRACE_EXIT_POINT;   
    }

// -----------------------------------------------------------------------------
// CMapsIconPicture::GetOriginalSizeInTwips
// Convert size to twips
// -----------------------------------------------------------------------------
//
void CMapsIconPicture::GetOriginalSizeInTwips( TSize & /* aSize */ ) const 
    {
    TRACE_ENTRY_POINT;
    TRACE_EXIT_POINT;    
    }

// -----------------------------------------------------------------------------
// CMapsIconPicture::Draw
// Draw funtion to draw the map icon
// -----------------------------------------------------------------------------
//
void CMapsIconPicture::Draw( CGraphicsContext& aGc, 
                             const TPoint& /* aTopLeft */,
                             const TRect& /* aClipRect */,
                             MGraphicsDeviceMap* /* aMap */) const
    {
    TRACE_ENTRY_POINT;
    
    aGc.Reset();
    
    // Create the icon
    CGulIcon* icon = NULL;
    PIM_TRAPD_HANDLE( icon = iServices.GetIconL( MCalenServices::ECalenMapIcon ) );   

    TAknLayoutRect icon_layout_rect;
    icon_layout_rect.LayoutRect( iRect, AknLayoutScalable_Apps::field_cale_ev_pane_g1( 0 ).LayoutLine() );
    TRect area = icon_layout_rect.Rect();
    AknIconUtils::SetSize( icon->Bitmap(), area.Size() );
    
    aGc.DrawBitmapMasked( area, icon->Bitmap(), area.Size(), icon->Mask(), ETrue );
    delete icon;
    
    TRACE_EXIT_POINT;   
    }
// End of file