📄 txtscpmv.cpp
字号:
// TXTSCPMV.CPP
//
// Copyright (c) 1999 Symbian Ltd. All rights reserved.
//
#if !defined(__E32STD_H__)
#include <e32std.h>
#endif
#if !defined(__TXTETEXT_H__)
#include <txtetext.h>
#endif
#if !defined(__TXTRICH_H__)
#include <txtrich.h>
#endif
#if !defined(__APPARC_H__)
#include <apparc.h>
#endif
#if !defined(__MSVUIDS_H__)
#include <MSVUIDS.H>
#endif
#if !defined(__MSVIDS_H__)
#include <MSVIDS.H>
#endif
#include "txtserv.h"
#include "txtscpmv.h"
#include "txtspan.h"
//
// CTxtActiveOper: base class for move, copy and delete operations
//
CTxtActiveOper::CTxtActiveOper(RFs& aFs, CMsvServerEntry& aServerEntry)
: CActive(0), iServerEntry(aServerEntry), iFs(aFs)
{
CActiveScheduler::Add(this);
iFs.Connect();
}
CTxtActiveOper::~CTxtActiveOper()
{
Cancel();
}
void CTxtActiveOper::Start(TMsvId& aSourceId, TMsvId& aDestId, TRequestStatus& aStatus)
//
// Start asynchronous transfer.
//
{
iSourceId = aSourceId;
iDestId = aDestId;
iStatus = KRequestPending;
iReportStatus = &aStatus;
SetActive();
aStatus = KRequestPending;
TRequestStatus *sP=&iStatus;
User::RequestComplete(sP, KErrNone);
}
void CTxtActiveOper::DoCancel()
{
}
void CTxtActiveOper::RunL()
//
// Default operation: do nothing
//
{
TRAPD(errorCode, DoRunL());
// Within this class, a leave is an external (service) error
// This basically means the DoRunL implementation is not allowed to leave with an error
// after calling User::RequestComplete
if (errorCode)
{
iCurrentCaller->Progress().iErrorCode = errorCode;
User::RequestComplete(iReportStatus, KErrNone);
}
}
//
// CTxtCopyMoveBase: walks over all the items in aSource, and starts aActiveOperation
// for each one of them, waiting for completion.
//
CTxtCopyMoveBase* CTxtCopyMoveBase::NewL(CTxtActiveOper* aActiveOperation, const CMsvEntrySelection& aSource,
CMsvServerEntry& aDestination, TMsvId& aServiceEntryId, TParse& aParse)
{
CTxtCopyMoveBase* self = new (ELeave) CTxtCopyMoveBase(aActiveOperation,aSource,
aDestination, aServiceEntryId, aParse);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop();
return self;
}
CTxtCopyMoveBase* CTxtCopyMoveBase::CopyConstructL(const CMsvEntrySelection& aSource)
{
CTxtActiveOper* newActive = iActiveOperation->CopyConstructL();
return NewL(newActive, aSource, iDestination, iServiceEntryId, iServiceDestinationpath);
}
CTxtCopyMoveBase::CTxtCopyMoveBase(CTxtActiveOper* aActiveOperation, const CMsvEntrySelection& aSource,
CMsvServerEntry& aDestination, TMsvId& aServiceEntryId, TParse& aParse)
: CActive( KMsgTxtRefreshMailboxPriority ),
iActiveOperation(aActiveOperation), iSource(aSource), iDestination(aDestination),
iServiceEntryId(aServiceEntryId), iServiceDestinationpath(aParse)
{
}
void CTxtCopyMoveBase::ConstructL()
{
iDestId = iDestination.Entry().Id();
iActiveOperation->SetCurrentCaller(this);
if (iActiveOperation->MoveIsToService())
{
__ASSERT_ALWAYS(iDestination.Entry().iServiceId == iServiceEntryId, gPanic(ETxtsInvalidService));
}
CActiveScheduler::Add(this); // Add CTxtCopyMoveBase to scheduler's queue
}
CTxtCopyMoveBase::~CTxtCopyMoveBase()
{
Cancel();
delete iActiveOperation;
iActiveOperation = NULL;
}
void CTxtCopyMoveBase::DoCancel()
//
// Cancel any current operation
//
{
delete iActiveOperation;
iActiveOperation = NULL;
iTxtCopyMoveState = ETxtFinished;
}
void CTxtCopyMoveBase::Start(TRequestStatus& aStatus)
//
// Start me up
//
{
iReportStatus = &aStatus;
iMsgCounter = -1;
// set up progress object
iProgress.iTotalMsgs=iSource.Count();
iProgress.iMsgsProcessed=0;
iProgress.iErrorCode=KErrNone;
if(iSource.Count())
{
iTxtCopyMoveState=ETxtRetrievingMessage;
}
else
{
iTxtCopyMoveState=ETxtFinished;
}
aStatus = KRequestPending;
SetActive();
TRequestStatus *sP=&iStatus;
User::RequestComplete(sP, KErrNone);
}
void CTxtCopyMoveBase::RunL()
{
TRAPD(errorCode, DoRunL());
// In this class a leave is an internal error
// No leave is allowed after calling User::RequestComplete in DoRunL because
// of this implementation
if (errorCode)
{
User::RequestComplete(iReportStatus, errorCode);
}
}
void CTxtCopyMoveBase::CheckDeleteSource()
// Delete previous source message if necessary
{
if (iMsgCounter>=0)
{
if (iActiveOperation->DeleteSourceAfterwards())
{
//delete the previous source
iDestination.SetEntry(iSource[iMsgCounter]);
TMsvId parent = iDestination.Entry().Parent();
iDestination.SetEntry(parent);
iDestination.DeleteEntry(iSource[iMsgCounter]);
}
}
}
void CTxtCopyMoveBase::SetupNewEntryL(TMsvId& aSourceMsgId, TMsvId& aNewDestMsvId)
// Create new entry index details based on source
{
// Get the destination path, and put it in the details
// section of the message
iDestination.SetEntry(aSourceMsgId);
TMsvEntry entry;
entry.iServiceId = iDestination.Entry().iServiceId;
entry.iRelatedId = iDestination.Entry().iRelatedId;
entry.iType = iDestination.Entry().iType;
entry.iMtm = iDestination.Entry().iMtm;
entry.iDate = iDestination.Entry().iDate;
entry.iSize = iDestination.Entry().iSize;
entry.iError = iDestination.Entry().iError;
// entry.iWdpPortNumber = iDestination.Entry().iWdpPortNumber;
entry.iMtmData1 = iDestination.Entry().iMtmData1;
entry.iMtmData2 = iDestination.Entry().iMtmData2;
entry.iMtmData3 = iDestination.Entry().iMtmData3;
// Copy the details and description for protection
TFileName name=iDestination.Entry().iDescription;
TFileName path=iDestination.Entry().iDetails;
entry.iDescription.Set(name);
entry.iDetails.Set(path);
entry.SetUnread(ETrue);
entry.SetNew(ETrue);
// If the move is to the service, make sure the entry is valid
if (iActiveOperation->MoveIsToService())
{
__ASSERT_DEBUG(name.Length()>0,gPanic(ETxtsInvalidFileName));
if (name.Length()==0)
User::Leave(KErrArgument);
entry.iDetails.Set(iServiceDestinationpath.FullName());
entry.iServiceId = iServiceEntryId;
}
else
{
entry.iServiceId = KMsvLocalServiceIndexEntryId;
}
// Create the new entry
iDestination.SetEntry(iDestId);
iDestination.CreateEntry(entry);
aNewDestMsvId=entry.Id();
iProgress.iNewId = aNewDestMsvId;
}
void CTxtCopyMoveBase::DoRunL()
{
// Check if error occurred on last stage
User::LeaveIfError(iStatus.Int()); // Leave if internal error has occurred.
if (iProgress.iErrorCode != KErrNone) // External error occurred
{
User::RequestComplete(iReportStatus,KErrNone);
return;
}
// Delete previous source message if necessary
CheckDeleteSource();
switch (iTxtCopyMoveState)
{
case ETxtRetrievingMessage:
// Operate on the next message
{
iMsgCounter++;
// For copy/move ops, make a new entry on the other side.
TMsvId newSourceMsgId=iSource[iMsgCounter];
TMsvId newDestMsvId=KMsvNullIndexEntryId;
if (iActiveOperation->CopiedHeader()) SetupNewEntryL(newSourceMsgId,newDestMsvId);
iProgress.iMsgsProcessed++; // Update progress info
// Check if finished
if(iMsgCounter == iSource.Count()-1)
{
iTxtCopyMoveState = ETxtFinished;
}
// Do the operation-specific part
iActiveOperation->Start(newSourceMsgId,newDestMsvId,iStatus);
SetActive();
}
break;
case ETxtFinished:
// Have now finished this operation, so pass the completion up
__ASSERT_DEBUG(iReportStatus != NULL, gPanic(ETxtsStrayRequest));
User::RequestComplete(iReportStatus,KErrNone);
break;
}
}
TTxtProgress& CTxtCopyMoveBase::Progress()
//
// Report the refreshing news back to the UI
//
{
return iProgress;
}
//
// Implementation of the several body-moving classes
//
void CTxtCopyToLocalOp::DoRunL()
//
// Copy one remote entry to local, getting the source text and storing
// it in the associated CMsvStore
//
{
User::LeaveIfError(iStatus.Int());
User::LeaveIfError(iServerEntry.SetEntry(iSourceId));
TMsvEntry entry = iServerEntry.Entry();
// Build a new source file file name
User::LeaveIfError(iServerEntry.SetEntry( iDestId ));
TxtUtils::GetEntryFileNameL(iFileName, entry);
DoMessageCopyToLocalL();
}
void CTxtCopyToLocalOp::DoMessageCopyToLocalL()
// Copy remote message to local: i.e. read file contents into message store
{
// Description of the body is the original file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -