mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
git-svn-id: https://zxing.googlecode.com/svn/trunk@1378 59b500cc-1b3d-0410-9834-0bbf25fbcc57
583 lines
14 KiB
C++
583 lines
14 KiB
C++
/*
|
|
* Copyright (c) 2009 Nokia Corporation.
|
|
*/
|
|
|
|
// INCLUDE FILES
|
|
#include <coemain.h>
|
|
#include <eikon.hrh>
|
|
#include <aknutils.h>
|
|
#include <pathinfo.h>
|
|
#include <f32file.h>
|
|
#include <BAUTILS.H>
|
|
#include "ZXingBarcodeReaderAppView.h"
|
|
#include "ZXingBarcodeReaderAppUi.h"
|
|
|
|
|
|
|
|
// ============================ MEMBER FUNCTIONS ===============================
|
|
|
|
CZXingBarcodeReaderAppView* CZXingBarcodeReaderAppView::NewL (const TRect& aRect )
|
|
{
|
|
CZXingBarcodeReaderAppView* self = CZXingBarcodeReaderAppView::NewLC (aRect );
|
|
CleanupStack::Pop (self );
|
|
return self;
|
|
}
|
|
|
|
CZXingBarcodeReaderAppView* CZXingBarcodeReaderAppView::NewLC (const TRect& aRect )
|
|
{
|
|
CZXingBarcodeReaderAppView* self = new (ELeave) CZXingBarcodeReaderAppView;
|
|
CleanupStack::PushL (self );
|
|
self->ConstructL (aRect );
|
|
return self;
|
|
}
|
|
|
|
void CZXingBarcodeReaderAppView::ConstructL (const TRect& aRect )
|
|
{
|
|
// Create a window for this application view
|
|
CreateWindowL ();
|
|
|
|
iTitleFont = AknLayoutUtils::FontFromId(EAknLogicalFontPrimarySmallFont);
|
|
|
|
iAppUi = static_cast<CZXingBarcodeReaderAppUi*>(iEikonEnv->EikAppUi());
|
|
|
|
// Set the windows size
|
|
SetRect (aRect );
|
|
|
|
//Start decoder timer.
|
|
StartTimer();
|
|
|
|
// Activate the window, which makes it ready to be drawn
|
|
ActivateL ();
|
|
}
|
|
|
|
CZXingBarcodeReaderAppView::CZXingBarcodeReaderAppView () : iPeriodic(NULL)
|
|
{
|
|
}
|
|
|
|
CZXingBarcodeReaderAppView::~CZXingBarcodeReaderAppView ()
|
|
{
|
|
if (iCameraWrapper)
|
|
{
|
|
iCameraWrapper->ReleaseAndPowerOff();
|
|
}
|
|
delete iCameraWrapper;
|
|
delete iData;
|
|
|
|
ReleaseBackBuffer();
|
|
}
|
|
|
|
TKeyResponse CZXingBarcodeReaderAppView::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
|
|
{
|
|
switch ( aKeyEvent.iCode )
|
|
{
|
|
case EKeyOK:
|
|
case EStdKeyDevice3:
|
|
{
|
|
// Capture picture
|
|
iCameraShutterFocusing = EFalse;
|
|
StartFocusing();
|
|
return EKeyWasConsumed;
|
|
}
|
|
case EKeyUpArrow:
|
|
{
|
|
if (iCameraWrapper->State() == CCameraEngine::EEngineViewFinding)
|
|
{
|
|
iCameraWrapper->AdjustDigitalZoom(ETrue);
|
|
}
|
|
return EKeyWasConsumed;
|
|
}
|
|
case EKeyDownArrow:
|
|
{
|
|
if (iCameraWrapper->State() == CCameraEngine::EEngineViewFinding)
|
|
{
|
|
iCameraWrapper->AdjustDigitalZoom(EFalse);
|
|
|
|
}
|
|
return EKeyWasConsumed;
|
|
}
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
#ifdef ENABLE_CAMERA_SHUTTER
|
|
// Camera shutter autofocus
|
|
switch ( aKeyEvent.iScanCode )
|
|
{
|
|
case KStdKeyCameraFocus:
|
|
case KStdKeyCameraFocus2:
|
|
{
|
|
// Camera shutter autofocus
|
|
if (aType == EEventKeyDown)
|
|
{
|
|
if (!iAppUi->IsBackCBA())
|
|
{
|
|
iCameraShutterFocusing = ETrue;
|
|
StartFocusing();
|
|
}
|
|
return EKeyWasConsumed;
|
|
}
|
|
else if (aType == EEventKeyUp)
|
|
{
|
|
// Camera state can be EEngineIdle or EEngineFocusing
|
|
if (!iAppUi->IsBackCBA() && (iCameraWrapper->State() == CCameraEngine::EEngineFocusing ||
|
|
iCameraWrapper->State() == CCameraEngine::EEngineIdle))
|
|
{
|
|
iCameraWrapper->FocusCancel();
|
|
CancelCapturedPicture();
|
|
iAppUi->UseOptionsExitCbaL();
|
|
}
|
|
return EKeyWasConsumed;
|
|
}
|
|
}
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
};
|
|
#endif
|
|
|
|
return EKeyWasNotConsumed;
|
|
}
|
|
|
|
void CZXingBarcodeReaderAppView::CancelCapturedPicture(TBool aCleanTexts)
|
|
{
|
|
if (iCameraWrapper && iCameraWrapper->State() == CCameraEngine::EEngineIdle)
|
|
{
|
|
TRAPD(err,iCameraWrapper->StartViewFinderL(iViewFinderSize));
|
|
if (aCleanTexts)
|
|
{
|
|
if (err)
|
|
{
|
|
SetError(_L("Camera viewfinder error %d"), err);
|
|
}
|
|
else
|
|
{
|
|
SetTitle(_L("Camera viewfinder"));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CZXingBarcodeReaderAppView::Draw(const TRect& /*aRect*/) const
|
|
{
|
|
CWindowGc& gc = SystemGc ();
|
|
|
|
// Draw backbuffer that has camera picture
|
|
gc.BitBlt(TPoint(0, 0), iBackBuffer);
|
|
|
|
// Draw texts
|
|
DrawTexts(gc);
|
|
|
|
// Focus rect
|
|
if (iCameraWrapper && iCameraWrapper->State() == CCameraEngine::EEngineFocusing)
|
|
{
|
|
gc.SetPenColor(KRgbWhite);
|
|
gc.DrawRect(iFocusRect);
|
|
}
|
|
}
|
|
|
|
void CZXingBarcodeReaderAppView::DrawTexts(CWindowGc& gc) const
|
|
{
|
|
if (iTitle.Length()>0)
|
|
{
|
|
TRect rect(Rect());
|
|
gc.SetPenColor(KRgbWhite);
|
|
gc.UseFont(iTitleFont);
|
|
gc.DrawText(iTitle, rect, rect.Height()/10, CGraphicsContext::ECenter );
|
|
gc.DiscardFont();
|
|
}
|
|
}
|
|
|
|
void CZXingBarcodeReaderAppView::SizeChanged()
|
|
{
|
|
// Create camera wrapper class here because
|
|
// whole camera wrapper and all handles have to reset
|
|
// while orientatio of the application changes.
|
|
if (iCameraWrapper)
|
|
{
|
|
// Power off camera if it is on
|
|
iCameraWrapper->StopViewFinder();
|
|
iCameraWrapper->ReleaseAndPowerOff();
|
|
delete iCameraWrapper; iCameraWrapper = NULL;
|
|
}
|
|
TInt camErr(KErrNotSupported);
|
|
if(CCameraEngine::CamerasAvailable() > 0)
|
|
{
|
|
TRAP(camErr, iCameraWrapper = CCameraEngine::NewL(0,0,this));
|
|
}
|
|
|
|
// iViewFinderSize is picture size for viewfinder.
|
|
// iCaptureSize is picture size for capturing picture.
|
|
// We want fill whole screen
|
|
if (Rect().Size().iWidth > Rect().Size().iHeight)
|
|
{
|
|
iViewFinderSize = TSize(Rect().Size().iWidth,Rect().Size().iWidth);
|
|
iCaptureSize = TSize(1280,960); // Captured picture size
|
|
}
|
|
else
|
|
{
|
|
iViewFinderSize = TSize(Rect().Size().iHeight,Rect().Size().iHeight);
|
|
iCaptureSize = TSize(1280,960); // Captured picture size
|
|
}
|
|
|
|
// Focus rectangle
|
|
iFocusRect = Rect();
|
|
iFocusRect.Shrink(Rect().Size().iWidth/4, Rect().Size().iHeight/4);
|
|
|
|
// Create back buffer where recieved camera pictures are copied
|
|
ReleaseBackBuffer();
|
|
CreateBackBufferL();
|
|
|
|
// Power on camera, start viewfinder when MceoCameraReady() received
|
|
if(camErr == KErrNone)
|
|
{
|
|
iCameraWrapper->ReserveAndPowerOn();
|
|
SetTitle(_L("Camera power on"));
|
|
}
|
|
else
|
|
{
|
|
SetTitle(_L("no camera found"));
|
|
}
|
|
}
|
|
|
|
void CZXingBarcodeReaderAppView::HandlePointerEventL (
|
|
const TPointerEvent& aPointerEvent )
|
|
{
|
|
if (aPointerEvent.iType == TPointerEvent::EButton1Down)
|
|
{
|
|
// When pointing to screen camera capture picture
|
|
if (!iAppUi->IsBackCBA() &&
|
|
iCameraWrapper && iCameraWrapper->State() == CCameraEngine::EEngineViewFinding)
|
|
{
|
|
iCameraShutterFocusing = EFalse;
|
|
StartFocusing();
|
|
}
|
|
// After captureing, when pointing again to screen camera
|
|
// start viewfinder again
|
|
else if (!iAppUi->IsBackCBA() &&
|
|
iCameraWrapper && iCameraWrapper->State() == CCameraEngine::EEngineIdle)
|
|
{
|
|
CancelCapturedPicture();
|
|
iAppUi->UseOptionsExitCbaL();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CZXingBarcodeReaderAppView::SetTitle(const TDesC& aTitle)
|
|
{
|
|
iTitle.Copy(aTitle);
|
|
DrawNow();
|
|
}
|
|
|
|
void CZXingBarcodeReaderAppView::SetError( const TDesC& aMsg, TInt aVal )
|
|
{
|
|
iTitle.Format(aMsg, aVal);
|
|
DrawNow();
|
|
}
|
|
|
|
void CZXingBarcodeReaderAppView::SetError( const TDesC& aMsg, TInt aVal1, TInt aVal2 )
|
|
{
|
|
iTitle.Format(aMsg, aVal1, aVal2);
|
|
DrawNow();
|
|
}
|
|
|
|
void CZXingBarcodeReaderAppView::CreateBackBufferL()
|
|
{
|
|
// create back buffer bitmap
|
|
iBackBuffer = new (ELeave) CFbsBitmap;
|
|
|
|
User::LeaveIfError( iBackBuffer->Create(Size(),EColor16M));
|
|
|
|
// create back buffer graphics context
|
|
iBackBufferDevice = CFbsBitmapDevice::NewL(iBackBuffer);
|
|
User::LeaveIfError(iBackBufferDevice->CreateContext(iBackBufferContext));
|
|
iBackBufferContext->SetPenStyle(CGraphicsContext::ESolidPen);
|
|
|
|
iBackBufferContext->SetBrushColor(KRgbBlack);
|
|
iBackBufferContext->Clear();
|
|
}
|
|
|
|
void CZXingBarcodeReaderAppView::ReleaseBackBuffer()
|
|
{
|
|
if (iBackBufferContext)
|
|
{
|
|
delete iBackBufferContext;
|
|
iBackBufferContext = NULL;
|
|
}
|
|
if (iBackBufferDevice)
|
|
{
|
|
delete iBackBufferDevice;
|
|
iBackBufferDevice = NULL;
|
|
}
|
|
if (iBackBuffer)
|
|
{
|
|
delete iBackBuffer;
|
|
iBackBuffer = NULL;
|
|
}
|
|
}
|
|
|
|
void CZXingBarcodeReaderAppView::MceoCameraReady()
|
|
{
|
|
iAppUi->UseOptionsExitCbaL();
|
|
|
|
if (iCameraWrapper->State() == CCameraEngine::EEngineIdle)
|
|
{
|
|
// Prepare camera
|
|
TRAPD(err,iCameraWrapper->PrepareL(iCaptureSize));
|
|
if (err)
|
|
{
|
|
SetError(_L("Camera prepare error %d"), err);
|
|
return;
|
|
}
|
|
|
|
// Start viewfinder. Viewfinder pictures starts coming into MceoViewFinderFrameReady();
|
|
TRAPD(err2,iCameraWrapper->StartViewFinderL(iViewFinderSize));
|
|
if (err2)
|
|
{
|
|
SetError(_L("Camera start viewfinder error %d"), err2);
|
|
return;
|
|
}
|
|
|
|
SetTitle(_L("Camera viewfinder"));
|
|
}
|
|
}
|
|
|
|
void CZXingBarcodeReaderAppView::Capture()
|
|
{
|
|
// This method is called when picture is focused with camera shutter and pressed whole down
|
|
// as taking a new picture
|
|
#ifdef ENABLE_CAMERA_SHUTTER
|
|
if (iCameraWrapper && !iAppUi->IsBackCBA())
|
|
{
|
|
// No focus supported
|
|
SetTitle(_L("Capturing picture"));
|
|
iCameraWrapper->StopViewFinder();
|
|
TRAPD(err,iCameraWrapper->CaptureL());
|
|
if (err)
|
|
{
|
|
SetError(_L("Camera capture error %d"), err);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void CZXingBarcodeReaderAppView::StartFocusing()
|
|
{
|
|
if (iCameraWrapper && iCameraWrapper->State() == CCameraEngine::EEngineViewFinding)
|
|
{
|
|
if (!iCameraWrapper->IsAutoFocusSupported())
|
|
{
|
|
// No focus supported
|
|
SetTitle(_L("Capturing picture"));
|
|
iCameraWrapper->StopViewFinder();
|
|
TRAPD(err,iCameraWrapper->CaptureL());
|
|
if (err)
|
|
{
|
|
SetError(_L("Camera capture error %d"), err);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Focusing supported
|
|
iCameraWrapper->StartFocusL();
|
|
SetTitle(_L("Autofocusing..."));
|
|
}
|
|
}
|
|
}
|
|
|
|
void CZXingBarcodeReaderAppView::MceoFocusComplete()
|
|
{
|
|
// CameraEngine state is EEngineIdle
|
|
SetTitle(_L("Focused"));
|
|
|
|
if (iCameraShutterFocusing)
|
|
{
|
|
// Leave as focused. User must press whole camera shutter down for capturing
|
|
// then CZXingBarcodeReaderAppView::Capture() is called
|
|
}
|
|
else
|
|
{
|
|
// Capture picture after it has focused
|
|
iCameraWrapper->StopViewFinder();
|
|
TRAPD(err,iCameraWrapper->CaptureL());
|
|
if (err)
|
|
{
|
|
SetError(_L("Camera capture error %d"), err);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CZXingBarcodeReaderAppView::MceoCapturedDataReady( TDesC8* aData )
|
|
{
|
|
SetTitle(_L("Saving picture..."));
|
|
|
|
delete iData; iData = NULL;
|
|
iData = aData->Alloc();
|
|
|
|
if (iCameraWrapper)
|
|
iCameraWrapper->ReleaseImageBuffer();
|
|
|
|
TRAP_IGNORE(iAppUi->UseOptionsBackCbaL());
|
|
|
|
StorePicture(iData);
|
|
}
|
|
|
|
void CZXingBarcodeReaderAppView::StorePicture( TDesC8* aData )
|
|
{
|
|
// Create path for filename
|
|
TFileName path = PathInfo::PhoneMemoryRootPath();
|
|
path.Append(PathInfo::ImagesPath());
|
|
|
|
// Ensure that path exists
|
|
BaflUtils::EnsurePathExistsL(iEikonEnv->FsSession(),path);
|
|
|
|
// Get next free filename for the image
|
|
TFileName fileToSave;
|
|
TBool fileExists = ETrue;
|
|
for (TInt i=1 ; i<100 ; i++)
|
|
{
|
|
fileToSave.Copy(path);
|
|
fileToSave.Append(_L("cw_image_"));
|
|
fileToSave.AppendNum(i);
|
|
fileToSave.Append(_L(".jpg"));
|
|
fileExists = BaflUtils::FileExists(iEikonEnv->FsSession(),fileToSave);
|
|
if (!fileExists)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Save file
|
|
if (!fileExists)
|
|
{
|
|
RFile file;
|
|
TInt err = file.Create(iEikonEnv->FsSession(),fileToSave,EFileWrite);
|
|
if (!err)
|
|
{
|
|
file.Write(*aData);
|
|
file.Close();
|
|
SetTitle(fileToSave);
|
|
}
|
|
else
|
|
{
|
|
SetError(_L("File saving error %d"),err);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetTitle(_L("File not saved, delete old pictures!"));
|
|
}
|
|
}
|
|
|
|
|
|
void CZXingBarcodeReaderAppView::MceoCapturedBitmapReady( CFbsBitmap* aBitmap )
|
|
{
|
|
if (iBackBufferContext)
|
|
{
|
|
TSize bmpSizeInPixels = aBitmap->SizeInPixels();
|
|
TInt xDelta = (Rect().Width() - bmpSizeInPixels.iWidth) / 2;
|
|
TInt yDelta = (Rect().Height() - bmpSizeInPixels.iHeight) / 2;
|
|
TPoint pos( xDelta, yDelta );
|
|
|
|
// Copy received viewfinder picture to back buffer
|
|
iBackBufferContext->BitBlt( pos, aBitmap, TRect( TPoint( 0, 0 ), bmpSizeInPixels ));
|
|
|
|
// Update backbuffer into screen
|
|
SetTitle(_L("New picture"));
|
|
}
|
|
if (iCameraWrapper)
|
|
iCameraWrapper->ReleaseImageBuffer();
|
|
}
|
|
|
|
void CZXingBarcodeReaderAppView::MceoViewFinderFrameReady( CFbsBitmap& aFrame )
|
|
{
|
|
if (iBackBufferContext)
|
|
{
|
|
TSize bmpSizeInPixels = aFrame.SizeInPixels();
|
|
TInt xDelta = (Rect().Width() - bmpSizeInPixels.iWidth) / 2;
|
|
TInt yDelta = (Rect().Height() - bmpSizeInPixels.iHeight) / 2;
|
|
TPoint pos( xDelta, yDelta );
|
|
|
|
// Copy received viewfinder picture to back buffer
|
|
iBackBufferContext->BitBlt( pos, &aFrame, TRect( TPoint( 0, 0 ), bmpSizeInPixels ));
|
|
|
|
// Update backbuffer into screen
|
|
DrawNow();
|
|
}
|
|
if (iCameraWrapper)
|
|
iCameraWrapper->ReleaseViewFinderBuffer();
|
|
}
|
|
|
|
void CZXingBarcodeReaderAppView::MceoHandleError( TCameraEngineError aErrorType, TInt aError )
|
|
{
|
|
// NOTE: CameraEngine state seems to go into CCameraEngine::EEngineIdle state
|
|
|
|
if (aErrorType == EErrReserve)
|
|
{
|
|
return; //-18 comes on application startup, but everything works ok
|
|
}
|
|
|
|
switch (aErrorType)
|
|
{
|
|
case EErrReserve:
|
|
{
|
|
SetError(_L("Camera reserved error (%d)"), aError);
|
|
break;
|
|
}
|
|
case EErrPowerOn:
|
|
{
|
|
SetError(_L("Camera power on error (%d)"), aError);
|
|
break;
|
|
}
|
|
case EErrViewFinderReady:
|
|
{
|
|
SetError(_L("Camera viewfinder error (%d)"), aError);
|
|
break;
|
|
}
|
|
case EErrImageReady:
|
|
{
|
|
SetError(_L("Camera image ready error (%d)"), aError);
|
|
break;
|
|
}
|
|
case EErrAutoFocusInit:
|
|
case EErrAutoFocusMode:
|
|
case EErrAutoFocusArea:
|
|
case EErrAutoFocusRange:
|
|
case EErrAutoFocusType:
|
|
case EErrOptimisedFocusComplete:
|
|
{
|
|
//SetTitle(_L("Try focusing again"));
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
SetError(_L("Error %d (%d)"), aErrorType, aError);
|
|
break;
|
|
}
|
|
};
|
|
|
|
// Try handle error
|
|
CancelCapturedPicture(EFalse);
|
|
iAppUi->UseOptionsExitCbaL();
|
|
}
|
|
|
|
void CZXingBarcodeReaderAppView::MceoHandleOtherEvent( const TECAMEvent& /*aEvent*/ )
|
|
{
|
|
}
|
|
|
|
|
|
void CZXingBarcodeReaderAppView::StopTimer()
|
|
{
|
|
if(iPeriodic)
|
|
iPeriodic->Cancel();
|
|
}
|
|
|
|
|
|
|
|
|
|
// End of File
|