⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 commands1.cpp

📁 《UIQ 3 The Complete Guide》书的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Commands1.cpp - Commands example
//
// Copyright (C) UIQ Technology AB, 2007
//
// This material is provided "as is" without any warranty to its performance or functionality. 
// In no event shall UIQ Technology be liable for any damages whatsoever arising out of the
// use or inabilty to use this material. 
//

#include "Commands1.h"
#include "Commands1.hrh"
#include <Commands1.rsg>
#include <Commands1.mbg>

#include <QikMultiPageViewBase.h>
#include <QikCommand.h>
#include <QikCommandManager.h>
#include <QikListBoxModel.h>
#include <QikListBox.h>
#include <MQikListBoxData.h>
#include <QikSimpleDialog.h>
#include <eikstart.h>
#include <eiklabel.h>

//////////////////////////////////////////////////////////////////////////////
// The application Uid here MUST match UID3 defined in the MMP file 
// This is a development UID and must NOT be used in production type software
const TUid KAppSpecificUid={0xEDEAD003};

// internal secondary view id, must be unique amongst this applications views
const TUid KUidListView={0x00000001};

// views within applications are fully identified by the app Uid and secondary view id
#define KViewIdListView TVwsViewId(KAppSpecificUid,KUidListView)

_LIT(KMbmFile,"*"); // '*' is a shortcut to reference this app specific mbm (true for all apps)
//////////////////////////////////////////////////////////////////////////////////

const TInt KMaxListItemText=32;	// we support a max of 32 chars for each text item to be displayed

enum TAppSortTypes
	{
	ESortType1,
	ESortType2,
	ESortType3,
	};

enum TAppSortOrder
	{
	ESortOrderAscending,
	ESortOrderDescending
	};

class CAppEngine : public CBase
	{
protected:

public:
	CAppEngine(const TInt aZoomLevel);

	TInt ListViewZoomState() const;
	TBool SetListViewZoomState(const TInt aZoomLevel);

	TAppSortTypes ListViewSortType() const;
	void SetListViewSortType(const TAppSortTypes aType);
	TAppSortOrder ListViewSortOrder() const;
	void SetListViewSortOrder(const TAppSortOrder aType);

protected:
	// The 'engine' stores 'UI' information since UI components come and go, yet we want to preserve
	// UI configuration information between invocations of the view.
	TInt iZoomLevel;

	TAppSortTypes iSortType;
	TAppSortOrder iSortOrder;
	};

CAppEngine::CAppEngine(const TInt aZoomLevel) : 
	iZoomLevel(aZoomLevel)
	{}

TInt CAppEngine::ListViewZoomState() const
// Report the currently stored zoom state
	{
	return(iZoomLevel);
	}

TBool CAppEngine::SetListViewZoomState(const TInt aZoomLevel)
//
// Update list view zoom state. 
// Return TRUE if zoom state set is different to current level
//
	{
	if (aZoomLevel==iZoomLevel)
		return(EFalse);
	iZoomLevel=aZoomLevel;
	return(ETrue);
	}

TAppSortTypes CAppEngine::ListViewSortType() const
// Report the currently store sort type
	{
	return(iSortType);
	}

void CAppEngine::SetListViewSortType(const TAppSortTypes aType)
// Update the currently store sort type

	{
	iSortType=aType;
	}

TAppSortOrder CAppEngine::ListViewSortOrder() const
// Report the currently store sort order
	{
	return(iSortOrder);
	}

void CAppEngine::SetListViewSortOrder(const TAppSortOrder aType)
// Update the currently store sort order
	{
	iSortOrder=aType;
	}

//////////////////////////////////////////////////////////////////////////////////
class CAboutDialog : public CQikSimpleDialog
    {
protected:
	void PreLayoutDynInitL();
	};

// These would normally be derived from your in-house version control, this example just
// defines them here to remove such complexity from the example.
const TInt KAppMajorVersion=1;
const TInt KAppMinorVersion=0;
const TInt KAppBuild=2;

void CAboutDialog::PreLayoutDynInitL()
//
// Generate the version text - e.g. Version 1.00 (02) and set the label
//
	{
	TBuf<128>bb;
	iEikonEnv->Format128(bb,R_STR_VERSION,KAppMajorVersion,KAppMinorVersion,KAppBuild);
	CEikLabel* lbl=LocateControlByUniqueHandle<CEikLabel>(EAppLabel1);
	lbl->SetTextL(bb);	
	}

//////////////////////////////////////////////////////////////////////////////////
class CAppSpecificListView : public CQikMultiPageViewBase, public MQikListBoxObserver
	{
protected: 
	// from CQikViewBase
	TVwsViewId ViewId() const;
	void HandleCommandL(CQikCommand& aCommand);
	void ViewConstructL();
	void ViewDeactivated();
	void ViewActivatedL(const TVwsViewId& aPrevViewId,const TUid aCustomMessageId,const TDesC8& aCustomMessage);
	CQikCommand* DynInitOrDeleteCommandL(CQikCommand* aCommand,const CCoeControl& aControlAddingCommands);
	void TabActivatedL(TInt aTabId);
	
	// from MQikListBoxObserver
	void HandleListBoxEventL(CQikListBox* aListBox,TQikListBoxEvent aEventType,TInt aItemIndex,TInt aSlotId);

	// new methods
	static TInt SortComparisonFunction(const MQikListBoxData& aFirst,const MQikListBoxData& aSecond);
	void SortList1L();
	void UpdateList1CommandAvailability();
	void DeleteItemFromList1L();
	void AddSingleItemToList1L();
	void AddItemsToList1L();
	void AddItemsToList2L();

public:
	// new methods
	CAppSpecificListView(CAppSpecificUi& aAppUi,CAppEngine* aEngine);
	
protected:
	CAppEngine* iEngine;
	};

CAppSpecificListView::CAppSpecificListView(CAppSpecificUi& aAppUi,CAppEngine* aEngine) :
	CQikMultiPageViewBase(aAppUi,KNullViewId),iEngine(aEngine)
	{}

TVwsViewId CAppSpecificListView::ViewId() const
//
// All views are uniquely identified within the entire system. A TVwsViewId consists of 
// the application uid (uid3) and app specific view uid
//
	{
	return(KViewIdListView);
	}

TInt CAppSpecificListView::SortComparisonFunction(
//
// Compare function called back by the List box sort code..
// This function highlights a fairly significant deficiency in the way sorting is handled within
// list boxes. In particular every time a comparison is required (this function called) we 
// have to obtain a handle to the entity that defines what the sort order - in this case our 
// engine. We have to be a 'static' method to be passed to the TLinearOrder class, static
// methods have NO property so we have to obtain our engine via Thread Local Storage lookup
// CEikonEnv::Static()... 
// The alternative is to define 1 comparison function for each type of sort we want
// to perform and setup the call to the sort specific function. 
// We have 3 ways of sorting, each can be ascending or descending. To implement the alternative
// would require 6 sort comparison functions. 
// A second alternative is not to actually perform the sort in the list box but that has
// other consequences.
//
	const MQikListBoxData& aFirst,
	const MQikListBoxData& aSecond)
	{
	TInt ret;
	CAppEngine* engine=static_cast<CAppSpecificUi*>(CEikonEnv::Static()->EikAppUi())->AppEngine();
	switch (engine->ListViewSortType())
		{
	case ESortType1:	// sort by entire name
		ret=aFirst.Text(EQikListBoxSlotText1).CompareC(aSecond.Text(EQikListBoxSlotText1));
		break;
	case ESortType2:	// sort by second letter 
		ret=aFirst.Text(EQikListBoxSlotText1)[1]-aSecond.Text(EQikListBoxSlotText1)[1];
		break;
	case ESortType3:	// sort by third letter 
		ret=aFirst.Text(EQikListBoxSlotText1)[2]-aSecond.Text(EQikListBoxSlotText1)[2];
		break;
		}
	if (engine->ListViewSortOrder()==ESortOrderDescending)
		ret=(-ret);
	return(ret);
	}

void CAppSpecificListView::SortList1L()
//
// Sort the list dependant on the current user sort preferences
//
	{
	CQikListBox* listbox = LocateControlByUniqueHandle<CQikListBox>(EAppSpecificListViewListId1);
	MQikListBoxModel& model(listbox->Model());
	model.ModelBeginUpdateLC();

	// Simulate an error occuring, e.g. the ModelBeginUpdateLC() method leaving to
	// demonstrate that error handling is more than simply TRAPing the Leave().
	if (iEngine->ListViewSortType()==ESortType3)
		User::Leave(KErrNotFound);

	// Define the comparison function the sort should use
	TLinearOrder<MQikListBoxData> compare(CAppSpecificListView::SortComparisonFunction);

	// tell the model to perform the sort.
	model.Sort(compare);

	// we have now finished the sort, this will cause the display to be updated
	model.ModelEndUpdateL();
	}

void CAppSpecificListView::HandleCommandL(CQikCommand& aCommand)
//
// Handle the commands coming in from the controls that can deliver cmds..
//
	{
	switch (aCommand.Id())
		{
	case EAppCmdAbout:
		(new(ELeave)CAboutDialog)->ExecuteLD(R_ABOUT_DIALOG);
		break;

	case EAppCmdHelp:
		// very very poor mans help, the objective at this time is to show that the
		// system placed the Help command in platform specific position, overriding any
		// priority setting we happened to have defined.
		iEikonEnv->InfoWinL(R_STR_HELP_TITLE,R_STR_HELP_TEXT);
		break;

	case EAppCmdAdd2:
		AddSingleItemToList1L();
		break;

	// the generic delete cmd - assigned to the Cancel key in the RSS.
	case EAppCmdDelete:
		DeleteItemFromList1L();
		break;

	case EAppCmdSortCascade:
		// never called as its more of a placeholder for the cascade items 
		// than a command in its own right
		break;

	case EAppCmdSortType1:
		// NOTE that we have explictly NOT added any error handling code for this command.
		iEngine->SetListViewSortType(ESortType1);
		SortList1L();
		break;

	case EAppCmdSortType2:
		// NOTE that we have explictly NOT added any error handling code for this command.
		iEngine->SetListViewSortType(ESortType2);
		SortList1L();
		break;

	case EAppCmdSortType3:
		{
		// Error handling is more than simply TRAPing any Leave() that occurs. If you Sort by
		// type 3 and observe the UI you will note that the menu radio button state is
		// updated BEFORE we are delivered the command. Similarly we simply set the 
		// engine Sort type to be type 3. If the sort fails both the UI and the engine are 
		// out of sync with the actual data in the list box
		//
		// ROLLBACK is equally as important as actually catching the error
		// 
		// The following implements full error handling with rollback so the engine and
		// UI remain in a consistent state. 

		TAppSortTypes oldType=iEngine->ListViewSortType();
		iEngine->SetListViewSortType(ESortType3);
		TRAPD(err,SortList1L(););
		if (err!=KErrNone)
			{
			// set engine back to its previous state
			iEngine->SetListViewSortType(oldType);


			// now roll back the UI so the list box data, UI and engine are all in same state.
			CQikCommandManager& cm=CQikCommandManager::Static();
			TInt commandId=EAppCmdSortType1;
			if (oldType==ESortType2)
				commandId=EAppCmdSortType2;
			else if (oldType==ESortType3)
				commandId=EAppCmdSortType3;
			cm.SetChecked(*this,EAppCmdSortType3,EFalse);
			cm.SetChecked(*this,commandId,ETrue);
			LocateControlByUniqueHandle<CQikListBox>(EAppSpecificListViewListId1)->SetCurrentItemIndexL(0,ETrue,EDrawNow);
			User::Leave(err); // inform user via a system type dlg
			}
		break;
		}

	case EAppCmdSortOrder:
		// swap the ascending/descending state (a+d-a = d    or    a+d-d = a)
		iEngine->SetListViewSortOrder((TAppSortOrder)
					(ESortOrderAscending+ESortOrderDescending-iEngine->ListViewSortOrder()));
		SortList1L(); // again NO error handling code implemented here...
		break;
			
	case EAppCmdAdd:
	case EAppCmdDelete2:
	case EAppCmdDelete3:
	case EAppCmdSortAltType1:
	case EAppCmdSortAltType2:
	case EAppCmdDebugTest:
	// Clearly in a real application these should perform some real actions..
		iEikonEnv->InfoMsg(R_STR_NOT_IMPLMENTED_YET);
		break;

	default: // e.g. the back button...
		CQikViewBase::HandleCommandL(aCommand);
		break;
		}
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -