home *** CD-ROM | disk | FTP | other *** search
- // SearchState.cpp
- //
- // Copyright (c) 1999-2000 Sander van der Wal. All rights reserved.
- //
- // $Id: searchstate.cpp 1.1 2000-09-17 13:18:14+02 svdwal Exp svdwal $
- //
- // $Log: searchstate.cpp $
- // Revision 1.1 2000-09-17 13:18:14+02 svdwal
- // Initial checkin
- //
-
- #include "SearchState.h"
-
- // --o EIKON
- #include <eikfindd.h> // SEdwinFindModel
- #include <eiklabel.h>
- //#include <eikon.rsg>
- #include <eikdialg.hrh>
-
- // Engine
- // --o PDFLib
- #include "PDFDoc.h"
- #include "TextOutputDev.h"
-
- #include "Pdf.hrh"
- #include "Pdf.rsg"
-
- // Profiling
- #include "PROFILE.H"
-
-
- //
- // Global const
- //
- static inline TInt round(double x) { return TInt(x+0.5); };
-
- /////////////////////////////////////////////////////////////////////////////
- //
- // CSearchingDialog
- //
- //////////////////////////////////////////////////////////////////////////////
- class CSearchingDialog: public CEikDialog,
- public MSearchStateObserver
- {
- public:
- CSearchingDialog(CSearchState& iSearchState);
-
- // --0 CEikDialog
- private:
- void PreLayoutDynInitL();
- void PostLayoutDynInitL();
- TBool OkToExitL(TInt /*aButtonId*/);
-
- // --o MSearchStateObserver
- private:
- void NotifyFound();
- void NotifyError(TInt aError);
- void NotifyPage(TInt aPage);
-
- private:
- CSearchState& iSearchState;
- };
-
- CSearchingDialog::CSearchingDialog(CSearchState& aSearchState)
- : iSearchState(aSearchState)
- {
- iSearchState.SetObserver(this);
- }
-
-
- void CSearchingDialog::PreLayoutDynInitL()
- {
- // use MaxPage() to get enough room for the biggest page number
- TBuf<10> buf;
- buf.Num(iSearchState.MaxPage());
- CEikLabel* label=((CEikLabel*)Control(ESearchingDialogPage));
- label->iAlignment=EHRightVCenter;
- label->SetTextL(buf);
- }
-
-
- void CSearchingDialog::PostLayoutDynInitL()
- {
- TBuf<10> buf;
- buf.Num(iSearchState.Page());
- CEikLabel* label=((CEikLabel*)Control(ESearchingDialogPage));
- label->iAlignment=EHLeftVCenter;
- label->SetTextL(buf);
-
- iSearchState.StartSearchingL();
- }
-
-
- TBool CSearchingDialog::OkToExitL(TInt /* aButtonId */ )
- {
- iSearchState.CancelSearch();
- return(ETrue);
- }
-
-
- void CSearchingDialog::NotifyFound()
- {
- TryExitL(EEikBidOk);// this doesn't leave in this case.
- }
-
-
- void CSearchingDialog::NotifyError(TInt anErrorCode)
- {
- if (anErrorCode!=KErrCancel)
- delete(this);
- else
- TryExitL(EEikBidCancel);
- }
-
-
- void CSearchingDialog::NotifyPage(TInt aPage)
- {
- TBuf<10> buf;
- buf.Num(aPage);
- TRAPD(ret, SetLabelL(ESearchingDialogPage, buf));
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- //
- // CSearchState
- //
- //////////////////////////////////////////////////////////////////////////////
- CSearchState::CSearchState(PDFDoc* aDoc, TInt aStartPage, SEdwinFindModel* aFindModel)
- : iState(EDone), iDoc(aDoc), iFindModel(aFindModel), iStartPage(aStartPage)
- {
- iMin.iX = iMin.iY = iMax.iX = iMax.iY = 0;
- iSelection = TRect(0,0,0,0);
-
- // search current page starting at top of page
- iPage = iStartPage;
- iTop = gTrue;
- }
-
-
- void CSearchState::ConstructL()
- {
- // search following pages
- iTextOut = new(ELeave) TextOutputDev();
- iTextOut->ConstructL(0, gFalse /* useEUCJP */, gFalse);
- if (!iTextOut->isOk()) {
- delete iTextOut;
- iTextOut = 0;
- }
- else
- iState = EStart;
- }
-
-
- CSearchState::~CSearchState()
- {
- if (iActivePage) {
- iActivePage->Cancel();
- delete iActivePage;
- }
- delete iTextOut;
- }
-
-
- void CSearchState::SetObserver(MSearchStateObserver* aObserver)
- {
- iObserver = aObserver;
- }
-
-
- TInt CSearchState::MaxPage() const { return iDoc->getNumPages(); }
-
-
- void CSearchState::NotifyPageFinishedL(TInt aError)
- {
- if (aError == KErrNone)
- // reenter the state engine until it has found something
- while (!StepL());
- else if (iObserver)
- iObserver->NotifyError(aError);
- }
-
-
- TBool CSearchState::FindNextL()
- {
- // if result is fast to find, return directly
- // else start a dialog with a cancel button and the active page
-
- iObserver = 0;
- TBool fast = StepL();
- if (!fast) {
- CSearchingDialog* dialog = new(ELeave) CSearchingDialog(*this);
- dialog->ExecuteLD(R_SEARCHING_DIALOG);
- }
- return iFound;
- }
-
-
- void CSearchState::StartSearchingL()
- {
- if (iState != EDone) {
- iActivePage = CActivePage::NewL(10, this);
- StepL();
- }
- else if (iObserver)
- iObserver->NotifyError(KErrCancel);
- return;
- }
-
-
- TBool CSearchState::StepL()
- {
- iFound = EFalse;
- for (;;) {
- switch (iState) {
-
- case EStart: // start searching by rendering the chars on the first page
- iNumSeen = 0;
- iPg = iStartPage;
- iState = ENextPage;
- return EFalse;
-
- case EStartAtSelection: // search current page starting at current selection or top of page
- iXMin1=0;
- iYMin1=0;
- iXMax1=0;
- iYMax1=0;
- if (iSelection.iTl.iX < iSelection.iBr.iX && iSelection.iTl.iY < iSelection.iBr.iY) {
- iMin.iX = iSelection.iBr.iX;
- iMin.iY = (iSelection.iTl.iY + iSelection.iBr.iY) / 2;
- iTop = gFalse;
- }
- else
- iTop = gTrue;
-
- iXMin1 = iMin.iX;
- iYMin1 = iMin.iY;
- if (iTextOut->findText((char*)iFindModel->iText.PtrZ(), iTop, gTrue, &iXMin1, &iYMin1, &iXMax1, &iYMax1,
- (iFindModel->iFlags & EFindCaseSensitive) ? gTrue : gFalse))
- iState = EFound;
- else if (iNumSeen < iDoc->getNumPages()) {
- iTop = gTrue;
- iPg = iPage + 1;
- iState = ENextPage;
- return EFalse;
- }
- else
- iState = ENotFound;
- break;
-
- case ENextPage: // search following pages
- if (iPg > iDoc->getNumPages()) {
- iTop = gTrue;
- iState = EPrevPage;
- iPg = 1;
- }
- else {
- iActivePage->StartRenderingL(iTextOut, iDoc, iPg, 72, 0);
- if (iObserver)
- iObserver->NotifyPage(iPg);
- iNumSeen++;
- iState = EDisplayingNextPage;
- return ETrue;
- }
- break;
-
- case EDisplayingNextPage:
- if (iTextOut->findText((char*)iFindModel->iText.PtrZ(), gTrue, gTrue, &iXMin1, &iYMin1, &iXMax1, &iYMax1,
- (iFindModel->iFlags & EFindCaseSensitive)?gTrue:gFalse))
- iState = EFoundPage;
- else {
- iPg++;
- iState = ENextPage;
- return EFalse;
- }
- break;
-
- case EPrevPage: // search previous pages
- if (iPg >= iStartPage)
- iState = EStopAtSelection;
- else {
- iActivePage->StartRenderingL(iTextOut, iDoc, iPg, 72, 0);
- if (iObserver)
- iObserver->NotifyPage(iPg);
- iNumSeen++;
- iState = EDisplayingPrevPage;
- return ETrue;
- }
- break;
-
- case EDisplayingPrevPage:
- if (iTextOut->findText((char*)iFindModel->iText.PtrZ(), gTrue, gTrue, &iXMin1, &iYMin1, &iXMax1, &iYMax1,
- (iFindModel->iFlags & EFindCaseSensitive)?gTrue:gFalse))
- iState = EFoundPage;
- else {
- iPg++;
- iState = EPrevPage;
- return EFalse;
- }
- break;
-
- case EStopAtSelection: // search current page ending at current selection
- if (iSelection.iTl.iX < iSelection.iBr.iX && iSelection.iTl.iY < iSelection.iBr.iY) {
- iMax.iX = iSelection.iTl.iX;
- iMax.iY = (iSelection.iTl.iY + iSelection.iBr.iY) / 2;
- if (iTextOut->findText((char*)iFindModel->iText.PtrZ(), gTrue, gFalse, &iXMin1, &iYMin1, &iXMax1, &iYMax1,
- (iFindModel->iFlags & EFindCaseSensitive)?gTrue:gFalse))
- iState = EFound;
- else
- iState = ENotFound;
- }
- else
- iState = ENotFound;
- break;
-
- case ENotFound:
- CancelSearch();
- delete iTextOut;
- iTextOut = 0;
- iState = EDone;
- if (iObserver)
- iObserver->NotifyError(KErrCancel);
- return ETrue;
-
- case EFoundPage: // found on a different page, which becomes the current page
- iPage = iPg;
- iState = EFound;
- break;
-
- case EFound: // found: change the selection
- CancelSearch();
- iFound = ETrue;
- iSelection = TRect(round(iXMin1), round(iYMin1), round(iXMax1), round(iYMax1));
- iState = EStartAtSelection;
- if (iObserver)
- iObserver->NotifyFound();
- return ETrue;
-
- case EDone:
- return ETrue;
-
- } // switch
- } // for
- }
-
-
- void CSearchState::CancelSearch()
- {
- if (iActivePage) {
- iActivePage->Cancel();
- delete iActivePage;
- iActivePage = 0;
- }
- }
-
- TRect CSearchState::Selection() const
- {
- TReal selXMin, selYMin;
- iTextOut->cvtDevToUser(iSelection.iTl.iX, iSelection.iTl.iY, &selXMin, &selYMin);
-
- TReal selXMax, selYMax;
- iTextOut->cvtDevToUser(iSelection.iBr.iX, iSelection.iBr.iY, &selXMax, &selYMax);
-
- TRect res(round(KTwipsPerPoint*selXMin), round(KTwipsPerPoint*selYMin),
- round(KTwipsPerPoint*selXMax), round(KTwipsPerPoint*selYMax));
- res.Normalize();
-
- return res;
- }