diff -r 1fc85118c3ae -r 870918037e16 landmarksui/uicontrols/src/CLmkSender.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/landmarksui/uicontrols/src/CLmkSender.cpp Wed Sep 01 12:31:27 2010 +0100 @@ -0,0 +1,669 @@ +/* + * Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies). + * All rights reserved. + * This component and the accompanying materials are made available + * under the terms of "Eclipse Public License v1.0" + * which accompanies this distribution, and is available + * at the URL "http://www.eclipse.org/legal/epl-v10.html". + * + * Initial Contributors: + * Nokia Corporation - initial contribution. + * + * Contributors: + * + * Description: LandmarksUi Sender class implementation + * + */ + +// INCLUDE FILES + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "LmkConsts.h" +#include "CLmkEncoder.h" +#include "landmarks.hrh" +#include "CLmkUiUtils.h" +#include "LmkFileUtils.h" +#include "Debug.h" +#include "CLmkSender.h" +#include "CLmkFields.h" +#include "LmkConsts.h" +#include "CLmkDbUtils.h" +#include +#include + +// CONSTANTS +//for the sendui query +const static TInt KBluetooth = 0x10009ed5; +const static TInt KInfrared = 0x100053A4; +const static TInt KEmail = 0x10001028; +const static TInt KMessaging = 0x102072D6; + +const TInt KNumOfReplaceChars(25); + +/// Unnamed namespace for local definitions +namespace + { + const TInt KLmkMtmFilterGranularity(8); +#if defined(_DEBUG) + _LIT( KPanicMsg, "CLmkSender" ); + + void Panic(TPanicCode aReason) + { + User::Panic(KPanicMsg, aReason); + } +#endif + } // namespace + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CLmkSender::CLmkSender +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CLmkSender::CLmkSender(CPosLandmarkDatabase& aDb) : + iLastOperationResult(KErrNone), iDb(aDb) + { + } + +// ---------------------------------------------------- +// CLmkSender::ConstructL +// ---------------------------------------------------- +// +void CLmkSender::ConstructL(CPosLandmarkDatabase& aDb) + { + iSendUi = CSendUi::NewL(); + iEncoder = CLmkEncoder::NewL(aDb, *this, ETrue); + } + +// ----------------------------------------------------------------------------- +// CLmkSender::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +EXPORT_C CLmkSender* CLmkSender::NewL(CPosLandmarkDatabase& aDb) + { + CLmkSender* self = new (ELeave) CLmkSender(aDb); + CleanupStack::PushL(self); + self->ConstructL(aDb); + CleanupStack::Pop(); + return self; + } + +// ---------------------------------------------------- +// CLmkSender::~CLmkSender +// ---------------------------------------------------- +// +CLmkSender::~CLmkSender() + { + if (iWaitNote) + { + TRAPD( err, iWaitNote->ProcessFinishedL() ); + if (err != KErrNone) + { + delete iWaitNote; + iWaitNote = NULL; + } + } + delete iEncoder; + delete iSendUi; + } + +// --------------------------------------------------------- +// CLmkSender::DisplaySendMenuL +// --------------------------------------------------------- +// +EXPORT_C void CLmkSender::DisplaySendMenuL(CEikMenuPane& aMenuPane, + TInt aVisibleCount, TInt aMenuTextResource) const + { + TInt pos(0); + aMenuPane.ItemAndPos(ELmkCmdSendDummy, pos); + // Set dummy command dimmed anyway. It was only needed because + // SendUI needs to know the right position: + aMenuPane.SetItemDimmed(ELmkCmdSendDummy, ETrue); + + // Now if there are items visible then let SendUi check whether + // option can be shown: + if (aVisibleCount > 0) + { + TSendingCapabilities capabilities(0, 0, + TSendingCapabilities::EAllServices); + iSendUi->AddSendMenuItemL(aMenuPane, pos, ELmkCmdSend, capabilities); + + // Set menu item text to desired value since previous operation + // overrides it with SendUI default value. + if (aMenuTextResource != KZeroResourceId) + { + aMenuPane.SetItemTextL(ELmkCmdSend, aMenuTextResource); + } + } + } + +// --------------------------------------------------------- +// CLmkSender::DisplaySendCascadeMenuL +// --------------------------------------------------------- +// +EXPORT_C void CLmkSender::DisplaySendCascadeMenuL(CEikMenuPane& /*aMenuPane*/) const + { + // Construct the MTM filter + CArrayFixFlat* mtmFilter = new (ELeave) CArrayFixFlat ( + KLmkMtmFilterGranularity); + CleanupStack::PushL(mtmFilter); + mtmFilter->AppendL(KSenduiMtmSmsUid); // hide SMS + mtmFilter->AppendL(KSenduiMtmFaxUid); // hide fax + CleanupStack::PopAndDestroy(); // mtmFilter + } + +// ---------------------------------------------------- +// CLmkSender::CreateAndSendL +// ---------------------------------------------------- +// +void CLmkSender::CreateAndSendL(TInt aCommandId, + const RArray& aMarkedIds, TPosLmItemId aSelectedId) + { + DEBUG( CLmkSender::CreateAndSendL entered ); + HBufC* filePath; + PrepareSendFilePathL(filePath); + TPtr ptr = filePath->Des(); + TInt markedCount = aMarkedIds.Count(); + if (markedCount == 0 || markedCount == 1) + { + // One item only marked or unmarked + RArray lmIdArray(1); + CleanupClosePushL(lmIdArray); + User::LeaveIfError(lmIdArray.Append(aSelectedId)); + CPosLandmark* landmark = iDb.ReadLandmarkLC(aSelectedId); + HBufC* webUrl = HBufC::NewL(KMaxBufferLen); + CleanupStack::PushL(webUrl); + TPtrC urlDes = webUrl->Des(); + landmark->GetPositionField(ELmkPositionFieldWebAddress, urlDes); + if (urlDes.Length() > KMaxUrlFieldLenWithDefaultProtocol) + { + TInt pos = urlDes.Find(KProtocol); + if (pos == KErrNotFound) + { + webUrl = webUrl->ReAllocL(KHttp().Length() + urlDes.Length()); + TPtr url = webUrl->Des(); + webUrl->Des().Copy(urlDes); + webUrl->Des().Insert(0, KHttp); + landmark->SetPositionFieldL(ELmkPositionFieldWebAddress, + webUrl->Des()); + } + } + CleanupStack::PopAndDestroy();//webUrl + TPtrC landmarkName; + TInt retVal(0); + retVal = landmark->GetLandmarkName(landmarkName); + if (retVal == KErrNone) + { + iEncoder->StartEncodingL(landmarkName, lmIdArray); + ptr.Append(landmarkName); + } + else + { + iEncoder->StartEncodingL(KLmkEncodedDataFileName, lmIdArray); + ptr.Append(KLmkEncodedDataFileName); + } + SendL(ptr, aCommandId); + CleanupStack::PopAndDestroy(2); //landmark, lmIdArray + } + else + { + HBufC* pckgName; + TPtrC currentPckgName;//not really used, only for passing to the func. + if (QueryNewPackageNameLC(currentPckgName, pckgName)) + { + TPtr name = pckgName->Des(); + iEncoder->StartEncodingL(name, aMarkedIds); + ptr.Append(name); + SendL(ptr, aCommandId); + } + CleanupStack::PopAndDestroy(); + } + CleanupStack::PopAndDestroy(filePath); //filePath + } +// ---------------------------------------------------- +// CLmkSender::HandleOperationL +// ---------------------------------------------------- +// +void CLmkSender::HandleOperationL(TOperationTypes /*aType*/, + TReal32 /*aProgress*/, TInt aStatus) + { + if (aStatus != KPosLmOperationNotComplete) + { + __ASSERT_DEBUG( iWaitNote, Panic( KLmkPanicNullMember ) ); + iWaitNote->ProcessFinishedL(); + iWaitNote = NULL; + iLastOperationResult = aStatus; + } + } + +// ---------------------------------------------------- +// CLmkSender::SendLandmarksL +// ---------------------------------------------------- +// +void CLmkSender::SendLandmarksL(TInt aCommandId, const TDesC& aPackageName, + const RPointerArray& aLandmarks) + { + DEBUG( CLmkSender::SendMultipleLandmarkL entered ); + TInt lmkCount = aLandmarks.Count(); + __ASSERT_DEBUG(lmkCount > 0, Panic( KLmkPanicNullMember ) ); + if (lmkCount == 1) + { + SendSingleLandmarkL(aCommandId, aLandmarks); + } + else + { + SendLandmarksPackageL(aCommandId, aPackageName, aLandmarks); + } + } + +// ---------------------------------------------------- +// CLmkSender::SendSingleLandmarkL +// ---------------------------------------------------- +// +void CLmkSender::SendSingleLandmarkL(const CPosLandmark& alandmark) + { + CLmkLandmark* lmkLandmark; + LmkLandmarkFromPosLandmarkL(lmkLandmark, alandmark); + SendSingleLandmarkL(ELmkCmdSend, *lmkLandmark); + CleanupStack::PopAndDestroy();//landMarkLmk + } + +// ---------------------------------------------------- +// CLmkSender::SendSingleLandmarkL() +// ---------------------------------------------------- +// +void CLmkSender::SendSingleLandmarkL(TInt aCommandId, + const CLmkLandmark& alandmark) + { + TPtrC ptr; + RPointerArray landmark; + landmark.Append(&alandmark); + SendLandmarksL(aCommandId, ptr, landmark); + landmark.Close(); + } + +// ---------------------------------------------------- +// CLmkSender::SendSingleLandmarkL() +// ---------------------------------------------------- +// +void CLmkSender::SendSingleLandmarkL(TInt aCommandId, const RPointerArray< + CLmkLandmark>& aLandmarks) + { + HBufC* filePath; + PrepareSendFilePathL(filePath); + TPtr ptr = filePath->Des(); + CLmkLandmark* lmk = aLandmarks[0]; + CPosLandmark* landmark = lmk->PosLandmark(); + CLmkDbUtils::AddDefaultProtocolL(landmark); + TPtrC landmarkName; + TInt retVal(KErrNone); + retVal = landmark->GetLandmarkName(landmarkName); + + if (retVal == KErrNone && LmkFileUtils::IsValidPathL(landmarkName)) + { + TRAP(retVal,iEncoder->StartEncodingL(landmarkName,aLandmarks)); + if (retVal == KErrNone) + { + ptr.Append(landmarkName); + } + } + else + { + retVal = KErrBadName; + } + + if (retVal != KErrNone) + { + TPtr lmName = ReplaceSpecialCharactersL(landmarkName); + TRAP(retVal,iEncoder->StartEncodingL(lmName,aLandmarks)); + if (retVal == KErrNone) + { + ptr.Append(lmName); + } + else + { + iEncoder->StartEncodingL(KLmkEncodedDataFileName, aLandmarks); + ptr.Append(KLmkEncodedDataFileName); + } + } + SendL(ptr, aCommandId); + CleanupStack::PopAndDestroy(filePath); //filePath + } + +// ---------------------------------------------------- +// CLmkSender::SendLandmarksPackageL +// ---------------------------------------------------- +// +void CLmkSender::SendLandmarksPackageL(TInt aCommandId, + const TDesC& aPackageName, + const RPointerArray& aLandmarks) + { + HBufC* pckgName; + HBufC* filePath; + PrepareSendFilePathL(filePath); + TPtr ptr = filePath->Des(); + if (QueryNewPackageNameLC(aPackageName, pckgName)) + { + TPtr desName = pckgName->Des(); + iEncoder->StartEncodingL(desName, aLandmarks); + ptr.Append(desName); + SendL(ptr, aCommandId); + } + CleanupStack::PopAndDestroy(2); + } + +// ---------------------------------------------------- +// CLmkSender::SendL() +// ---------------------------------------------------- +// +void CLmkSender::SendL(TDes& aFilePath, TInt aCommandId) + { + aFilePath.Append(KLmkEncodedDataFileExtension); + iWaitNote = new (ELeave) CAknWaitDialog(NULL, ETrue); + if (iWaitNote->ExecuteLD(R_LMK_ENCODING_WAIT_NOTE)) + { + if (iLastOperationResult == KErrNone) + { + RFs fs; + User::LeaveIfError(fs.Connect()); + CleanupClosePushL(fs); + User::LeaveIfError(fs.ShareProtected()); + RFile fileHandle; + User::LeaveIfError(fileHandle.Open(fs, aFilePath, EFileShareAny)); + CleanupClosePushL(fileHandle); + TRAPD( err, SendFileL( aCommandId, fileHandle, ETrue)); + if (err != KErrNone) + { + CleanupStack::PopAndDestroy(); // fileHandle + LmkFileUtils::DeleteFileL(aFilePath); + CleanupStack::PopAndDestroy(); // fs + User::LeaveIfError(err); + } + CleanupStack::PopAndDestroy(); // fileHandle + LmkFileUtils::DeleteFileL(aFilePath); + CleanupStack::PopAndDestroy(); // fs + } + else + { // error situation + CCoeEnv::Static()->HandleError(iLastOperationResult); + } + } + else + { + //making iWaitNote null, since framework destroys waitnote + //dialog on pressing cancel. + iWaitNote = NULL; + iEncoder->CancelEncodeOperationL(); + } + } + +// ---------------------------------------------------- +// CLmkSender::SendFileL +// ---------------------------------------------------- +// +void CLmkSender::SendFileL(TInt /*aCommandId*/, const TDesC& aFile, + TBool aDeleteSentFile) + { + DEBUG( CLmkSender::SendFileL entered ); + + // one attachment only: + CMessageData * messageData = CMessageData::NewL(); + CleanupStack::PushL( messageData ); + messageData->AppendAttachmentL( aFile ); + DEBUG( CLmkSender::SendFileL: calling SendUI ); + LoadFilteredSendListQueryL(messageData); + DEBUG( CLmkSender::SendFileL: SendUI returned ); + + // Delete the file since it is no more needed + if( aDeleteSentFile ) + { + LmkFileUtils::DeleteFileL( aFile ); + } + CleanupStack::PopAndDestroy( messageData ); + } + +// ---------------------------------------------------- +// CLmkSender::SendFileL -- FileHandle version +// ---------------------------------------------------- +// +void CLmkSender::SendFileL(TInt /*aCommandId*/, RFile& aFile, TBool /*aDeleteSentFile*/) + { + DEBUG( CLmkSender::SendFileL entered ); + + // one attachment only: + CMessageData * messageData = CMessageData::NewL(); + CleanupStack::PushL(messageData); + messageData->AppendAttachmentHandleL(aFile); + DEBUG( CLmkSender::SendFileL: calling SendUI ); + LoadFilteredSendListQueryL(messageData); + CleanupStack::PopAndDestroy(); //messageData + DEBUG( CLmkSender::SendFileL: SendUI returned ); + } + +// ---------------------------------------------------- +// CLmkSender::QueryPackageName +// ---------------------------------------------------- +// +TBool CLmkSender::QueryNewPackageNameLC(const TDesC& aCurrentPckgName, + HBufC*& aNewPackageName) + { + TBool retVal = EFalse; + HBufC* pkgName = StringLoader::LoadL(R_LMK_DEFAULT_PACKAGE_NAME, + CEikonEnv::Static()); + + if (aCurrentPckgName.Length() > pkgName->Des().Length()) + { + delete pkgName; + pkgName = NULL; + pkgName = HBufC::NewL(aCurrentPckgName.Length()); + pkgName->Des().Copy(aCurrentPckgName); + } + + TPtr desName = pkgName->Des(); + + CAknTextQueryDialog* dlg = new (ELeave) CAknTextQueryDialog(desName, + CAknQueryDialog::ENoTone); + if (dlg->ExecuteLD(R_LMK_PACKAGE_NAME_QUERY)) + { + retVal = ETrue; + if (!LmkFileUtils::IsValidPathL(desName)) + { + delete pkgName; + pkgName = NULL; + + TInt len = KLmkEncodedDataFileName().Length(); + aNewPackageName = HBufC::NewLC(len); + aNewPackageName->Des().Copy(KLmkEncodedDataFileName); + return retVal; + } + } + aNewPackageName = HBufC::NewLC(pkgName->Des().Length()); + aNewPackageName->Des().Copy(pkgName->Des()); + + delete pkgName; + pkgName = NULL; + + return retVal; + } + +// ---------------------------------------------------- +// CLmkSender::LmkLandmarkFromPosLandmarkL() +// ---------------------------------------------------- +// +void CLmkSender::LmkLandmarkFromPosLandmarkL(CLmkLandmark*& aLmkLandmark, + const CPosLandmark& aPosLandmark) + { + RArray categoryIdArray; + RPointerArray categories; + aPosLandmark.GetCategoriesL(categoryIdArray); + + CPosLmCategoryManager* categoryMgr = CPosLmCategoryManager::NewL(iDb); + CleanupStack::PushL(categoryMgr); + TInt catCount = categoryIdArray.Count(); + for (TInt i = 0; i < catCount; i++) + { + TPosLmItemId catId = categoryIdArray[i]; + CPosLandmarkCategory* category = categoryMgr->ReadCategoryLC(catId); + categories.Append(category); + CleanupStack::Pop(); + } + categoryIdArray.Close(); + CleanupStack::PopAndDestroy();//categoryMgr + aLmkLandmark = CLmkLandmark::NewL(&aPosLandmark, categories); + CleanupStack::PushL(aLmkLandmark); + categories.ResetAndDestroy(); + } + +// ---------------------------------------------------- +// CLmkSender::PrepareSendFilePathL() +// ---------------------------------------------------- +// +void CLmkSender::PrepareSendFilePathL(HBufC*& aFilePath) + { + // Full path name (private path c:\\private\\UID3 + pacakge File name + File bname Extension) + aFilePath = HBufC::NewLC(2 * KLmkPackageNameMaxLen + + KLmkEncodedDataFileExtension().Length()); + TPtr ptr = aFilePath->Des(); + + // Create the private path(c:\\private\\UID3) for Landmarks UI application + TFileName fileName; + RFs fs; + User::LeaveIfError(fs.Connect()); + CleanupClosePushL(fs); + fs.SessionPath(fileName); + fs.MkDirAll(fileName); + aFilePath->Des().Append(fileName); + CleanupStack::PopAndDestroy(); // fs + } + +// ---------------------------------------------------- +// CLmkSender::PrepareMultipleLandmarkForSendL() +// ---------------------------------------------------- +// +void CLmkSender::PrepareMultipleLandmarkForSendL( + RPointerArray& aLmkLandmark, + const RArray& aMarkedIds) + { + /* + This function prepares an array of CLmkLandmark from given + landmark ids. + */ + for (TInt i = 0; i < aMarkedIds.Count(); i++) + { + CPosLandmark* landmark = iDb.ReadLandmarkLC(aMarkedIds[i]); + CLmkLandmark* lmk; + LmkLandmarkFromPosLandmarkL(lmk, *landmark); + CleanupStack::Pop(lmk); + User::LeaveIfError(aLmkLandmark.Append(lmk)); + CleanupStack::PopAndDestroy();//landmark + } + } + +// ---------------------------------------------------- +// CLmkSender::LoadFilteredSendListQueryL() +// ---------------------------------------------------- +// +void CLmkSender::LoadFilteredSendListQueryL(const CMessageData* aMessageData) + { + /** + * Currently we need to show only four services in the sendui query + * 1.via messaging + * 2.via bluetooth + * 3.via infrared + * 4.via email + */ + RPointerArray serviceList; + CleanupClosePushL(serviceList); + //load all the available services + iSendUi->AvailableServicesL(serviceList); + TInt count = serviceList.Count(); + CArrayFixFlat* serviceFilter = new (ELeave) CArrayFixFlat ( + count); + CleanupStack::PushL(serviceFilter); + for (TInt i = 0; i < count; i++) + { + CSendingServiceInfo* info = serviceList[i]; + TPtrC ptr = info->ServiceName(); + CleanupStack::PushL(info); + TUid id = info->ServiceId(); + //check if this service is not one of the required list + if (id.iUid != KBluetooth && id.iUid != KInfrared && id.iUid + != KEmail && id.iUid != KMessaging) + { + //unwanted serivce list for filtering. + serviceFilter->AppendL(info->ServiceId()); + } + CleanupStack::PopAndDestroy();//info + } + TSendingCapabilities capabilities(0, 0, + TSendingCapabilities::ESupportsAttachments); + iSendUi->ShowQueryAndSendL(aMessageData, capabilities, serviceFilter); + CleanupStack::PopAndDestroy(2);//serviceList,serviceFilter + } + +// ---------------------------------------------------- +// CLmkSender::ReplaceSpecialCharactersL +// ---------------------------------------------------- +// +TPtr CLmkSender::ReplaceSpecialCharactersL(TPtrC aText) + { + TBuf replaceChars; + replaceChars.Zero(); + + // special chars from Unicode/Character reference + replaceChars.Append(0x0022); // """ + replaceChars.Append(0x002A); // "*" + replaceChars.Append(0x002F); // "/" + + replaceChars.Append(0x003A); // ":" + replaceChars.Append(0x003C); // "<" + replaceChars.Append(0x003E); // ">" + replaceChars.Append(0x003F); // "?" + replaceChars.Append(0x005C); // "\" + replaceChars.Append(0x007C); // "|" + + TInt nameLength = KLmkEncodedDataFileName.iTypeLength; + if (nameLength < aText.Length()) + { + nameLength = aText.Length(); + } + HBufC* buffer = HBufC::NewLC(nameLength); + TPtr des1 = buffer->Des(); + des1.Copy(aText); + AknTextUtils::ReplaceCharacters(des1, replaceChars, TChar(' ')); + + TInt spaceCount = 0; + for (TInt i = 0; i < des1.Length(); i++) + { + if (des1[i] == TChar(' ')) + spaceCount++; + } + + if (spaceCount == des1.Length()) + { + des1.Copy(KLmkEncodedDataFileName); + } + + CleanupStack::Pop(buffer); + return des1; + } + +// End of File +