// TMENU3.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//

#include <barsread.h>
#include <eikenv.h>
#include <coecntrl.h>
#include <basched.h>
#include <eikappui.h>
#include <e32keys.h>
#include <eikdef.h>
//#include <eikpanic.h>
#include <eikmenup.h>
#include <eikmenub.h>
#include <eikmenu.hrh>
#include <eikapp.h>
#include <eikrutil.h>
#include <eikdoc.h>
#include <coeerror.h>
#include <eikcolor.h>
#include <bautils.h>
#include "tmenu3.hrh"
#include <tmenu3.rsg>

#pragma data_seg(".E32_UID")
//__WINS_UID(0,KAppUidValue,208)
#pragma data_seg()

const int KMenuBarF=0x2000;
const int KMenuPaneEmpty=0x2001;

//
// class CSimpleControl
//

enum TMessageControlFontStyle
    {
    EStyleElementBold=EMenuCommandBold,
    EStyleElementItalic=EMenuCommandItalic,
    EStyleElementUnderline=EMenuCommandUnderline,
    EStyleElementStrikethrough=EMenuCommandStrikethrough
    };

class CSimpleAppUi;

class CSimpleControl : public CCoeControl
    {
public:
	~CSimpleControl();
    void ConstructL();
	void ToggleFontStyleAndRedrawL(TMessageControlFontStyle aStyleElement);
    void DrawMessage() const;
    void DrawMessageNow() const;
    void SetMessage(const TDesC& aMessage);
    void SetMessage(TInt aResourceId);
	void SetZoom(TInt aZoom) { iZoom=aZoom; }
	void SetTextAlign(CGraphicsContext::TTextAlign aTextAlign) { iTextAlign=aTextAlign; }
	void SetMessageText(const TDesC& aMessage) { iMessage=aMessage; }
	const TDesC& Message() const { return iMessage; }
	TBool DummyEnabled() const { return iDummyEnabled; }
	void SetDummyEnabled(TBool aEnabled) { iDummyEnabled=aEnabled; }
	TBool CascadeEnabled() const { return iCascadeEnabled; }
	void SetCascadeEnabled(TBool aEnabled) { iCascadeEnabled=aEnabled; }
	TBool BoldEnabled() const { return iBoldEnabled; }
	void SetBoldEnabled(TBool aEnabled) { iBoldEnabled=aEnabled; }
	void SetFontL(const TFontSpec& aFontSpec);
	void DynInitMenuPaneL(TInt aMenuId,CEikMenuPane* aMenuPane);
	TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType);

private: // framework
	TBool CheckHotKeyNotDimmedL(TInt aSelection);
	void Draw(const TRect& aRect) const;
private:
    TBuf<40> iMessage;
    TFontSpec iFontSpec;
    TFontUnderline iFontUnderline;
    TFontStrikethrough iFontStrikethrough;
    const CFont* iFont;
	TBool iDummyEnabled;
	TBool iCascadeEnabled;
	TBool iBoldEnabled;
	TInt iZoom;
	CGraphicsContext::TTextAlign iTextAlign;
    };


class CSimpleAppUi : public CEikAppUi
    {
public:
    void ConstructL();
	~CSimpleAppUi();
	void OfferKeyToAppL(const TKeyEvent& aKeyEvent,TEventCode aType);
private: // framework
	void CreateStandardListBox();
	void CreateStandardMultiColumnListBox();
    void HandleCommandL(TInt aCommand);
	void DynInitMenuPaneL(TInt aMenuId,CEikMenuPane* aMenuPane);
	void TestColorArraysL();
private: // from MEikMenuObserver
	void RestoreMenuL(CCoeControl* aMenuWindow,TInt aMenuId,TMenuType aMenuType);
private:
    CSimpleControl* iSimpleControl;
	TBuf<100> iMenuTitle;
    };


CSimpleControl::~CSimpleControl()
	{
	iCoeEnv->ReleaseScreenFont(CONST_CAST(CFont*,iFont));
	}

void CSimpleControl::ConstructL()
    {
    CreateWindowL();
    Window().SetShadowDisabled(ETrue);
    SetExtentToWholeScreenL();
	iTextAlign=CGraphicsContext::ECenter;
    TFontSpec spec(_L("Arial"),140);
    SetFontL(spec);
    iCoeEnv->ReadResource(iMessage,R_MENB_START_MESSAGE);
    ActivateL();
    }


TKeyResponse CSimpleControl::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
	{
	if (aType!=EEventKey)
        return(EKeyWasConsumed);
	if ((aKeyEvent.iCode==9) && (aKeyEvent.iModifiers&EModifierCtrl))// Ctrl-tab
		{
		TFontSpec spec=iFontSpec;
		spec.iFontStyle.SetStrokeWeight(spec.iFontStyle.StrokeWeight()? EStrokeWeightNormal: EStrokeWeightBold);
        SetFontL(spec);
		}
	iMessage.Format(_L("Key 0x%x, modifier 0x%x"),aKeyEvent.iCode,aKeyEvent.iModifiers);
    DrawMessageNow();
    return(EKeyWasConsumed);
	}

void CSimpleControl::Draw(const TRect& /*aRect*/) const
    {
    DrawMessage();
    }

void CSimpleControl::ToggleFontStyleAndRedrawL(TMessageControlFontStyle aStyleElement)
    {
    TFontSpec spec=iFontSpec;
    TBool doSet=EFalse;
    switch (aStyleElement)
        {
    case EStyleElementBold:
        spec.iFontStyle.SetStrokeWeight(spec.iFontStyle.StrokeWeight()? EStrokeWeightNormal: EStrokeWeightBold);
        doSet=ETrue;
        break;
    case EStyleElementItalic:
        spec.iFontStyle.SetPosture(spec.iFontStyle.Posture()? EPostureUpright: EPostureItalic);
        doSet=ETrue;
        break;
    case EStyleElementUnderline:
        iFontUnderline=(iFontUnderline? EUnderlineOff: EUnderlineOn);
        break;
    case EStyleElementStrikethrough:
        iFontStrikethrough=(iFontStrikethrough? EStrikethroughOff: EStrikethroughOn);
        }
    if (doSet)
        SetFontL(spec); // otherwise change effective at Draw time
    DrawMessageNow();
    }

TBool CSimpleControl::CheckHotKeyNotDimmedL(TInt aSelection)
	{
	if ((aSelection==EMenuCommandWindowDummy)&&(!iDummyEnabled))
		return EFalse;
	if ((aSelection==EMenuCommandBold)&&(!iBoldEnabled))
		return EFalse;
	return ETrue;
	}

void CSimpleControl::DynInitMenuPaneL(TInt aMenuId,CEikMenuPane* aMenuPane)
	{
/*
	if (aMenuId==R_EIK_MENU_ZOOM)
		{
		SEikMenuItemData zoom50;
		zoom50.iCommandId=EMenuCommandZoom50;
		zoom50.iCascadeId=0;
		zoom50.iFlags=0;
		zoom50.iText=(_L("Zoom 50%"));
		aMenuPane->AddMenuItemL(zoom50);
		SEikMenuItemData zoom75;
		zoom75.iCommandId=EMenuCommandZoom75;
		zoom75.iCascadeId=0;
		zoom75.iFlags=0;
		zoom75.iText=(_L("Zoom 75%"));
		aMenuPane->AddMenuItemL(zoom75);
		SEikMenuItemData zoom125;
		zoom125.iCascadeId=0;
		zoom125.iFlags=0;
		zoom125.iCommandId=EMenuCommandZoom125;
		zoom125.iText=(_L("Zoom 125%"));
		aMenuPane->AddMenuItemL(zoom125);
		SEikMenuItemData zoom150;
		zoom150.iCascadeId=0;
		zoom150.iFlags=0;
		zoom150.iCommandId=EMenuCommandZoom150;
		zoom150.iText=(_L("Zoom 150%"));
		aMenuPane->AddMenuItemL(zoom150);
		SEikMenuItemData zoom200;
		zoom200.iCascadeId=0;
		zoom200.iFlags=0;
		zoom200.iCommandId=EMenuCommandZoom200;
		zoom200.iText=(_L("Zoom 200%"));
		aMenuPane->AddMenuItemL(zoom200);
		}
*/
	if (aMenuId==R_MENB_OPTIONS_MENU)
		{
		TBuf<20> toggleBoldText;		
		if (iBoldEnabled)
			{
			toggleBoldText=_L("Disable Bold");
			aMenuPane->SetItemDimmed(EMenuCommandBold,EFalse);
			}
		else
			{
			toggleBoldText=_L("Enable Bold");
			aMenuPane->SetItemDimmed(EMenuCommandBold,ETrue);
			}
		aMenuPane->SetItemTextL(EMenuCommandBoldToggle,toggleBoldText);		
		if (iFontSpec.iFontStyle.StrokeWeight())
			aMenuPane->SetItemButtonState(EMenuCommandBold,EEikMenuItemSymbolOn);
		if (iFontSpec.iFontStyle.Posture())
			aMenuPane->SetItemButtonState(EMenuCommandItalic,EEikMenuItemSymbolOn);
		if (iFontUnderline)
			aMenuPane->SetItemButtonState(EMenuCommandUnderline,EEikMenuItemSymbolOn);
		if (iFontStrikethrough)
			aMenuPane->SetItemButtonState(EMenuCommandStrikethrough,EEikMenuItemSymbolOn);
		if (iZoom==EMenuCommandZoomOut)
			aMenuPane->SetItemButtonState(EMenuCommandZoomOut,EEikMenuItemSymbolOn);
		else if (iZoom==EMenuCommandZoomIn)
			aMenuPane->SetItemButtonState(EMenuCommandZoomIn,EEikMenuItemSymbolOn);
		else
			aMenuPane->SetItemButtonState(EMenuCommandZoomNormal,EEikMenuItemSymbolOn);
		if (iTextAlign==CGraphicsContext::ELeft)
			aMenuPane->SetItemButtonState(EMenuCommandLeft,EEikMenuItemSymbolOn);
		else if (iTextAlign==CGraphicsContext::ECenter)
			aMenuPane->SetItemButtonState(EMenuCommandMiddle,EEikMenuItemSymbolOn);
		else
			aMenuPane->SetItemButtonState(EMenuCommandRight,EEikMenuItemSymbolOn);
		}
	if (aMenuId==R_MENB_WINDOW_MENU)
		{
		TBuf<20> toggleDummyText;
		if (iDummyEnabled)
			{
			toggleDummyText=_L("Disable dummy");
			aMenuPane->SetItemDimmed(EMenuCommandWindowDummy,EFalse);
			}
		else
			{
			toggleDummyText=_L("Enable dummy");
			aMenuPane->SetItemDimmed(EMenuCommandWindowDummy,ETrue);
			}
		aMenuPane->SetItemTextL(EMenuCommandWindowToggleDummy,toggleDummyText);
		if (iCascadeEnabled)
			{
			toggleDummyText=_L("Disable cascade");
			aMenuPane->SetItemDimmed(EMenuCommandWindowCascade,EFalse);
			}
		else
			{
			toggleDummyText=_L("Enable cascade");
			aMenuPane->SetItemDimmed(EMenuCommandWindowCascade,ETrue);
			}
		aMenuPane->SetItemTextL(EMenuCommandWindowToggleCascade,toggleDummyText);
		}
	}

/*void CSimpleControl::DrawMessage() const
    {
    TRect rect=Rect();
    rect.Shrink(10,60);
    TInt ascent=(rect.iBr.iY-rect.iTl.iY-iFont->HeightInPixels())/2 + iFont->AscentInPixels();
    CWindowGc& gc=SystemGc();
	gc.UseFont(iFont);
    if (iFontUnderline)
        gc.SetUnderlineStyle(iFontUnderline);
    if (iFontStrikethrough)
        gc.SetStrikethroughStyle(iFontStrikethrough);
    gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
    gc.DrawText(iMessage,rect,ascent,iTextAlign,0);
    }*/

void CSimpleControl::DrawMessage() const
    {
    CWindowGc& gc=SystemGc();
	gc.Clear();
	TPoint pos(20,15);
	gc.UseFont(iFont);

	TFindThread findThread;
	TFullName name;
	while (findThread.Next(name)==0)
		{
		RThread thread;
		thread.Open(findThread);
		TThreadPriority priority = thread.Priority();
		RProcess process;
		/*TInt err=*/thread.Process(process); // !! how to handle an error here?
		TProcessPriority processPriority = process.Priority();
		process.Close();
		thread.Close();

		gc.DrawText(name,pos);
		TBuf<64> buf;
		TBuf<32> format(_S("tpri=%d ppri=%d"));
		buf.Format(format,priority,processPriority);
		gc.DrawText(buf,TPoint(pos.iX+300,pos.iY));
		pos.iY+=15;
		}
	}


void CSimpleControl::DrawMessageNow() const
    {
	ActivateGc();
	DrawMessage();
	DeactivateGc();
    }

void CSimpleControl::SetMessage(const TDesC& aMessage)
    {
    iMessage=aMessage;
    DrawMessageNow();
    }

void CSimpleControl::SetMessage(TInt aResourceId)
    {
    iCoeEnv->ReadResource(iMessage,aResourceId);
    DrawMessageNow();
    }

void CSimpleControl::SetFontL(const TFontSpec& aFontSpec)
    {
    CFont* font=iCoeEnv->CreateScreenFontL(aFontSpec);
	iCoeEnv->ReleaseScreenFont(CONST_CAST(CFont*,iFont)); // after previous line succeeds
    iFont=font;
    iFontSpec=aFontSpec;
    }

//
// CSimpleAppUi
//

void CSimpleAppUi::ConstructL()
    {
    BaseConstructL();
    iSimpleControl=new(ELeave) CSimpleControl;
    iSimpleControl->ConstructL();
    AddToStackL(iSimpleControl);
    }

void CSimpleAppUi::RestoreMenuL(CCoeControl* aMenuWindow,TInt aMenuId,TMenuType aMenuType)
    {
	if(aMenuId==KMenuBarF)
		{
		CEikMenuBar::TTitle title;
		CEikMenuBar::CTitleArray* titleArray = new(ELeave) CEikMenuBar::CTitleArray;
		CleanupStack::PushL(titleArray);

		iEikonEnv->ReadResource(iMenuTitle,R_MENB_LONG_MENU_TITLE);
		title.iData.iText=TPtrC(iMenuTitle);
		title.iData.iMenuPaneResourceId=R_MENB_LONG_MENU;
		titleArray->AddTitleL(title);

		iEikonEnv->ReadResource(iMenuTitle,R_MENB_MENU_F_MENU_TITLE);
		title.iData.iText=TPtrC(iMenuTitle);
		title.iData.iMenuPaneResourceId=R_MENB_F;
		titleArray->AddTitleL(title);

		iEikonEnv->ReadResource(iMenuTitle,R_MENB_RESOURCE_EMPTY_MENU_TITLE);
		title.iData.iText=TPtrC(iMenuTitle);
		title.iData.iMenuPaneResourceId=R_MENB_EMPTY_MENU;
		titleArray->AddTitleL(title);

		iEikonEnv->ReadResource(iMenuTitle,R_MENB_CODED_EMPTY_MENU_TITLE);
		title.iData.iText=TPtrC(iMenuTitle);
		title.iData.iMenuPaneResourceId=KMenuPaneEmpty;
		titleArray->AddTitleL(title);

		STATIC_CAST(CEikMenuBar*,aMenuWindow)->SetMenuTitleArray(titleArray);
		CleanupStack::Pop();	
		}
	else if(aMenuId==KMenuPaneEmpty)
		{
		iEikonEnv->InfoMsg(R_MENB_CODED_EMPTY_MENU_TITLE);
		}
	else
		MEikMenuObserver::RestoreMenuL(aMenuWindow,aMenuId,aMenuType);
    }

CSimpleAppUi::~CSimpleAppUi()
	{
    delete iSimpleControl;
	}

void CSimpleAppUi::OfferKeyToAppL(const TKeyEvent& aKeyEvent,TEventCode aType)
	{	
	if ((aKeyEvent.iCode==9) && (aKeyEvent.iModifiers&EModifierCtrl)) // tab
		// 'Ctrl Tab' displayed as extra text, (not a hotkey) on bold menu item.
		// key event offered to app, even when menu is displaying so
		// need to dismiss menubar if displaying.
		{
		StopDisplayingMenuBar();
		iSimpleControl->OfferKeyEventL(aKeyEvent, aType);
		}
	}


void CSimpleAppUi::DynInitMenuPaneL(TInt aMenuId,CEikMenuPane* aMenuPane)
	{
	iSimpleControl->DynInitMenuPaneL(aMenuId,aMenuPane);
	}

void CSimpleAppUi::HandleCommandL(TInt aCommand)
    {
    switch (aCommand)
        {
	case EMenuCommandColor:
		TestColorArraysL();
		break;
    case EMenuCommandFileExit:
        iSimpleControl->SetMessage(R_MENB_EXIT_MESSAGE);
		iCoeEnv->Flush(200000);
        CBaActiveScheduler::Exit();
	case ECommandMenuBarA:
		MenuBar()->ChangeMenuBarL(R_MENB_HOTKEYS,R_MENB_MENUBAR_A);
		break;
	case ECommandMenuBarB:
		MenuBar()->ChangeMenuBarL(R_MENB_HOTKEYS,R_MENB_MENUBAR_B);
		break;
	case ECommandMenuBarC:
		MenuBar()->ChangeMenuBarL(R_MENB_HOTKEYS,R_MENB_MENUBAR_C);
		break;
	case ECommandMenuBarD:
		MenuBar()->ChangeMenuBarL(R_MENB_HOTKEYS,R_MENB_MENUBAR_D);
		break;
	case ECommandMenuBarE:
		MenuBar()->ChangeMenuBarL(R_MENB_HOTKEYS_E,R_MENB_MENUBAR_E);
		break;
	case ECommandMenuBarALater:
		MenuBar()->ChangeMenuBarL(R_MENB_HOTKEYS,R_MENB_MENUBAR_A,EFalse);
		break;
	case ECommandMenuBarBLater:
		MenuBar()->ChangeMenuBarL(R_MENB_HOTKEYS,R_MENB_MENUBAR_B,EFalse);
		break;
	case ECommandMenuBarCLater:
		MenuBar()->ChangeMenuBarL(R_MENB_HOTKEYS,R_MENB_MENUBAR_C,EFalse);
		break;
	case ECommandMenuBarDLater:
		MenuBar()->ChangeMenuBarL(R_MENB_HOTKEYS,R_MENB_MENUBAR_D,EFalse);
		break;
	case ECommandMenuBarELater:
		MenuBar()->ChangeMenuBarL(R_MENB_HOTKEYS_E,R_MENB_MENUBAR_E,EFalse);
		break;
    case ECommandMenuBarF:
		MenuBar()->ChangeMenuBarL(R_MENB_HOTKEYS_E,KMenuBarF);
		break;
	case EMenuCommandBoldToggle:
		if (iSimpleControl->BoldEnabled())
			iSimpleControl->SetBoldEnabled(EFalse);
		else
			iSimpleControl->SetBoldEnabled(ETrue);
		iSimpleControl->SetMessage(R_MENB_BOLD_TOGGLE);	
		break;		
	case EMenuCommandBold:
		if (!(iSimpleControl->BoldEnabled()))
			break;
    case EMenuCommandItalic:
    case EMenuCommandUnderline:
    case EMenuCommandStrikethrough:
        iSimpleControl->ToggleFontStyleAndRedrawL((TMessageControlFontStyle)aCommand);
        break;
    case EMenuCommandZoomNormal:
		iSimpleControl->SetZoom(EMenuCommandZoomNormal);
		iSimpleControl->SetMessage(_L("Scale 1:1"));
        break;
    case EMenuCommandZoomIn:
		iSimpleControl->SetZoom(EMenuCommandZoomIn);
        iSimpleControl->SetMessage(_L("Zoom in"));
        break;
    case EMenuCommandZoomOut:
		iSimpleControl->SetZoom(EMenuCommandZoomOut);
        iSimpleControl->SetMessage(_L("Zoom out"));
        break;
    case EMenuCommandLeft:
		iSimpleControl->SetTextAlign(CGraphicsContext::ELeft);
        iSimpleControl->DrawMessageNow();
		break;
    case EMenuCommandMiddle:
		iSimpleControl->SetTextAlign(CGraphicsContext::ECenter);
        iSimpleControl->DrawMessageNow();
		break;
    case EMenuCommandRight:
		iSimpleControl->SetTextAlign(CGraphicsContext::ERight);
        iSimpleControl->DrawMessageNow();
		break;
    case EMenuCommandToolsOne:
    case EMenuCommandToolsTwo:
    case EMenuCommandToolsThree:
    case EMenuCommandToolsFour:
    case EMenuCommandToolsFive:
    case EMenuCommandToolsSix:
		{
		TBuf<40> message=iSimpleControl->Message();
        iCoeEnv->Format128(message,R_MENB_TOOL_COMMAND_CHOSEN,aCommand-EMenuCommandToolsOne+1);
        iSimpleControl->DrawMessageNow();
        break;
		}
	case EMenuCommandWindowToggleDummy:
		if (iSimpleControl->DummyEnabled())
			iSimpleControl->SetDummyEnabled(EFalse);
		else
			iSimpleControl->SetDummyEnabled(ETrue);
		iSimpleControl->SetMessage(R_MENB_WINDOW_TOGGLE_DUMMY);	
		break;	
	case EMenuCommandWindowDummy:
		iSimpleControl->SetMessage(R_MENB_WINDOW_DUMMY_MESSAGE);
		break;
	case EMenuCommandWindowToggleCascade:
		if (iSimpleControl->CascadeEnabled())
			iSimpleControl->SetCascadeEnabled(EFalse);
		else
			iSimpleControl->SetCascadeEnabled(ETrue);
		iSimpleControl->SetMessage(R_MENB_WINDOW_TOGGLE_CASCADE);	
		break;
    case EPopupCommandOne:
        iSimpleControl->SetMessage(R_MENB_FIRST_COMMAND);
        break;
    case EPopupCommandTwo:
        iSimpleControl->SetMessage(R_MENB_SECOND_COMMAND);
        break;
   	case EPopupCommandThree:
        iSimpleControl->SetMessage(R_MENB_THIRD_COMMAND);
        break;
	case EMenuCommandAlertOne:
		iEikonEnv->AlertWin(_L("One line alert"));
		break;
	case EMenuCommandBreakpoint:
		if (!iEikonEnv->QueryWinL(_L("Execute hard-wired breakpoint?"),TPtrC()))
			break;
#if defined(__WINS__)
		_asm int 3;
#else
		asm(".word 0xe7ffffff");
#endif
		// fall through to AlertTwo code
	case EMenuCommandAlertTwo:
		iEikonEnv->AlertWin(_L("Two line alert, longer lines"),_L("Second line"));
		break;
	case EMenuCommandNotifyOne:
//		User::Notify(_L("One line notifier"),_L(""),_L("Continue"));
		iEikonEnv->InfoMsg(_L("Temporarily disabled"));
		break;
	case EMenuCommandNotifyTwo:
//		User::Notify(_L("Two line notifier, longer lines"),_L("Second line"),_L("Continue"));
		iEikonEnv->InfoMsg(_L("Temporarily disabled"));
		break;
	case EMenuCommandAlertLeave:
		User::Leave(-2);
		break;
	case EMenuCommandLeaveEikon:
		CBaActiveScheduler::LeaveForAlert(KNullUid,R_MENB_WINDOW_DUMMY_MESSAGE);
		break;
	case EMenuCommandLeaveCone:
		CBaActiveScheduler::LeaveForInfoPrint(KUidConeDll,KErrCoeResourceFileDuplicateOffset);
		break;
	case EMenuCommandContextError:
		iEikonEnv->HandleErrorWithContext(KErrDied,R_MENB_FIRST_COMMAND);
		break;
    default:
        iSimpleControl->SetMessage(R_MENB_NOT_IMPLEMENTED_YET);
        break;
        }
    }

void test(TBool aBool)
	{
	__ASSERT_ALWAYS(aBool,User::Invariant());
	}

struct STempCleanup
	{
	TInt iResourceFileOffset;
	CEikonEnv* iEnv;
	};

void DeleteTemp(TAny* aPtr)
	{
	STempCleanup& temp=*(STempCleanup*)aPtr;
	temp.iEnv->DeleteResourceFile(temp.iResourceFileOffset);
	}

void CSimpleAppUi::TestColorArraysL()
	{
	iEikonEnv->ColorList().SetColor(EEikColorWindowBackground,KRgbBlack);
	test(iEikonEnv->ColorList().Color(EEikColorWindowBackground)==KRgbBlack);
	// add some app specific colours
	CEikColorArray* array=CEikColorArray::NewLC();
	array->AddL(123,KRgbWhite);
	TUid uid={1234};
	iEikonEnv->ColorList().AddColorArrayL(uid,array);
	CleanupStack::Pop(); // array
	array=CEikColorArray::NewLC();
	array->AddL(321,KRgbBlack);
	uid.iUid=4321;
	iEikonEnv->ColorList().AddColorArrayL(uid,array);
	CleanupStack::Pop(); // array
	test(iEikonEnv->ColorList().Color(uid,321)==KRgbBlack);
	uid.iUid=1234;
	test(iEikonEnv->ColorList().Color(uid,123)==KRgbWhite);
	test(iEikonEnv->ColorList().ContainsColorArray(uid));
	uid.iUid=12345;
	test(iEikonEnv->ColorList().ContainsColorArray(uid)==EFalse);
	uid.iUid=1234;
	iEikonEnv->ColorList().DeleteColorArray(uid);
	}

//
// CSimpleDocument
//

class CSimpleDocument : public CEikDocument
	{
public:
	CSimpleDocument(CEikApplication& aApp): CEikDocument(aApp) { }
private: // from CApaDocument
	CEikAppUi* CreateAppUiL();
	};

CEikAppUi* CSimpleDocument::CreateAppUiL()
	{
    return(new(ELeave) CSimpleAppUi);
	}

//
// CSimpleApplication
//

class CSimpleApplication : public CEikApplication
	{
private: // from CApaApplication
	CApaDocument* CreateDocumentL();
	TUid AppDllUid() const;
	};

const TUid KUidSimpleApp={208};

TUid CSimpleApplication::AppDllUid() const
	{
	return(KUidSimpleApp);
	}

CApaDocument* CSimpleApplication::CreateDocumentL()
	{
	return(new(ELeave) CSimpleDocument(*this));
	}

//
// EXPORTed functions
//

EXPORT_C CApaApplication* NewApplication()
	{
	return(new CSimpleApplication);
	}

GLDEF_C TInt E32Dll(TDllReason)
	{
	return(KErrNone);
	}
