Execution of landmark operations
Article Metadata
Contents |
Short description
CPosLmOperation - this is base class for landmark operations, it supports two variants of execution:
- method ExecuteL() allows to run the operation synchronously (batch mode):
Library required:
LIBRARY eposlandmarks.lib //CPosLandmarkDatabase, CPosLmOperation
Capabilities needed:
Capability LocalServices NetworkServices ReadDeviceData
Capability ReadUserData WriteDeviceData WriteUserData
CPosLmOperation* operation = iDb->InitializeL();
CleanupStack :: PushL( operation );
operation->ExecuteL();
CleanupStack :: PopAndDestroy( operation );
This can be simplified by using function ExecuteAndDeleteLD. It runs the operation and deletes the object when it is done.
ExecuteAndDeleteLD( iDb->InitializeL() );
- method NextStep() allows to run the operation asynchronously by using active objects (incrementally execution).
Base class for incrementally execution
You can use class CLmOperationHandler as a base class for the incrementally execution operations. Descendants must override only one method ExecL().
CLmOperationHandler header:
#include <e32base.h>
// forward declarations
class CPosLandmarkDatabase;
class CPosLmOperation;
// operation execution obserever
class MLmOperationHandlerObserver
{
public:
virtual void OnOperationProgress( TInt aProgress ) = 0;
virtual void OnOperationError( TInt aErrorCode ) = 0;
};
class CLmOperationHandler : public CActive
{
public:
CLmOperationHandler( const TDesC& anUri, MLmOperationHandlerObserver* anObserver );
virtual ~CLmOperationHandler();
void ExecuteL(); // start incremental execution
void NotifyStop(); // notify the need to stop
protected:
virtual void ExecL() = 0;
private:
void DelObjects(); // free memory
public: // From CActive
void RunL();
void DoCancel();
protected: // Data
TBool iNeedStop; // stop flag
CPosLmOperation* iOperation; // current operation
CPosLandmarkDatabase* iDb; // landmark database for the operation
TBuf<128> iUri; // database URI
TReal32 iProgress; // current operation progress
MLmOperationHandlerObserver* iObserver;
};
CLmOperationHandler implementation:
#include <epos_landmarks.h>
#include <epos_cposlandmarkdatabase.h>
#include "LmOpHandler.h"
CLmOperationHandler :: CLmOperationHandler( const TDesC& anUri,
MLmOperationHandlerObserver* anObserver ):
CActive( EPriorityNormal ),
iObserver( anObserver ), iNeedStop( EFalse ), iUri( anUri )
{
CActiveScheduler :: Add( this );
}
CLmOperationHandler :: ~CLmOperationHandler()
{
Cancel(); // cancel request
DelObjects(); // guaranteed removing
}
void CLmOperationHandler :: ExecuteL()
{
iObserver->OnOperationProgress( 0 ); // operation start
ExecL(); // virtual method call
}
void CLmOperationHandler :: NotifyStop()
{
iNeedStop = ETrue; // stop flag
}
void CLmOperationHandler :: RunL()
{
switch( iStatus.Int() )
{
case KPosLmOperationNotComplete:
if( iNeedStop )
{
// need to stop ("Cancel" was pressed)
DelObjects();
iNeedStop = EFalse;
}
else
{
// notify observer
iObserver->OnOperationProgress( iProgress * 100 );
// next iteration
iOperation->NextStep( iStatus, iProgress );
SetActive();
}
break;
case KErrNone:
{
// The operation has completed.
iObserver->OnOperationProgress( 100 );
DelObjects();
} break;
default:
{
// error occured
iObserver->OnOperationError( iStatus.Int() );
DelObjects();
} break;
}
}
void CLmOperationHandler :: DoCancel()
{
// Cancel is done by deleting the operation object.
DelObjects();
}
void CLmOperationHandler :: DelObjects()
{
delete iOperation;
iOperation = NULL;
delete iDb;
iDb = NULL;
}
The examples of descendants:
// this class allows to initialize database
class CLmOpDbInitHandler : public CLmOperationHandler
{
public:
CLmOpDbInitHandler( const TDesC& anUri, MLmOperationHandlerObserver* anObserver ):
CLmOperationHandler( anUri, anObserver ) {}
protected:
void ExecL()
{
iDb = CPosLandmarkDatabase :: OpenL( iUri );
if( iDb->IsInitializingNeeded() )
{
iOperation = iDb->InitializeL();
iOperation->NextStep( iStatus, iProgress );
SetActive();
}
else
{
// initialization not needed - forced finishing
iStatus = KErrNone;
RunL();
}
}
};
// this class allows to compact database
class CLmOpDbCompactHandler : public CLmOperationHandler
{
public:
CLmOpDbCompactHandler( const TDesC& anUri, MLmOperationHandlerObserver* anObserver ):
CLmOperationHandler( anUri, anObserver ) {}
protected:
void ExecL()
{
iDb = CPosLandmarkDatabase :: OpenL( iUri );
iOperation = iDb->CompactL();
iOperation->NextStep( iStatus, iProgress );
SetActive();
}
};
Progress dialog
Class CLmProgressDialog demonstrates how to realize simple progress dialog.
Header:
#include <eikprogi.h>
#include <AknProgressDialog.h>
class MProgressDialogObserver
{
public:
virtual void CancelOperation() = 0;
};
class CLmProgressDialog : public MProgressDialogCallback
{
public:
CLmProgressDialog( MProgressDialogObserver* anObserver ):
iObserver( anObserver ), iProgressDialog( NULL ), iProgressInfo( NULL ) {}
virtual ~CLmProgressDialog();
void StartProgressNoteL();
void UpdateProcessL( TInt aProgress, const TDesC& aProgressText );
void ProcessFinishedL();
protected:
void DialogDismissedL( TInt aButtonId );
private:
CAknProgressDialog* iProgressDialog;
CEikProgressInfo* iProgressInfo;
MProgressDialogObserver* iObserver;
};
Implementation:
CLmProgressDialog :: ~CLmProgressDialog()
{
ProcessFinishedL();
}
void CLmProgressDialog :: StartProgressNoteL()
{
iProgressDialog = new (ELeave) CAknProgressDialog(
reinterpret_cast<CEikDialog**>( &iProgressDialog ),
ETrue );
iProgressDialog->PrepareLC( R_PROGRESS_NOTE );
iProgressInfo = iProgressDialog->GetProgressInfoL();
iProgressDialog->SetCallback( this );
iProgressDialog->RunLD();
iProgressInfo->SetFinalValue( 100 );
}
void CLmProgressDialog :: UpdateProcessL( TInt aProgress, const TDesC& aProgressText )
{
if( iProgressDialog )
iProgressDialog->SetTextL( aProgressText );
if( iProgressInfo )
iProgressInfo->SetAndDraw( aProgress );
}
void CLmProgressDialog :: ProcessFinishedL()
{
if( iProgressDialog )
{
iProgressDialog->ProcessFinishedL();
iProgressDialog = NULL;
}
}
void CLmProgressDialog :: DialogDismissedL( TInt aButtonId )
{
iProgressDialog = NULL;
iProgressInfo = NULL;
if( aButtonId == EAknSoftkeyCancel )
iObserver->CancelOperation();
}
Using progress dialog with incrementally execution
Your AppUi class must realize necessary interfaces:
- MProgressDialogObserver,
- MLmOperationHandlerObserver
and contain members:
CLmProgressDialog* iProgressDialog;
CLmOperationHandler* iOperationHandler;
Necessary methods can be implemented as follows:
void CYourAppUi :: ConstructL()
{
...
iProgressDialog = new (ELeave) CLmProgressDialog( this );
...
}
CYourAppUi :: ~CYourAppUi()
{
...
delete iProgressDialog;
iProgressDialog = NULL;
delete iOperationHandler;
iOperationHandler = NULL;
...
}
void CYourAppUi :: CancelOperation()
{
iProgressDialog->ProcessFinishedL();
iOperationHandler->NotifyStop();
}
_LIT( KProgressMess, "Completeness: " );
void CYourAppUi :: OnOperationProgress( TInt aProgress )
{
if( aProgress == 0 )
iProgressDialog->StartProgressNoteL();
else
{
TBuf<32> messWait( KProgressMess );
messWait.AppendNum( aProgress );
messWait.Append( '%' );
if( aProgress < 100 )
iProgressDialog->UpdateProcessL( aProgress, messWait );
else
{
iProgressDialog->UpdateProcessL( 100, messWait );
iProgressDialog->ProcessFinishedL();
}
}
}
_LIT( KErrorMess, "Error ocurred, code is: " );
void CYourAppUi :: OnOperationError( TInt aErrorCode )
{
TBuf<64> messError( KErrorMess );
messError.AppendNum( aErrorCode );
CAknErrorNote* note = new ( ELeave ) CAknErrorNote( ETrue );
note->ExecuteLD( messError );
}
Now you can start incrementally execution:
_LIT( KDbUri, "file://C:eposlm.ldb" );
iOperationHandler = new (ELeave) CLmOpDbCompactHandler( KDbUri, this );
iOperationHandler->ExecuteL();
Related Links:
- Landmarks/web client example using Carbide.c++ and UI designer
- How to use Landmarks API
- How to select and show a landmark
- How to compact local landmark databases
- How to export landmarks from database to file
- How to import landmarks from file to database
- How to obtain and save current location
- Retrieving location information
- How to manage landmark categories


21 Sep
2009
This article demostrates code snippests for how we can use Landmark API and execute landmark operations. Class CLmOperationHandler, Class CLmProgressDialog are very well-expained with their related code. The article is in organized manner with required libraries and capabilities mentioned at the top before presenting the code. The code also contains comments to make it much more understandable for beginners.
This article is specially meant for beginners to study Landmark API.