// EIKAPPUI.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//

#include <eikappui.h>
#include <eikenv.h>
#include <eikdef.h>
#include <eikhkeyt.h>
#include <eikhkeyc.h>
#include <eikmenup.h>
#include <eikmenub.h>
#include <eiktbar.h>
#include <eikcmds.hrh>
#include <eikdoc.h>
#include <eikapp.h>
#include <eiklabel.h>
#include <eikpriv.hrh>
#include <eikdef.hrh>
#include <eikon.rsg>
#include <eikcfdlg.h>
#include <eikproc.h>
#include <basched.h>
#include <coeutils.h>
#include <eikpanic.h>
#include <eikshut.h>
#include <apgtask.h>
#include <eikfnlab.h>
#include <eiktbar.hrh>

EXPORT_C CEikAppUi::CEikAppUi()
	: iSidebarPopupId(-1)
    {
    }

EXPORT_C CEikAppUi::~CEikAppUi()
    {
	if (iContainerAppUi)
		iCoeEnv->SetAppUi(iContainerAppUi);
	if (iDocument)
		iDocument->NullAppUi();
    ClosePopup();
    delete(iMenuBar);
	delete(iToolBar);
	delete(iToolBand);
	delete(iTitleBand);
    }

EXPORT_C void CEikAppUi::HandleModelChangeL()
	{
	}

EXPORT_C void CEikAppUi::ConstructL()
	{
	BaseConstructL();
	}

EXPORT_C void CEikAppUi::BaseConstructL(TInt aAppUiFlags)
    {
    iContainerAppUi=(CEikAppUi*)iCoeEnv->SetAppUi(this);
    CCoeAppUi::ConstructL(iContainerAppUi);
	if (!iContainerAppUi)
		iEikonEnv->ControlStackReadyL();
    if (!(aAppUiFlags&(ENoAppResourceFile|ENonStandardResourceFile)))
	    ReadAppInfoResourceL();
	else if (iContainerAppUi)
		AddTitleBandL();
    }

EXPORT_C void CEikAppUi::ReadAppInfoResourceL(TInt aResourceFileOffset)
	{
    SEikAppInfo appInfo;
    TPtr ptr((TText*)&appInfo,sizeof(appInfo));
	const TInt resourceFileOffset=(aResourceFileOffset)? aResourceFileOffset : Application()->ResourceFileOffset();
    iCoeEnv->ReadResource(ptr,EAppInfoResourceOffset+resourceFileOffset);
    if (appInfo.iMenuBarId)
        {
        iMenuBar=new(ELeave) CEikMenuBar;
        iMenuBar->ConstructL(this,appInfo.iHotKeysId,appInfo.iMenuBarId);
        AddToStackL(iMenuBar,ECoeStackPriorityMenu,ECoeStackFlagRefusesFocus);
        }
	TRect boundingRect=ClientRect(); // make toolband stretch to the screen width by default
	if (appInfo.iToolBarId)
		{
		iToolBar=new(ELeave) CEikToolBar;
		iToolBar->ConstructL(this,appInfo.iToolBarId,boundingRect);
		}
	if (iContainerAppUi)
		AddTitleBandL();
	if (appInfo.iToolBandId)
		{
		boundingRect.iTl.iY=ClientRect().iTl.iY;
		iToolBand=new(ELeave) CEikToolBar;
		iToolBand->StaticConstructL(this,appInfo.iToolBandId);
		if (iTitleBand)
			iToolBand->SetAdjacent(ECoeAdjTop);
		iToolBand->SetBoundingRectL(boundingRect);
		if (!iToolBand->DelayActivation())
			iToolBand->ActivateL();
		if (iToolBar) // in case toolbar/band overlap, put bar in front
			iToolBar->DrawableWindow()->SetOrdinalPosition(0);
		}
	if (iTitleBand) // put title band in front
		iTitleBand->DrawableWindow()->SetOrdinalPosition(0);
	}

void CEikAppUi::AddTitleBandL()
	{
	iTitleBand=new(ELeave) CEikToolBar;
	iTitleBand->StaticConstructL(this,R_EIK_TBAR_TITLE);
	TBuf<64> tmp;
	const TApaAppCaption& object=iDocument->AppCaption();
	const TApaAppCaption& container=iContainerAppUi->iDocument->AppCaption();
	iCoeEnv->Format128(tmp,R_EIK_TBUF_TITLE_BAR_LABEL,&object,&container);
	STATIC_CAST(CEikLabel*,iTitleBand->ControlById(EEikCidTitleBarLabel))->SetTextL(tmp);
	const TInt width=(iToolBar? iToolBar->Size().iWidth-iToolBar->Border().SizeDelta().iWidth : KEikStdFileNameLabelWidth);
	(*iTitleBand->ControlArray())[2].SetLength(width);
	iTitleBand->SetBoundingRectL(TRect(TPoint(0,0),iCoeEnv->ScreenDevice()->SizeInPixels()));
	STATIC_CAST(CEikFileNameLabel*,iTitleBand->ControlById(EEikCidTitleBatFileNameLabel))->UpdateL();
	if (!(iTitleBand->DelayActivation()))
		iTitleBand->ActivateL();
	}

EXPORT_C TRect CEikAppUi::ClientRect() const
	{
	TRect rect(TPoint(0,0),iCoeEnv->ScreenDevice()->SizeInPixels());
	if (iToolBar)
		iToolBar->ReduceRect(rect);
	if (iTitleBand)
		iTitleBand->ReduceRect(rect);
	if (iToolBand)
		iToolBand->ReduceRect(rect);
	return(rect);
	}

EXPORT_C void CEikAppUi::ProcessCommandL(TInt aCommand)
    {
	if (iPopup)
	    ClosePopup();
    else if (iMenuBar)
        iMenuBar->StopDisplayingMenuBar();
    if (aCommand!=EEikCmdCanceled)
	    HandleCommandL(aCommand);
    }

EXPORT_C void CEikAppUi::HandleCommandL(TInt /*aCommand*/)
    {
    }

EXPORT_C void CEikAppUi::CreateHotKeyControlL(TInt aResourceId)
    {
    CEikHotKeyTable* table=new(ELeave) CEikHotKeyTable;
    CleanupStack::PushL(table);
    table->ConstructFromResourceL(aResourceId);
    CEikHotKeyControl* control=new(ELeave) CEikHotKeyControl(table,this);
    CleanupStack::Pop(); // table now owned by control
    CleanupStack::PushL(control);
    AddToStackL(control,ECoeStackPriorityMenu,ECoeStackFlagRefusesFocus|ECoeStackFlagOwnershipTransfered);
    CleanupStack::Pop();
    }

EXPORT_C void CEikAppUi::LaunchPopupMenuL(TInt aResourceId,const TPoint& aTargetPos,TPopupTargetPosType aTargetType,const CEikHotKeyTable* aHotKeyTable)
    {
    ClosePopup();
    iPopup=new(ELeave) CEikMenuPane(this);
    TRAPD(err,DoLaunchPopupL(aResourceId,aTargetPos,aHotKeyTable,aTargetType));
    if (err)
        {
        ClosePopup();
        User::Leave(err);
        }
    }

EXPORT_C void CEikAppUi::ClosePopup()
    {
    if (iPopup)
		{
		RemoveFromStack(iPopup);
		delete(iPopup);
		iPopup=NULL;
		}
	iSidebarPopupId=-1;
    }

void CEikAppUi::DoLaunchPopupL(TInt aResourceId,const TPoint& aTargetPos, const CEikHotKeyTable* aHotKeyTable, TPopupTargetPosType aTargetType)
    {
    iPopup->ConstructL(NULL);
    RestoreMenuL(iPopup,aResourceId,MEikMenuObserver::EMenuPane);
    iPopup->SetPointerCapture(ETrue);
    AddToStackL(iPopup,ECoeStackPriorityDialog);
    iPopup->StartDisplayingMenuPane(aHotKeyTable,aTargetPos,NULL,0,aTargetType);
    }

EXPORT_C void CEikAppUi::StopDisplayingMenuBar()
	{
	if (iMenuBar)
		{
		if (iMenuBar->IsVisible())
			iMenuBar->StopDisplayingMenuBar();
		}
	}

EXPORT_C void CEikAppUi::SetEmphasis(CCoeControl* aMenuWindow,TBool aEmphasis)
    {
    UpdateStackedControlFlags(aMenuWindow,aEmphasis? 0: ECoeStackFlagRefusesFocus,ECoeStackFlagRefusesFocus);
    HandleStackChanged();
    }

EXPORT_C void CEikAppUi::SetDocument(CEikDocument* aDocument)
	{
	iDocument=aDocument;
	}

EXPORT_C void CEikAppUi::SetEmbeddedDocInfo(MApaEmbeddedDocObserver* aDoorObserver,TBool aReadOnly)
	{
	iDoorObserver=aDoorObserver;
	iEmbeddedAndReadOnly=aReadOnly;
	}

EXPORT_C CEikDocument* CEikAppUi::Document() const
	{
	return iDocument;
	}

EXPORT_C void CEikAppUi::SetDocChanged()
	{
	iDocument->SetChanged(ETrue);
	}

EXPORT_C void CEikAppUi::SaveAnyChangesL()
	{
	if (iDocument->HasChanged())
		iDocument->SaveL();
	}

EXPORT_C CEikApplication* CEikAppUi::Application() const
	{
	return((CEikApplication*)(iDocument->Application()));
	}

EXPORT_C void CEikAppUi::Exit()
	{
	if (iContainerAppUi)
		delete this;
	else
		CBaActiveScheduler::Exit();
	}

EXPORT_C void CEikAppUi::SaveL()
	{
	if (iContainerAppUi)
		iContainerAppUi->iDocument->SetChanged(ETrue);
	else
		iDocument->SaveL();
	}

EXPORT_C void CEikAppUi::HandleSideBarMenuL(TInt aResourceId,const TPoint& aPos,TInt /*aModifiers*/,const CEikHotKeyTable* aHotKeyTable)
	{
	TBool launchSidebarPopup(iSidebarPopupId!=aResourceId && (aResourceId==R_EIK_SIDEBAR_EDIT_MENU || aResourceId==R_EIK_SIDEBAR_IRDA_MENU));
	if (iPopup)
		ClosePopup();// sets iSidebarPopupId to -1
	if (aResourceId==0) // 0 indicates menu bar
		{
		iMenuBar->TryDisplayMenuBarL();
		const TInt title=iMenuBar->SelectedTitle();
		const TInt item=iMenuBar->SelectedItem();
		iMenuBar->MoveHighlightToL(title, (item>=0?item:0));
		return;
		}
	// otherwise a popup menu
	if (iMenuBar) 
        iMenuBar->StopDisplayingMenuBar();
	if (launchSidebarPopup)
		{
		LaunchPopupMenuL(aResourceId,aPos,EPopupTargetTopLeft,aHotKeyTable);
		iSidebarPopupId=aResourceId;
		}
	}

EXPORT_C TBool CEikAppUi::ProcessCommandParametersL(TApaCommand /*aCommand*/ ,TFileName& aDocumentName, const TDesC8& /*aTail*/)
	{ // is this the right thing to do ???
	Application()->GetDefaultDocumentFileName(aDocumentName);
	return ConeUtils::FileExists(aDocumentName);
	}

EXPORT_C TBool CEikAppUi::ProcessCommandParametersL(TApaCommand aCommand,TFileName& aDocumentName)
	{ 
	if (aCommand==EApaCommandCreate)
		return EFalse; // assume aDocumentName is valid
	if (aCommand==EApaCommandRun || aCommand==EApaCommandBackground)
		{
		TFileName fileName=iEikonEnv->Process()->LastUsedFileL(CEikProcess::ELastOpenFile);
		if (ValidFileExists(fileName))
			{
			aDocumentName=fileName;
			return ETrue;
			}
		}
	if (!ValidFileExists(aDocumentName))
		CApaApplication::GenerateFileName(iEikonEnv->FsSession(),aDocumentName);
	return ConeUtils::FileExists(aDocumentName);
	}

TBool CEikAppUi::ValidFileExists(const TDesC& aFileName)
	{
	if (!ConeUtils::FileExists(aFileName))
		return EFalse;
	TEntry entry;
	iEikonEnv->FsSession().Entry(aFileName,entry);
	TUid fileType=entry[2];
	TUid appType=Application()->AppDllUid();
	return (fileType==appType || ValidFileType(fileType));
	}

EXPORT_C TBool CEikAppUi::ValidFileType(TUid /*aFileUid*/) const
	{
	return EFalse;
	}

EXPORT_C void CEikAppUi::HandleMessageReadyL()
	{
	new(ELeave) CEikShutter(ETrue); // will destroy itself
	}

EXPORT_C void CEikAppUi::HandleSystemEventL(const TWsEvent& aEvent)
	{
	switch (*(TApaSystemEvent*)(aEvent.EventData()))
		{
	case EApaSystemEventShutdown:
		new(ELeave) CEikShutter(EFalse); // will destroy itself
	default:
		;
		}
	}

EXPORT_C void CEikAppUi::ProcessMessageL(TUid aUid,const TDesC8& aParams)
	{
	switch (aUid.iUid)
		{
#if defined(_UNICODE)
	case KUidApaMessageSwitchOpenFileValue16:
#else
	case KUidApaMessageSwitchOpenFileValue8:
#endif
#if defined(_UNICODE)
		{
		TPtrC fileName(((TText*)aParams.Ptr()),aParams.Length()/2);
		OpenFileL(fileName);
		}
#else
		OpenFileL(aParams);
#endif
		return;
#if defined(_UNICODE)
	case KUidApaMessageSwitchCreateFileValue16:
#else
	case KUidApaMessageSwitchCreateFileValue8:
#endif
#if defined(_UNICODE)
		{
		TPtrC fileName(((TText*)aParams.Ptr()),aParams.Length()/2);
		CreateFileL(fileName);
		}
#else
		CreateFileL(aParams);
#endif
		return;
	default:
		return;
		}
	}

EXPORT_C void CEikAppUi::OpenFileL(const TDesC& /*aFileName*/)
	{
	}

EXPORT_C void CEikAppUi::CreateFileL(const TDesC& /*aFileName*/)
	{
	}

EXPORT_C TErrorHandlerResponse CEikAppUi::HandleError(TInt /*aError*/,const SExtendedError& /*aExtErr*/,TDes& /*aErrorText*/,TDes& /*aContextText*/)
	{
	return(EErrorNotHandled);
	}

EXPORT_C void CEikAppUi::Reserved_1()
	{}
EXPORT_C void CEikAppUi::Reserved_2()
	{}
EXPORT_C void CEikAppUi::Reserved_3()
	{}
EXPORT_C void CEikAppUi::Reserved_4()
	{}
