--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/DirectPrint/DirectPrintApp/engine/src/directprintengine.cpp Tue May 11 14:10:02 2010 +0800
@@ -0,0 +1,649 @@
+/*
+* Copyright (c) 2010 Kanrikogaku Kenkyusho, Ltd.
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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:
+* Kanrikogaku Kenkyusho, Ltd. - Initial contribution
+*
+* Contributors:
+*
+* Description:
+* {Description of the file}
+*
+*/
+
+#include <pdrport.h> // CFilePrinterPort
+#include <TXTETEXT.H> // CEditableText
+#include <TXTRICH.H> // CRichText
+#include <FLDBLTIN.H> // CPageNumField
+#include <flddef.h> // KPageNumberFieldUid, KNumPagesFieldUid
+#include <stringloader.h> // StringLoader
+#include <xmlengdocument.h> // RXmlEngDocument
+#include <xmlengelement.h> // TXmlEngElement
+#include <xmlengattr.h> // TXmlEngAttr
+#include <xmlengnodelist.h> // RXmlEngNodeList
+#include <bautils.h> // BaflUtils
+#include <eikenv.h> // CEikonEnv
+
+#include "clog.h"
+#include <directprintapp.rsg>
+#include "directprintengine.h"
+#include "directprintband.h"
+#include "directprintengineobserver.h"
+#include "directprintmodel.h"
+#include "directprintbanduid.h"
+
+//! Default Page spec in Twips
+#define KDefaultPageSpecInTwips TPageSpec(TPageSpec::EPortrait,TSize(11906,16838))
+
+CDirectPrintEngine::CDirectPrintEngine(CDirectPrintModel& aModel)
+ : iModel(aModel)
+ {
+ }
+
+CDirectPrintEngine::~CDirectPrintEngine()
+ {
+ if (iProgressDialog)
+ {
+ TRAP_IGNORE(iProgressDialog->ProcessFinishedL());
+ delete iProgressDialog;
+ iProgressDialog = NULL;
+ }
+
+ if (iPrintBand)
+ {
+ delete iPrintBand;
+ iPrintBand = NULL;
+ }
+
+ iPrintSetup->FreeModelList();
+ delete iPrintSetup;
+ delete iProgressMessage;
+ iFs.Close();
+ }
+
+CDirectPrintEngine* CDirectPrintEngine::NewL(CDirectPrintModel& aModel)
+ {
+ CDirectPrintEngine* self = CDirectPrintEngine::NewLC(aModel);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CDirectPrintEngine* CDirectPrintEngine::NewLC(CDirectPrintModel& aModel)
+ {
+ CDirectPrintEngine* self = new(ELeave) CDirectPrintEngine(aModel);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+void CDirectPrintEngine::ConstructL()
+ {
+ LOG("CDirectPrintEngine::ConstructL BEGIN");
+ iFs.Connect();
+
+ iPrintSetup = CPrintSetup::NewL();
+ iPrintSetup->AddPrinterDriverDirL(KDefaultPrinterDriverPath);
+ iModelList = iPrintSetup->ModelNameListL(iFs);
+
+#ifdef _DEBUG
+ LOG1("ModelCount=[%d]", ModelCount());
+ for (TInt i=0; i < ModelCount(); i++)
+ {
+ TPrinterModelEntry entry = (*iModelList)[i];
+ RDebug::Print(_L("[%d][%S][%d] "), i, &(entry.iModelName), entry.iRequiresPrinterPort);
+ LOG1("ModelName=[%S]", &(entry.iModelName));
+ }
+#endif
+ // read progress message
+ iProgressMessage = StringLoader::LoadL( R_DIRECTPRINT_MSG_PRINTING_PROGRESS );
+
+ LOG("CDirectPrintEngine::ConstructL END");
+ }
+
+void CDirectPrintEngine::SetObserver(MDirectPrintEngineObserver* aObserver)
+ {
+ iObserver = aObserver;
+ }
+
+/**
+ Override of base class virtual.
+ Notifies that a print or print preview operation is about to begin.
+ */
+void CDirectPrintEngine::NotifyPrintStarted(TPrintParameters /*aPrintParams*/)
+ {
+ iPageCounter = 0;
+ TRAPD(err, StartPrintProgressNoteL());
+ iLastError = err;
+ }
+
+/**
+ Override of base class virtual.\n
+ Notifies that a band is about to be printed used to display print progress information,
+ including the current page number.\n
+ It is called immediately before each band is printed.\n
+ */
+void CDirectPrintEngine::NotifyBandPrinted(TInt /*aPercent*/, TInt aCurrentPageNum, TInt /*aCurrentCopyNum*/)
+ {
+ if (iPageCounter==0)
+ {
+ // start print
+ }
+ if (iPageCounter<aCurrentPageNum)
+ {
+ // next page
+ iPageCounter = aCurrentPageNum;
+ TRAPD(err, UpdatePrintProgressNoteL(iPageCounter));
+ iLastError = err;
+ }
+ }
+
+/**
+ Override of base class virtual.\n
+ Notifies that the print or print preview operation has completed.\n
+ used to display information about how the operation completed,
+ for example any errors that occurred.\n
+ */
+void CDirectPrintEngine::NotifyPrintEnded(TInt aErr)
+ {
+ CActiveScheduler::Stop();
+ TInt err = KErrNone;
+
+ if (aErr == KErrNone)
+ {
+ if (iObserver)
+ {
+ TRAP(err, iObserver->HandlePrintEventL(MDirectPrintEngineObserver::EDirectPrintEngineEventFinishCreatePrintData, 0, KNullDesC));
+ }
+ }
+ else
+ {
+ switch (aErr)
+ {
+ case KErrCancel:
+ if (iObserver)
+ {
+ TRAP(err, iObserver->HandlePrintEventL(MDirectPrintEngineObserver::EDirectPrintEngineEventCancelCreatePrintData, aErr, KNullDesC));
+ }
+ break;
+ default:
+ if (iObserver)
+ {
+ TRAP(err, iObserver->HandlePrintEventL(MDirectPrintEngineObserver::EDirectPrintEngineEventErrorCreatePrintData, aErr, KNullDesC));
+ }
+ break;
+ }
+ }
+
+ TRAP(err, EndPrintProgressNoteL());
+ }
+
+/**
+ Override of base class virtual.\n
+ Returns the number of pages in the current document.\n
+ @return - TInt (Number of pages).\n
+ */
+TInt CDirectPrintEngine::UpdateFieldNumPages()const
+ {
+ return iMaxPageNum;
+ }
+
+
+void CDirectPrintEngine::PrintL()
+ {
+
+ // set the total page
+ iMaxPageNum = 1;
+ iPrintSetup->Header()->SetNumPagesInfo(*this);
+
+ TInt modelNum = iModelList->UidToNum(ModelUid(iModelIndex));
+ iPrintSetup->CreatePrinterDeviceL(modelNum);
+
+ // create a port if necessary
+ CPrinterPort* port=NULL;
+ if ((*iModelList)[modelNum].iRequiresPrinterPort)
+ {
+#ifdef __WINSCW__
+ port = CFilePrinterPort::NewL(_L("c:\\fpr.pcl"));
+#else
+// port = CFilePrinterPort::NewL(_L("e:\\fpr.pcl"));
+ port = CFilePrinterPort::NewL(_L("c:\\fpr.pcl"));
+#endif
+ }
+
+ iPrintSetup->PrinterDevice()->SelectPageSpecInTwips(KDefaultPageSpecInTwips);
+ iPrintSetup->iPageMarginsInTwips.iHeaderOffset = 720;
+ iPrintSetup->iPageMarginsInTwips.iFooterOffset = 0;
+ iPrintSetup->iPageMarginsInTwips.iMargins.iLeft = 1440; // 1 inch
+ iPrintSetup->iPageMarginsInTwips.iMargins.iRight = 1440;
+ iPrintSetup->iPageMarginsInTwips.iMargins.iTop = 1440;
+ iPrintSetup->iPageMarginsInTwips.iMargins.iBottom = 1440;
+
+ if (iObserver)
+ {
+ iObserver->HandlePrintEventL(MDirectPrintEngineObserver::EDirectPrintEngineEventStartCreatePrintData, 0, KNullDesC);
+ }
+
+
+ TRAPD(err, DoPrintL(port));
+ if (err == KErrNone)
+ {
+ CActiveScheduler::Start(); // stopped by killing it - subtle...
+ }
+ else
+ {
+ if (iObserver)
+ {
+ iObserver->HandlePrintEventL(MDirectPrintEngineObserver::EDirectPrintEngineEventErrorCreatePrintData, err, KNullDesC);
+ }
+ }
+
+// if (iPrintBand)
+// {
+// delete iPrintBand;
+// iPrintBand = NULL;
+// }
+ }
+
+void CDirectPrintEngine::DoPrintL(CPrinterPort* aPort)
+ {
+ // create a header
+ iPrintSetup->Header()->CreateTextL();
+ TBuf<40> buf(_L("This is the header on page out of "));
+ buf.Append(CEditableText::EParagraphDelimiter);
+ iPrintSetup->Header()->Text()->InsertL(0,buf);
+ CTextField* pNumberfield=iPrintSetup->Header()->Text()->NewTextFieldL(KPageNumberFieldUid);
+ iPrintSetup->Header()->Text()->InsertFieldL(27,pNumberfield,KPageNumberFieldUid);
+ CNumPagesField* numPagesField=(CNumPagesField*)iPrintSetup->Header()->Text()->NewTextFieldL(KNumPagesFieldUid);
+ iPrintSetup->Header()->Text()->InsertFieldL(35,numPagesField,KNumPagesFieldUid);
+ iPrintSetup->Header()->Text()->UpdateFieldL(27);
+ iPrintSetup->Header()->Text()->UpdateFieldL(35);
+ iPrintSetup->Header()->SetFirstPageToPrintTo(1); // no header on first 3 pages
+
+ iPrintSetup->Footer()->CreateTextL();
+ TBuf<40> buf2(_L("This is the footer on page "));
+ buf2.Append(CEditableText::EParagraphDelimiter);
+ iPrintSetup->Footer()->Text()->InsertL(0,buf2);
+ CTextField* pNumberfield2=iPrintSetup->Footer()->Text()->NewTextFieldL(KPageNumberFieldUid);
+ iPrintSetup->Footer()->Text()->InsertFieldL(27,pNumberfield2,KPageNumberFieldUid);
+ iPrintSetup->Footer()->Text()->UpdateFieldL(27);
+
+ // start print to file
+ iPrintSetup->iNumOfFirstPage = 1;
+ TPrintParameters params;
+ params.iFirstPage = 1; // don't print the first page at all, ie print page no's 3-6
+ params.iLastPage = 1;
+ params.iNumCopies = 1;
+ TPageSpec spec;
+ spec.iPortraitPageSize = KA4PaperSizeInTwips;
+ spec.iOrientation = TPageSpec::EPortrait;
+ iPrintSetup->PrinterDevice()->SelectPageSpecInTwips(spec);
+
+ //===========================
+ // start printing
+ //===========================
+ iPrintSetup->StartPrintL(params, *(PageRegionPrinter()), aPort, this);
+
+ }
+
+
+TInt CDirectPrintEngine::ModelCount()
+ {
+ return iModelList->ModelCount();
+ }
+
+void CDirectPrintEngine::ModelName(TInt aIndex, TDes& aDes)
+ {
+ TPtrC name((*iModelList)[aIndex].iModelName);
+ if (name.Length() <= aDes.MaxLength())
+ {
+ aDes.Copy(name);
+ }
+ }
+
+TUid CDirectPrintEngine::ModelUid(TInt aIndex)
+ {
+ return (*iModelList)[aIndex].iUid;
+ }
+
+void CDirectPrintEngine::SetUseModel(TInt aIndex)
+ {
+ iModelIndex = aIndex;
+ }
+
+void CDirectPrintEngine::StartPrintProgressNoteL()
+ {
+ // Delete possible previous CAknProgressDialog.
+ delete iProgressDialog;
+ iProgressDialog = NULL;
+
+ // Create new CAknProgressDialog.
+ iProgressDialog = new ( ELeave ) CAknProgressDialog( reinterpret_cast
+ <CEikDialog**>
+ ( &iProgressDialog ) );
+
+ iProgressDialog->SetCallback( this );
+ iProgressDialog->PrepareLC( R_DIRECTPRINT_PRINT_PROGRESS_NOTE );
+ iProgressInfo = iProgressDialog->GetProgressInfoL();
+ iProgressInfo->SetFinalValue( iMaxPageNum );
+
+ TBuf<32> msg;
+ msg.AppendFormat(*iProgressMessage, iPageCounter, iMaxPageNum);
+ iProgressDialog->SetTextL(msg);
+ iProgressDialog->RunLD();
+ }
+
+void CDirectPrintEngine::EndPrintProgressNoteL()
+ {
+ if (iProgressDialog)
+ {
+ iProgressDialog->ProcessFinishedL();
+ delete iProgressDialog;
+ iProgressDialog = NULL;
+ }
+ }
+
+void CDirectPrintEngine::UpdatePrintProgressNoteL(TInt aPage)
+ {
+ if (iProgressInfo)
+ {
+ TBuf<32> msg;
+ msg.AppendFormat(*iProgressMessage, aPage, iMaxPageNum);
+ iProgressDialog->SetTextL(msg);
+ iProgressInfo->SetAndDraw(aPage);
+ }
+ }
+
+void CDirectPrintEngine::DialogDismissedL( TInt /*aButtonId*/ )
+ {
+ if (iPrintSetup)
+ {
+ iPrintSetup->EndPrint();
+ }
+ }
+
+void CDirectPrintEngine::StartPrintPreviewL()
+ {
+ // Clear previous object
+ EndPrintPreview();
+
+ // set the total page
+ iMaxPageNum = 1;
+ iPrintSetup->Header()->SetNumPagesInfo(*this);
+
+ TInt modelNum = iModelList->UidToNum(ModelUid(iModelIndex));
+ iPrintSetup->CreatePrinterDeviceL(modelNum);
+
+ // create a port if necessary
+ //CPrinterPort* port=NULL;
+ //if ((*iModelList)[modelNum].iRequiresPrinterPort)
+ // {
+ // port = CFilePrinterPort::NewL(_L("e:\\fpr.pcl"));
+ // }
+
+ iPrintSetup->PrinterDevice()->SelectPageSpecInTwips(KDefaultPageSpecInTwips);
+ iPrintSetup->iPageMarginsInTwips.iHeaderOffset = 720;
+ iPrintSetup->iPageMarginsInTwips.iFooterOffset = 0;
+ iPrintSetup->iPageMarginsInTwips.iMargins.iLeft = 1440; // 1 inch
+ iPrintSetup->iPageMarginsInTwips.iMargins.iRight = 1440;
+ iPrintSetup->iPageMarginsInTwips.iMargins.iTop = 1440;
+ iPrintSetup->iPageMarginsInTwips.iMargins.iBottom = 1440;
+ }
+
+void CDirectPrintEngine::EndPrintPreview()
+ {
+ }
+
+void CDirectPrintEngine::SetParamL(RXmlEngDocument* aParam)
+ {
+ LOG("CDirectPrintEngine::SetParamL BEGIN");
+
+ iParam = aParam;
+ if ( iPrintBand )
+ {
+ delete iPrintBand;
+ iPrintBand = NULL;
+ }
+
+ _LIT8(KElementRecogMode, "RecognizeMode");
+ _LIT8(KElementRecogModeAttr, "mode");
+ _LIT8(KElementRecogModeValueFile, "PrintRecognizeModeFile");
+ _LIT8(KElementRecogModeValuePlugin, "PrintRecognizeModePlugin");
+ _LIT8(KElementFile, "PrintFile");
+ _LIT8(KElementFileAttr, "file");
+ _LIT8(KElementPluginUid, "PluginUid");
+ _LIT8(KElementPluginUidAttr, "uid");
+
+ TXmlEngElement element = iParam->DocumentElement().FirstChild().AsElement();
+ HBufC* filename = NULL;
+ TUint uidValue = 0;
+
+ enum {
+ EParamModeFile = 0x0001,
+ EParamModePlugin = 0x0002,
+ EParamFileExist = 0x0008,
+ EParamPluginExist = 0x0010
+ };
+ TUint paramFlag = 0;
+
+ while (element.NotNull())
+ {
+ if (element.Name().CompareF(KElementRecogMode()) == 0)
+ {
+ TXmlEngAttr attr = element.AttributeNodeL(KElementRecogModeAttr,KNullDesC8);
+ if(attr.Value().CompareF(KElementRecogModeValueFile) == 0)
+ {
+ paramFlag |= EParamModeFile;
+ LOG("Param:Mode=File");
+ }
+ else if(attr.Value().CompareF(KElementRecogModeValuePlugin) == 0)
+ {
+ paramFlag |= EParamModePlugin;
+ LOG("Param:Mode=Plugin");
+ }
+ else
+ {
+ LOG("[Error] Param:Mode=Not set");
+ break;
+ }
+ }
+ else if (element.Name().CompareF(KElementFile()) == 0)
+ {
+ TXmlEngAttr attr = element.AttributeNodeL(KElementFileAttr,KNullDesC8);
+ filename = HBufC::NewLC(attr.Value().Length());
+ TPtr ptr(filename->Des());
+ ptr.Copy(attr.Value());
+ if (ptr.Length() > 0)
+ {
+ LOG1("Param:FileName UID=[%S]", &ptr);
+ if (BaflUtils::FileExists(CEikonEnv::Static()->FsSession(), ptr))
+ {
+ paramFlag |= EParamFileExist;
+ }
+ }
+ if (!(paramFlag & EParamFileExist))
+ {
+ LOG("[Error] File not exist");
+ }
+ }
+ else if (element.Name().CompareF(KElementPluginUid()) == 0)
+ {
+ TXmlEngAttr attr = element.AttributeNodeL(KElementPluginUidAttr,KNullDesC8);
+ //HBufC8* bufUid = HBufC8::NewLC(attr.Value().Length());
+ //TPtr8 ptr(bufUid->Des());
+ HBufC* bufUid = HBufC::NewLC(attr.Value().Length());
+ TPtr ptr(bufUid->Des());
+ ptr.Copy(attr.Value());
+ //_LIT8(KHeadOfHexString, "0x");
+ _LIT(KHeadOfHexString, "0x");
+ const TInt KUidStingLength = 8;
+ if (ptr.Left(KHeadOfHexString().Length()).CompareF(KHeadOfHexString()) == 0)
+ {
+ ptr.Delete(0, KHeadOfHexString().Length());
+ }
+ if (ptr.Length() == KUidStingLength)
+ {
+ //TBuf<8> bufUid;
+ //bufUid.Copy(ptr);
+ //TLex lex(bufUid);
+ TLex lex(ptr);
+ if (lex.Val(uidValue,EHex) == KErrNone)
+ {
+ LOG1("Param:Plugin UID=[0x%X]", uidValue);
+ paramFlag |= EParamPluginExist;
+ }
+ else
+ {
+ LOG("[Error] Convert from HEX string to int");
+ }
+ }
+ if (!(paramFlag & EParamPluginExist))
+ {
+ LOG("[Error] File not exist");
+ }
+ CleanupStack::PopAndDestroy(bufUid); //bufUid
+ }
+
+ if (paramFlag == (EParamFileExist|EParamModeFile)
+ || paramFlag == (EParamPluginExist|EParamModePlugin))
+ {
+ break;
+ }
+ element = element.NextSibling().AsElement();
+ }
+
+ if (paramFlag == (EParamFileExist|EParamModeFile)
+ && filename)
+ {
+ TPtrC ptr(filename->Des());
+ SearchPluginFromFilenameL(ptr);
+ }
+ if (paramFlag == (EParamPluginExist|EParamModePlugin)
+ && uidValue)
+ {
+ TUid uid = TUid::Uid(uidValue);
+ LoadPluginFromUidL(uid);
+ }
+
+ if (filename)
+ {
+ CleanupStack::PopAndDestroy(filename); //filename
+ }
+
+ if ( !iPrintBand )
+ {
+ // error xml parameter
+ User::Leave(KErrArgument);
+ }
+
+ LOG("CDirectPrintEngine::SetParamL END");
+ }
+
+void CDirectPrintEngine::SearchPluginFromFilenameL(const TDesC& aFileName)
+ {
+ LOG("CDirectPrintEngine::SearchPluginFromFilenameL START");
+ RImplInfoPtrArray infoArray;
+ TUid interface = TUid::Uid(KDirectPrintBandInterfaceUid);
+ REComSession::ListImplementationsL( interface, infoArray );
+ CleanupClosePushL( infoArray );
+ LOG1("CDirectPrintEngine::SearchPluginFromFilenameL infoArray.Count(): %d", infoArray.Count());
+
+ TParsePtrC parse(aFileName);
+
+ TPtrC8 dataType;
+ TPtrC16 dispName;
+ TPtrC8 opaqueData;
+ HBufC* dataTypeBuf = NULL;
+ TBool bFound = EFalse;
+ TInt findLen;
+ const TChar KDataTypeSeparator = '|';
+
+ for( TInt i = 0; i < infoArray.Count(); i++ )
+ {
+ LOG1("[InfoArray] i=%d", i);
+ CImplementationInformation* info = infoArray[i];
+ dataType.Set( info->DataType() );
+ dispName.Set( info->DisplayName() );
+ opaqueData.Set( info->OpaqueData() );
+
+ dataTypeBuf = HBufC::NewLC( dataType.Length() );
+ TPtr dataTypePtr(dataTypeBuf->Des());
+ dataTypePtr.Copy( dataType );
+
+ LOG1("[DataType]=[%S]", &dataTypePtr);
+ FOREVER
+ {
+ findLen = dataTypePtr.Locate( KDataTypeSeparator );
+ if (findLen < 0)
+ {
+ // the separator is not found
+ if (dataTypePtr.Length() > 0)
+ {
+ findLen = dataTypePtr.Length();
+ }
+ else
+ {
+ break;
+ }
+ }
+// LOG1("[Compare]=[%S]", &(dataTypePtr.Left( findLen )));
+// LOG1("[Ext]=[%S]", &(parse.Ext()));
+// LOG1("[Comp]=[%S]", &(dataTypePtr.Left( findLen )));
+ if ( parse.Ext().CompareF( dataTypePtr.Left( findLen ) ) == 0 )
+ {
+ bFound = ETrue;
+ break;
+ }
+ dataTypePtr.Delete( 0, findLen+1 );
+ }
+
+ CleanupStack::PopAndDestroy(dataTypeBuf); // dataTypeBuf
+
+ if ( bFound )
+ {
+ LOG("Match!!!");
+ LoadPluginFromUidL(info->ImplementationUid());
+ break;
+ }
+ }
+
+ infoArray.ResetAndDestroy();
+ CleanupStack::PopAndDestroy(&infoArray); // infoArray
+
+ LOG("CDirectPrintEngine::SearchPluginFromFilenameL End");
+ }
+
+void CDirectPrintEngine::LoadPluginFromUidL(const TUid aUid)
+ {
+ LOG1("CDirectPrintEngine::LoadPluginFromUidL(0x%X) Start", aUid.iUid);
+
+ CDirectPrintBand* band = NULL;
+ band = CDirectPrintBand::NewL(aUid);
+ TCleanupItem clItem( CleanupBand, band );
+ CleanupStack::PushL( clItem );
+ band->InitPrintBandL( iPrintSetup,
+ iParam,
+ KNullDesC );
+ CleanupStack::Pop(); // band
+ iPrintBand = band;
+
+ LOG("CDirectPrintEngine::LoadPluginFromUidL End");
+ }
+
+void CDirectPrintEngine::CleanupBand( TAny* aData )
+ {
+ LOG("[CDirectPrintEngine::CleanupBand]\t Begin");
+
+ CDirectPrintBand* band = (CDirectPrintBand*)aData;
+ delete band;
+
+ LOG("[CDirectPrintEngine::CleanupBand]\t End");
+ }
+
+
+
+// End of file