📄 svexopenappappview.cpp
字号:
// Copyright (c) 2006 Murray Read, All rights reserved
#include "SvexOpenAppAppView.h"
#include "SvexOpenAppAppUi.h"
#include "SvexService.hrh"
#include "SvexService.h"
#include <apaid.h>
#include <SvexUtil.h>
#include <SvexOpenApp.rsg>
#include "SvexOpenApp.hrh"
#include <aknQueryDialog.h>
const TInt KMimeAppGranularity = 1;
const TInt KMaxTextLen = 64;
CSvexOpenAppAppView* CSvexOpenAppAppView::NewL(const CSvexInfoBase& aInfo)
{
CSvexOpenAppAppView* self = new(ELeave) CSvexOpenAppAppView(aInfo);
CleanupStack::PushL(self);
self->ConstructMainPaneL();
CleanupStack::Pop(self);
return self;
}
CSvexOpenAppAppView::~CSvexOpenAppAppView()
{
delete iDialog;
}
CSvexOpenAppAppView::CSvexOpenAppAppView(const CSvexInfoBase& aInfo)
: CSvexServiceAppListView(KOpenServiceUid, aInfo)
{
}
void CSvexOpenAppAppView::OpenL()
{
TInt index = iListBox->CurrentItemIndex();
TInt count = iService->MsasiCount();
if (index < 0 || count <= index)
return;
// show the registration info for the selected app
ShowAppL(iService->MsasiAt(index));
}
// called by the app UI when it gets the ShowApp server message
void CSvexOpenAppAppView::ShowAppL(TUid aAppUid)
{
TInt count = iService->MsasiCount();
for (TInt ii=0; ii<count; ii++)
{
TSvexAppServiceInfo reg = iService->MsasiAt(ii);
if (aAppUid == reg.iAppUid)
{
ShowAppL(reg);
break;
}
}
}
void CSvexOpenAppAppView::ShowAppL(const TSvexAppServiceInfo& aReg)
{
iDialog = CSvexOpenDialog::NewL(aReg, iInfo);
iDialog->ExecuteLD();
iDialog = 0;
}
CSvexOpenDialog* CSvexOpenDialog::NewL(const TSvexAppServiceInfo& aReg, const CSvexInfoBase& aInfo)
{
CSvexOpenDialog* self = new(ELeave) CSvexOpenDialog(aReg, aInfo);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
CSvexOpenDialog::~CSvexOpenDialog()
{
}
CSvexOpenDialog::CSvexOpenDialog(const TSvexAppServiceInfo& aReg, const CSvexInfoBase& aInfo)
: CAppServiceInfoDialog(aReg, aInfo)
{
}
// The dialog text for the Open Service shows the mime-type list
// but not the opaque-data, which is not used.
void CSvexOpenDialog::DialogTextL()
{
TBuf<KMaxTextLen> b;
_LIT(KAppName, "App name:\n");
AppendTextL(KAppName);
AppendTextL(iInfo.AppCaption(iReg.iAppUid));
_LIT(KCrlf, "\n");
AppendTextL(KCrlf);
_LIT(KAppUid, "App UID:\n");
AppendTextL(KAppUid);
_LIT(K8HexFormat, "0x%08x\n\n");
b.Format(K8HexFormat, iReg.iAppUid);
AppendTextL(b);
_LIT(KMimeTypes, "Mime types:\n");
AppendTextL(KMimeTypes);
const CArrayFixFlat<TDataTypeWithPriority>& dataTypes = iReg.iInfo.DataTypes();
TInt count = dataTypes.Count();
for (TInt ii=0; ii<count; ii++)
{
const TDataTypeWithPriority& dataType = dataTypes[ii];
_LIT(KIntFormat, "%d ");
b.Format(KIntFormat, dataType.iPriority);
AppendTextL(b);
AppendTextL(dataType.iDataType.Des());
AppendTextL(KCrlf);
}
}
CSvexOpenAppMimeView* CSvexOpenAppMimeView::NewL(const CSvexInfoBase& aInfo)
{
CSvexOpenAppMimeView* self = new(ELeave) CSvexOpenAppMimeView(aInfo);
CleanupStack::PushL(self);
self->ConstructMainPaneL();
CleanupStack::Pop(self);
return self;
}
CSvexOpenAppMimeView::~CSvexOpenAppMimeView()
{
delete iSubView;
delete iMimeArray;
}
CEikTextListBox* CSvexOpenAppMimeView::NewListBoxL() const
{
return new (ELeave) CAknSingleStyleListBox();
}
TInt CSvexOpenAppMimeView::Count() const
{
return iMimeArray->Count();
}
void CSvexOpenAppMimeView::GetText(TInt aIndex, TBuf<KMaxListText>& aText) const
{
// Show the mime-type as a descriptor
TBuf<KMaxDataTypeLength> des(iMimeArray->At(aIndex).DataType().Des());
_LIT(KListFormat, "\t%S\t\t");
aText.Format(KListFormat, &des);
}
void CSvexOpenAppMimeView::OpenL()
{
TInt index = iListBox->CurrentItemIndex();
TInt count = Count();
if (index < 0 || count <= index)
return;
// Show the apps for a mime-type on OpenL.
ShowMimeL(iMimeArray->At(index));
}
CSvexOpenAppMimeView::CSvexOpenAppMimeView(const CSvexInfoBase& aInfo)
: iInfo(aInfo)
{
}
void CSvexOpenAppMimeView::ConstructMainPaneL()
{
iMimeArray = new(ELeave) CSvexMimeArray(iInfo);
iMimeArray->ConstructL();
CSvexListView::ConstructMainPaneL();
}
void CSvexOpenAppMimeView::ShowMimeL(CSvexMimeAppArray& aMimeAppArray)
{
// Launch a dialog to show the apps-for-mime-type sub-view
delete iSubView;
iSubView = 0;
iSubView = new(ELeave) CMimeAppListDialog(iInfo, aMimeAppArray);
iSubView->ConstructL(R_SVEXOPENAPP_MIMEAPPS_MENUBAR);
iSubView->ExecuteLD(R_SVEXOPENAPP_MIMEAPPS_DIALOG);
iSubView = 0;
_LIT(KMimeTypes, "Mime-types");
SetTitlePaneL(KMimeTypes);
}
CSvexMimeAppArray::CSvexMimeAppArray(const TDataType& aDataType)
: CArrayFixFlat<TSvexMimeAppWithPriority>(KMimeAppGranularity), iDataType(aDataType)
{
}
CSvexMimeAppArray::~CSvexMimeAppArray()
{
}
const TDataType& CSvexMimeAppArray::DataType() const
{
return iDataType;
}
// CSvexMimeArray has to turn an array of apps(and the mime types)
// they support into an array of mime-types(and the apps that
// support them). To do this, it uses a temporary RHashMap that
// uses the datatype name as a key.
CSvexMimeArray::CSvexMimeArray(const CSvexInfoBase& aInfo)
: iInfo(aInfo)
{
}
CSvexMimeArray::~CSvexMimeArray()
{
// destroy the mime-type array
iArray.ResetAndDestroy();
iArray.Close();
delete iService;
}
// RHashMap does not support TPtrC8 as a native key type
// so we must provide the hash function.
TUint32 TPtrC8Hash(const TPtrC8& aPtr)
{
return DefaultHash::Des8(aPtr);
}
// RHashMap does not support TPtrC8 as a native key type
// so we must provide the identity function.
TBool TPtrC8Ident(const TPtrC8& aL, const TPtrC8& aR)
{
return DefaultIdentity::Des8(aL, aR);
}
// Cleanup function to destroy the contents of the hashMap used during construction
void DestroyHashContents(TAny* aHash)
{
RHashMap<TPtrC8, CSvexMimeAppArray*>& hash = *static_cast<RHashMap<TPtrC8, CSvexMimeAppArray*>*>(aHash);
THashMapIter<TPtrC8, CSvexMimeAppArray*> mimeIter(hash);
for (CSvexMimeAppArray* const* pMime = mimeIter.NextValue(); pMime; pMime = mimeIter.NextValue())
{
delete *pMime;
}
}
void CSvexMimeArray::ConstructL()
{
ASSERT(!iArray.Count());
// Get the array of all apps that support the Open Service.
CleanupStack::Pop(iService = iInfo.DirectServiceInfoLC(KOpenServiceUid));
// count the maximum number of mime-types that could be used.
// note there are very few cases when a mime-type is supported
// by more than one app (but we do want to catch them).
TInt mimeCount = 0;
TInt count = iService->MsasiCount();
for (TInt ii=0; ii<count; ii++)
mimeCount += iService->MsasiAt(ii).iInfo.DataTypes().Count();
// Create the temporary hash map with the appropriate hash and identity functions
RHashMap<TPtrC8, CSvexMimeAppArray*> hash(&TPtrC8Hash, &TPtrC8Ident);
// make sure hash is closed on a leave
CleanupClosePushL(hash);
// make sure hash contents are deleted on a leave
CleanupStack::PushL(TCleanupItem(DestroyHashContents, &hash));
// Reserve enough space for all mime-types
hash.ReserveL(mimeCount);
// Add the mime-types for each app
for (TInt ii=0; ii<count; ii++)
AddRegL(iService->MsasiAt(ii), hash);
// convert the hashMap into an array
CompleteConstructL(hash);
// remove the DestroyHashContents protection, contents are now in the array.
CleanupStack::Pop();
// close the hash map
CleanupStack::PopAndDestroy(&hash);
}
void CSvexMimeArray::AddRegL(const TSvexAppServiceInfo& aReg, RHashMap<TPtrC8, CSvexMimeAppArray*>& aHash)
{
ASSERT(!iArray.Count());
// Go through the mime-types that the app supports
const CArrayFixFlat<TDataTypeWithPriority>& dataTypes = aReg.iInfo.DataTypes();
TInt count = dataTypes.Count();
for (TInt ii=0; ii<count; ii++)
{
const TDataTypeWithPriority& dataType = dataTypes[ii];
TPtrC8 des8(dataType.iDataType.Des8());
// look for the mime-type name in the hashMap
CSvexMimeAppArray** pArray = aHash.Find(des8);
if (!pArray)
{
// If not found, add a new entry to the hashMap with an empty app array
CSvexMimeAppArray* array = new(ELeave) CSvexMimeAppArray(dataType.iDataType);
CleanupStack::PushL(array);
aHash.InsertL(des8, array);
CleanupStack::Pop(array);
pArray = &array;
}
TSvexMimeAppWithPriority app(aReg);
app.iPriority = dataType.iPriority;
// add the app to the app array. NB, since there are very
// few apps that support any particular mime-type, there
// is no need to optimised the reallocating AppendL() calls
(*pArray)->AppendL(app);
}
}
void CSvexMimeArray::CompleteConstructL(RHashMap<TPtrC8, CSvexMimeAppArray*>& aHash)
{
ASSERT(!iArray.Count());
// reserve enough space in the array to hold all the elements
// in the hashMap
TInt count = aHash.Count();
iArray.ReserveL(count);
// Iterate through the contents of the hashMap. Add them
// to the array and remove them from the hashMap.
THashMapIter<TPtrC8, CSvexMimeAppArray*> mimeIter(aHash);
for (CSvexMimeAppArray* const* pMime = mimeIter.NextValue(); pMime; pMime = mimeIter.NextValue())
{
iArray.AppendL(*pMime);
mimeIter.RemoveCurrent();
}
}
TInt CSvexMimeArray::Count() const
{
return iArray.Count();
}
CSvexMimeAppArray& CSvexMimeArray::At(TInt aIndex)
{
return *iArray[aIndex];
}
CMimeAppListControl::CMimeAppListControl(const CSvexInfoBase& aInfo, CSvexMimeAppArray& aAppArray)
: iInfo(aInfo), iAppArray(aAppArray)
{
}
CMimeAppListControl::~CMimeAppListControl()
{
}
void CMimeAppListControl::ConstructFromResourceL(TResourceReader&)
{
ConstructControlL();
}
void CMimeAppListControl::ConstructControlL()
{
SetTitlePaneL(iAppArray.DataType().Des());
RApaLsSession& ls(iInfo.LsSession());
// get the default handler application for the mime-type
User::LeaveIfError(ls.AppForDataType(iAppArray.DataType(), iDefaultApp));
CSvexListView::ConstructControlL();
}
CEikTextListBox* CMimeAppListControl::NewListBoxL() const
{
return new (ELeave) CAknDoubleStyleListBox();
}
TInt CMimeAppListControl::Count() const
{
return iAppArray.Count();
}
void CMimeAppListControl::GetText(TInt aIndex, TBuf<KMaxListText>& aText) const
{
const TSvexMimeAppWithPriority& app = iAppArray[aIndex];
TApaAppCaption caption = iInfo.AppCaption(app.iReg.iAppUid);
TPtrC def(KNullDesC);
_LIT(KDefault, " (default)");
// if this app is the default handler for the mime-type, add
// the text "(default)" to the list text.
if (app.iReg.iAppUid == iDefaultApp)
def.Set(KDefault);
_LIT(KFormat, "\t%S\tpriority: %d%S\t");
aText.Format(KFormat, &caption, app.iPriority, &def);
}
void CMimeAppListControl::OpenL()
{
}
TSize CMimeAppListControl::MinimumSize()
{
return iEikonEnv->EikAppUi()->ClientRect().Size();
}
void CMimeAppListControl::HandleCommandL(TInt aCommand)
{
if (aCommand == ESvexOpenAppSetDefault)
SetDefaultL();
else
CSvexListView::HandleCommandL(aCommand);
}
void CMimeAppListControl::SetDefaultL()
{
TInt index = iListBox->CurrentItemIndex();
TSvexMimeAppWithPriority& app = iAppArray[index];
TInt priority = app.iPriority;
RApaLsSession& ls(iInfo.LsSession());
// Set this app to be the default handler for the mime-type.
// This is the code that requires the WriteDeviceData capability.
ls.DeleteDataMapping(iAppArray.DataType()); // ignore errors
User::LeaveIfError(ls.InsertDataMapping(iAppArray.DataType(), priority, app.iReg.iAppUid));
// Update the default handler for this mime-type.
User::LeaveIfError(ls.AppForDataType(iAppArray.DataType(), iDefaultApp));
}
CMimeAppListDialog::CMimeAppListDialog(const CSvexInfoBase& aInfo, CSvexMimeAppArray& aAppArray)
: iInfo(aInfo), iAppArray(aAppArray)
{
}
SEikControlInfo CMimeAppListDialog::CreateCustomControlL(TInt aControlType)
{
SEikControlInfo control = {0, 0, 0};
if (aControlType == EOpenServiceControlId)
control.iControl = new (ELeave) CMimeAppListControl(iInfo, iAppArray);
else
control = CAknDialog::CreateCustomControlL(aControlType);
return control;
}
void CMimeAppListDialog::ProcessCommandL(TInt aCommandId)
{
List()->HandleCommandL(aCommandId);
CAknDialog::ProcessCommandL(aCommandId);
}
TBool CMimeAppListDialog::OkToExitL(TInt aButtonId)
{
switch (aButtonId)
{
case EAknSoftkeyOk:
List()->HandleCommandL(KSvexCmdIdOpen);
break;
case EAknSoftkeyBack:
return ETrue;
default:
return CAknDialog::OkToExitL(aButtonId);
}
return EFalse;
}
CMimeAppListControl* CMimeAppListDialog::List()
{
return ((CMimeAppListControl*)Control(EOpenServiceLineId));
}
TSvexMimeAppWithPriority::TSvexMimeAppWithPriority(const TSvexAppServiceInfo& aReg)
: iReg(aReg)
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -