📄 commands1.cpp
字号:
//
// 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 + -