graphicsdeviceinterface/gdi/sgdi/PRINTGDI.CPP
changeset 0 5d03bc08d59c
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <gdi.h>
       
    17 #include <f32file.h>
       
    18 #include <s32file.h>
       
    19 #include <bautils.h>
       
    20 #include <barsc.h>
       
    21 #include <barsread.h>
       
    22 #include "GDIPANIC.h"
       
    23 
       
    24 _LIT(KPdrExtension,"*.PDR"); // must be capitalized
       
    25 _LIT(KPdlExtension,".PDL"); // must be capitalized
       
    26 _LIT(KUdlExtension,".UDL"); // must be capitalized
       
    27 _LIT(KRscExtension,".RSC");
       
    28 _LIT(KGdiPrintPanic,"GDI - PRINT");
       
    29 
       
    30 _LIT(KGDIPanicDesc1, "GDI Pdr internal Panic %S, in file %S @ line %i");
       
    31 _LIT(KGDIPanicDesc2, "Assert condition = \"%S\"");
       
    32 
       
    33 enum TPdrStorePanic
       
    34 	{
       
    35 	EPdrModelIndexOutOfRange,
       
    36 	EPdrModelUidNotFound,
       
    37 	EPdrDirectoryIndexOutOfRange,
       
    38 	EPdrFileIndexOutOfRange,
       
    39 	EPdrPrinterDeviceExists,
       
    40 	EPdrPrinterDeviceDoesNotExist,
       
    41 	};
       
    42 
       
    43 void Panic(TPdrStorePanic aPanic)
       
    44 	{
       
    45 	User::Panic(KGdiPrintPanic,aPanic);
       
    46 	}
       
    47 	
       
    48 void PanicWithCondAndInfo(TPdrStorePanic aError, const TDesC& aCondition, const TDesC& aFileName, const TDesC& aPanicName, TInt aLine)
       
    49 	{
       
    50 	TBuf<256> buf;
       
    51 	buf.Format(KGDIPanicDesc1, &aPanicName, &aFileName, aLine);
       
    52 	RDebug::Print(buf);
       
    53 
       
    54 	buf.Format(KGDIPanicDesc2, &aCondition);
       
    55 	RDebug::Print(buf);
       
    56 	Panic(aError);
       
    57 	}
       
    58 
       
    59 //
       
    60 // TPrinterModelEntry
       
    61 //
       
    62 
       
    63 
       
    64 EXPORT_C void TPrinterModelEntry::InternalizeL(RReadStream& aStream)
       
    65 
       
    66 /** Internalises a printer model entry from a read stream. 
       
    67 
       
    68 The presence of this function means that the standard templated stream operator>>(), 
       
    69 defined in s32strm.h, is available to internalise objects of this class.
       
    70 
       
    71 @param aStream The read stream. */
       
    72     {
       
    73 	aStream >> iModelName;
       
    74 	iRequiresPrinterPort=aStream.ReadUint8L();
       
    75 	aStream >> iUid;
       
    76 	}
       
    77 
       
    78 
       
    79 EXPORT_C void TPrinterModelEntry::ExternalizeL(RWriteStream& aStream) const
       
    80 /** Externalises the printer model entry to a write stream.
       
    81 
       
    82 The presence of this function means that the standard templated stream operator<<(), 
       
    83 defined in s32strm.h, is available to externalise objects of this class.
       
    84 
       
    85 @param aStream The write stream. */
       
    86 	{
       
    87 	aStream << iModelName;
       
    88 	aStream.WriteUint8L((TUint8) iRequiresPrinterPort);
       
    89 	aStream << iUid;
       
    90 	}
       
    91 
       
    92 //
       
    93 // TPrinterModelHeader
       
    94 //
       
    95 
       
    96 
       
    97 EXPORT_C void TPrinterModelHeader::InternalizeL(RReadStream& aStream)
       
    98 /** Internalises a printer model header from a read stream. 
       
    99 
       
   100 The presence of this function means that the standard templated stream operator>>(), 
       
   101 defined in s32strm.h, is available to internalise objects of this class.
       
   102 
       
   103 @param aStream The read stream. */
       
   104  	{
       
   105 	aStream >> iEntry;
       
   106 	aStream >> iModelDataStreamId;
       
   107 	}
       
   108 
       
   109 
       
   110 EXPORT_C void TPrinterModelHeader::ExternalizeL(RWriteStream& aStream) const
       
   111  
       
   112 /** Externalises the printer model header to a write stream.
       
   113 
       
   114 The presence of this function means that the standard templated stream operator<<(), 
       
   115 defined in s32strm.h, is available to externalise objects of this class.
       
   116 @param aStream The write stream. */
       
   117     {
       
   118 	aStream << iEntry;
       
   119 	aStream << iModelDataStreamId;
       
   120 	}
       
   121 
       
   122 //
       
   123 // CPrinterDevice
       
   124 //
       
   125 
       
   126 EXPORT_C CPrinterDevice::CPrinterDevice():
       
   127 	CGraphicsDevice(),
       
   128 	iCurrentPageSpecInTwips()
       
   129 /** Standard constructor. */
       
   130 	{}
       
   131 
       
   132 
       
   133 EXPORT_C CPrinterDevice::~CPrinterDevice()
       
   134 
       
   135 /** Destructor.
       
   136 It frees all resources owned by the object, prior to its destruction. */
       
   137 	{
       
   138 	delete iControl;
       
   139 	}
       
   140 
       
   141 
       
   142 EXPORT_C void CPrinterDevice::SelectPageSpecInTwips(const TPageSpec& aPageSpecInTwips)
       
   143 /** Sets the page specification in twips.
       
   144 @param  aPageSpec The page specification in twips. */	
       
   145     {
       
   146 	iCurrentPageSpecInTwips=aPageSpecInTwips;
       
   147 	}
       
   148 
       
   149 
       
   150 EXPORT_C TRect CPrinterDevice::PrintablePageInPixels() const
       
   151 /** Gets the dimensions of the area to which the printer device can print.
       
   152 
       
   153 These dimensions are normally less than those returned by TPageSpec::OrientedPageSize() 
       
   154 because a margin exists between the boundary of the printable page and the 
       
   155 absolute extent of the page.
       
   156 
       
   157 @return The dimensions of the printer device area in pixels, respecting the 
       
   158 page orientation */
       
   159 	{
       
   160 	return TRect(SizeInPixels());
       
   161 	}
       
   162 
       
   163 
       
   164 EXPORT_C void CPrinterDevice::DeleteControl()
       
   165  /** Deletes the printer control owned by this object.
       
   166 
       
   167 The function sets the iControl member to NULL. */
       
   168     {
       
   169 	delete iControl;
       
   170 	iControl=NULL;
       
   171 	}
       
   172 
       
   173 
       
   174 EXPORT_C void CPrinterDevice::RestorePropertiesL()
       
   175 /** Restores printer properties. */	
       
   176     {
       
   177 	_LIT(KSystemIniFileNameSpec,"Z:\\System\\System.ini");
       
   178 
       
   179 	RFs fs;
       
   180 	User::LeaveIfError(fs.Connect());
       
   181 	CleanupClosePushL(fs);
       
   182 	
       
   183 	TDriveUnit drive(static_cast<TUint>(RFs::GetSystemDrive()));
       
   184 	TParse systemIniFileName;
       
   185 	systemIniFileName.Set(drive.Name(), &KSystemIniFileNameSpec, NULL);
       
   186 	
       
   187 	TUint atts = 0;
       
   188 	TInt ret = fs.Att(systemIniFileName.FullName(), atts);
       
   189 	if (ret == KErrNone)
       
   190 		{
       
   191 		CDictionaryStore* dictionarystore = NULL;
       
   192 		TRAPD(err,dictionarystore = CDictionaryFileStore::SystemL(fs));
       
   193 		if (err == KErrNone)
       
   194 			{
       
   195 			CleanupStack::PushL(dictionarystore);
       
   196 			if (dictionarystore->IsPresentL(Model().iUid))
       
   197 				{
       
   198 				RDictionaryReadStream stream;
       
   199 				stream.OpenLC(*dictionarystore,Model().iUid);
       
   200 				InternalizePropertiesL(stream);
       
   201 				CleanupStack::PopAndDestroy(); // stream
       
   202 				}
       
   203 			CleanupStack::PopAndDestroy(); // dictionarystore
       
   204 			}
       
   205 		}
       
   206 	CleanupStack::PopAndDestroy(); // fs
       
   207 	}
       
   208 
       
   209 
       
   210 EXPORT_C void CPrinterDevice::StorePropertiesL() const
       
   211 /**  Stores the printer properties. */
       
   212     {
       
   213 	RFs fs;
       
   214 	User::LeaveIfError(fs.Connect());
       
   215 	CleanupClosePushL(fs);
       
   216 	CDictionaryStore* dictionarystore = CDictionaryFileStore::SystemLC(fs);
       
   217 	RDictionaryWriteStream stream;
       
   218 	stream.AssignLC(*dictionarystore,Model().iUid);
       
   219 	ExternalizePropertiesL(stream);
       
   220 	stream.CommitL();
       
   221 	CleanupStack::PopAndDestroy(); // stream
       
   222 	dictionarystore->CommitL();
       
   223 	CleanupStack::PopAndDestroy(2); // dictionarystore, fs
       
   224 	}
       
   225 
       
   226 //
       
   227 // CPrinterControl
       
   228 //
       
   229 
       
   230 
       
   231 EXPORT_C CPrinterControl::~CPrinterControl()
       
   232 /**  Destructor.
       
   233 
       
   234 It frees all resources owned by the object, prior to its destruction. */
       
   235  {
       
   236 	delete iPrinterPort;
       
   237 	}
       
   238 
       
   239 EXPORT_C CPrinterControl::CPrinterControl(CPrinterPort* aPrinterPort):
       
   240 	CBase(),
       
   241 	iState(ENotPrinting),
       
   242 	iPrinterPort(aPrinterPort)
       
   243 	{}
       
   244 
       
   245 //
       
   246 // TPageSpec
       
   247 //
       
   248 
       
   249 
       
   250 EXPORT_C TPageSpec::TPageSpec():
       
   251 	iPortraitPageSize(TSize(0,0)),
       
   252 	iOrientation(EPortrait)
       
   253 /** Default constructor. 
       
   254 
       
   255 Initialises the page orientation to portrait and the page height and width 
       
   256 to zero. */
       
   257 	{}
       
   258 
       
   259 
       
   260 EXPORT_C TPageSpec::TPageSpec(TPageOrientation anOrientation,const TSize& aSize):
       
   261 	iPortraitPageSize(aSize),
       
   262 	iOrientation(anOrientation)
       
   263 /** Constructor with page orientation and size. 
       
   264 
       
   265 @param aOrientation Specifies the page orientation. 
       
   266 @param aSize Specifies the page size. */
       
   267  	{}
       
   268 
       
   269 
       
   270 EXPORT_C void TPageSpec::InternalizeL(RReadStream& aStream)
       
   271 /** Internalises a page specification object from a read stream. 
       
   272 
       
   273 The presence of this function means that the standard templated stream operator>>(), 
       
   274 defined in s32strm.h, is available to internalise objects of this class.
       
   275 
       
   276 @param aStream The read stream. */
       
   277  	{
       
   278 	iPortraitPageSize.iWidth = aStream.ReadInt32L();
       
   279 	iPortraitPageSize.iHeight = aStream.ReadInt32L();
       
   280 	iOrientation=(TPageSpec::TPageOrientation)aStream.ReadInt8L();
       
   281 	}
       
   282 
       
   283 
       
   284 EXPORT_C void TPageSpec::ExternalizeL(RWriteStream& aStream) const
       
   285 /** Externalises the page specification object to a write stream.
       
   286 
       
   287 The presence of this function means that the standard templated stream operator<<(), 
       
   288 defined in s32strm.h, is available to externalise objects of this class.
       
   289 @param aStream The write stream. */
       
   290  	{
       
   291 	aStream.WriteInt32L(iPortraitPageSize.iWidth);
       
   292 	aStream.WriteInt32L(iPortraitPageSize.iHeight);
       
   293 	aStream.WriteInt8L(iOrientation);
       
   294 	}
       
   295 
       
   296 
       
   297 EXPORT_C TSize TPageSpec::OrientedPageSize()const
       
   298 /** Gets the oriented page size.
       
   299 
       
   300 The oriented page size is the absolute width and height of the page, respecting 
       
   301 the page orientation.
       
   302 @return The oriented page size (in pixels or twips). */
       
   303   	{
       
   304 	if(iOrientation==EPortrait)
       
   305 		return(iPortraitPageSize);
       
   306 	return(TSize(iPortraitPageSize.iHeight,iPortraitPageSize.iWidth));
       
   307 	}
       
   308 
       
   309 
       
   310 EXPORT_C TBool TPageSpec::operator==(const TPageSpec& aPageSpec) const
       
   311 /** Equality operator. 
       
   312 
       
   313 This operator compares page specifications for equality. Two page specifications 
       
   314 are equal if both their orientations and portrait page sizes are equal.
       
   315 
       
   316 @param aPageSpec Page specification to be compared.
       
   317 @return ETrue, if the page specifications are equal; EFalse, otherwise. */
       
   318    {
       
   319 	return(iPortraitPageSize==aPageSpec.iPortraitPageSize &&
       
   320 		iOrientation==aPageSpec.iOrientation);
       
   321 	}
       
   322 
       
   323  
       
   324 EXPORT_C TBool TPageSpec::operator!=(const TPageSpec& aPageSpec) const
       
   325 /** Inequality operator.
       
   326 
       
   327 This operator compares two page specifications for inequality. Two page specifications 
       
   328 are unequal if one or both of their orientations and portrait page sizes differ.
       
   329 
       
   330 @param aPageSpec Page specification to be compared.
       
   331 @return ETrue, if the page specifications differ; EFalse, otherwise. */
       
   332 	{
       
   333 	return(!(*this==aPageSpec));
       
   334 	}
       
   335 
       
   336 
       
   337 // TMargins
       
   338 
       
   339 EXPORT_C void TMargins::InternalizeL(RReadStream& aStream)
       
   340 /** Internalises a set of margins from a read stream.
       
   341 
       
   342 The presence of this function means that the standard templated stream operator>>() 
       
   343 is available to internalise objects of this class.
       
   344 
       
   345 @param aStream Stream from which the object is internalised. */
       
   346 	{
       
   347 	iLeft = aStream.ReadInt32L();
       
   348 	iRight = aStream.ReadInt32L();
       
   349 	iTop = aStream.ReadInt32L();
       
   350 	iBottom = aStream.ReadInt32L();
       
   351 	}
       
   352 
       
   353 EXPORT_C void TMargins::ExternalizeL(RWriteStream& aStream) const
       
   354 /** Externalises a set of margins to a write stream.
       
   355 
       
   356 The presence of this function means that the standard templated stream operator<<() 
       
   357 is available to externalise objects of this class.
       
   358 
       
   359 @param aStream Stream to which the object is externalised. */
       
   360 	{
       
   361 	aStream.WriteInt32L(iLeft);
       
   362 	aStream.WriteInt32L(iRight);
       
   363 	aStream.WriteInt32L(iTop);
       
   364 	aStream.WriteInt32L(iBottom);
       
   365 	}
       
   366 
       
   367 EXPORT_C TBool TMargins::operator==(const TMargins& aMargins) const
       
   368 /** Tests margins for equality.
       
   369 
       
   370 @param aMargins The margin to be compared with this margin. 
       
   371 @return ETrue, if the margins are equal; EFalse, otherwise. */
       
   372 	{
       
   373 	return(iLeft==aMargins.iLeft && iRight==aMargins.iRight &&
       
   374 		iTop==aMargins.iTop && iBottom==aMargins.iBottom);
       
   375 	}
       
   376 
       
   377 EXPORT_C TBool TMargins::operator!=(const TMargins& aMargins) const
       
   378 /** Tests margins for inequality.
       
   379 
       
   380 @param aMargins The margin to be compared with this margin. 
       
   381 @return ETrue, if the margins are unequal; EFalse, otherwise. */
       
   382 	{
       
   383 	return(!(*this==aMargins));
       
   384 	}
       
   385 
       
   386 //
       
   387 // CPrinterDriverUI
       
   388 //
       
   389 
       
   390 EXPORT_C CPrinterDriverUI::CPrinterDriverUI()
       
   391 	{
       
   392 	__DECLARE_NAME(_S("CPrinterDriverUI"));
       
   393 	}
       
   394 
       
   395 
       
   396 EXPORT_C TBool CPrinterDriverUI::BeforePrintL()
       
   397  /** Provides an opportunity for a dialog to be put up before printing begins.
       
   398 
       
   399 @return ETrue, if printing is to continue; EFalse, if printing is to be cancelled. 
       
   400 The default implementation returns ETrue. */
       
   401   	{
       
   402 	return ETrue;
       
   403 	}
       
   404 
       
   405 
       
   406 EXPORT_C void CPrinterDriverUI::AfterPrintL()
       
   407  /** Provides an opportunity for a dialog to be put up after printing is complete.
       
   408 The default implementation is empty. */
       
   409 	{
       
   410 	}
       
   411 
       
   412 
       
   413 EXPORT_C void CPrinterDriverUI::SetPropertiesL()
       
   414 /** Provides an opportunity for a dialog to be put up to capture or change printer 
       
   415 properties.
       
   416 The default implementation is empty. */
       
   417 	{
       
   418 	}
       
   419 
       
   420 
       
   421 EXPORT_C TBool CPrinterDriverUI::CanSetProperties()
       
   422 /** Tests whether printer properties can be set.
       
   423 
       
   424 @return ETrue, if printer properties can be set; EFalse, otherwise. The default 
       
   425 implementation returns EFalse. */
       
   426     {
       
   427 	return EFalse;
       
   428 	}
       
   429 
       
   430 //
       
   431 // CPrinterDriver
       
   432 //
       
   433 
       
   434 
       
   435 EXPORT_C CPrinterDriver* CPrinterDriver::NewL()
       
   436 /** Constructs, and returns a pointer to a new instance for accessing a printer 
       
   437 specification data store.
       
   438 
       
   439 @return Pointer to the object for accessing a printer specification data store. */
       
   440 	{
       
   441 	CPrinterDriver* printerdriver=new(ELeave) CPrinterDriver;
       
   442 	CleanupStack::PushL(printerdriver);
       
   443 	User::LeaveIfError(printerdriver->iFs.Connect());
       
   444 	CleanupStack::Pop();
       
   445 	return printerdriver;
       
   446 	}
       
   447 
       
   448 
       
   449 EXPORT_C CPrinterDriver::~CPrinterDriver()
       
   450 /** Destructor.
       
   451 
       
   452 It frees all resources owned by the object, prior to its destruction. In particular, 
       
   453 it closes the printer specification data store and any open session with the file server.  */	
       
   454     {
       
   455 	Close();
       
   456 	iFs.Close();
       
   457 	}
       
   458 
       
   459 
       
   460 EXPORT_C void CPrinterDriver::OpenPdrL(const TDesC &aName)
       
   461 /**  Opens the specified printer specification data store.
       
   462 
       
   463 @return  The name of the printer specification data store. This must be a 
       
   464 valid printer specification data store,otherwise the function leaves with
       
   465 KErrNotSupported. */	
       
   466     {
       
   467 	Close();
       
   468 	TRAPD(ret,DoOpenPdrL(aName));
       
   469 	if (ret!=KErrNone)
       
   470 		{
       
   471 		Close();
       
   472 		User::Leave(ret);
       
   473 		}
       
   474 	}
       
   475 
       
   476 EXPORT_C void CPrinterDriver::Close()
       
   477 /** Closes the printer specification data store and frees resources.
       
   478 
       
   479 An open session with the file server remains open. */
       
   480 	{
       
   481 	delete iPdrStore,
       
   482 	iPdrStore=NULL;
       
   483 	iNumModels=0;
       
   484 	delete[] iModelList;
       
   485 	iModelList=NULL;
       
   486 	DeletePrinterDevice();
       
   487 	}
       
   488 
       
   489 
       
   490 EXPORT_C TInt CPrinterDriver::NumModels() const
       
   491  /** Gets the number of printer models defined by the printer specification.
       
   492 
       
   493 @return The number of printer models. */
       
   494  	{
       
   495 	return iNumModels;
       
   496 	}
       
   497 
       
   498 
       
   499 EXPORT_C TPrinterModelEntry CPrinterDriver::Model(TInt aNum) const
       
   500 /** Gets the specified printer model.
       
   501 
       
   502 @param aNum An index into the list of printer models defined in the printer 
       
   503 specification data.
       
   504 @return Model specific information. */
       
   505  	{
       
   506 	GDI_ASSERT_DEBUG(aNum>=0,EPdrModelIndexOutOfRange);
       
   507 	GDI_ASSERT_DEBUG(aNum<iNumModels,EPdrModelIndexOutOfRange);
       
   508 	return iModelList[aNum].iEntry;
       
   509 	}
       
   510 
       
   511 
       
   512 EXPORT_C CPrinterDevice* CPrinterDriver::CreatePrinterDeviceL(TUid aModelUid)
       
   513 /** Creates the physical graphics device to be used for printing.
       
   514 
       
   515 @param aModelUid The UID of a specific model which is defined in the printer 
       
   516 specification data.
       
   517 @return The physical graphics device to be used for printing.  */	
       
   518     {
       
   519 	GDI_ASSERT_DEBUG(!iPrinterDevice,EPdrPrinterDeviceExists);
       
   520 	TRAPD(ret,DoCreatePrinterDeviceL(aModelUid));
       
   521 	if (ret!=KErrNone)
       
   522 		{
       
   523 		DeletePrinterDevice();
       
   524 		User::Leave(ret);
       
   525 		}
       
   526 	return iPrinterDevice;
       
   527 	}
       
   528 
       
   529 void CPrinterDriver::LoadLibraryL(RLibrary& aLibrary,const TDesC& aExt,TUid aUid2)
       
   530 	{
       
   531 	TFileName filename=iPdlName;
       
   532 	filename.Append(aExt);
       
   533 
       
   534 	User::LeaveIfError(aLibrary.Load(filename));
       
   535 	TUidType type=aLibrary.Type();
       
   536 	if (type[1]!=aUid2 && type[2]!=iPdlUid)
       
   537 		{
       
   538 		aLibrary.Close();
       
   539 		User::Leave(KErrNotSupported);
       
   540 		}
       
   541 	if (type[1]!=aUid2)
       
   542 		{
       
   543 		aLibrary.Close();
       
   544 		User::Leave(KErrNotFound);
       
   545 		}
       
   546 	}
       
   547 
       
   548 
       
   549 EXPORT_C CPrinterDriverUI* CPrinterDriver::CreatePrinterDriverUIL()
       
   550 /** Constructs a printer specific user interface.
       
   551 
       
   552 The user interface object is optional, but if it exists, it is implemented 
       
   553 as part of a UDL (i.e. a UI DLL).
       
   554 
       
   555 @return A pointer to the printer specific user interface, or NULL if there is 
       
   556 none. */
       
   557     {
       
   558 	GDI_ASSERT_DEBUG(iPrinterDevice,EPdrPrinterDeviceDoesNotExist);
       
   559 	if (iUdlLibrary.Handle()==0)
       
   560 		{
       
   561 		TRAPD(ret,LoadLibraryL(iUdlLibrary,KUdlExtension,TUid::Uid(KUdlUidVal)));
       
   562 		if (ret==KErrNotFound)
       
   563 			return NULL;
       
   564 		else
       
   565 			User::LeaveIfError(ret);
       
   566 		}
       
   567 	TLibraryFunction f = iUdlLibrary.Lookup(1);
       
   568 	CPrinterDriverUI* printerdriverui=(CPrinterDriverUI*)((*f)());
       
   569 	CleanupStack::PushL(printerdriverui);
       
   570 	User::LeaveIfError(printerdriverui->SetPrinterDevice(iPrinterDevice));
       
   571 	CleanupStack::Pop();
       
   572 	return printerdriverui;
       
   573 	}
       
   574 
       
   575 CPrinterDriver::CPrinterDriver()
       
   576 	{}
       
   577 
       
   578 void CPrinterDriver::DeletePrinterDevice()
       
   579 	{
       
   580 	iUdlLibrary.Close();
       
   581 	delete iPrinterDevice;
       
   582 	iPrinterDevice=NULL;
       
   583 	iPdlLibrary.Close();
       
   584 	}
       
   585 
       
   586 void CPrinterDriver::DoOpenPdrL(const TDesC &aName)
       
   587 	{
       
   588 	Close();
       
   589 	iPdrStore=CDirectFileStore::OpenL(iFs,aName,EFileStream|EFileRead|EFileShareReadersOnly);
       
   590 	if (iPdrStore->Type()[1]!=TUid::Uid(KPdrStoreFileUidVal))
       
   591 		User::Leave(KErrNotSupported);
       
   592 	TStreamId headerid = iPdrStore->Root();
       
   593 	RStoreReadStream stream;
       
   594 	stream.OpenLC(*iPdrStore,headerid);
       
   595 		stream >> iPdlName;
       
   596 	stream >> iPdlUid;
       
   597 	iNumModels = stream.ReadInt32L();
       
   598 	iModelList = new(ELeave) TPrinterModelHeader[iNumModels];
       
   599 	for (TInt i=0; i<iNumModels; i++)
       
   600 		iModelList[i].InternalizeL(stream);
       
   601 	CleanupStack::PopAndDestroy();
       
   602 	}
       
   603 
       
   604 void CPrinterDriver::DoCreatePrinterDeviceL(TUid aModelUid)
       
   605 	{
       
   606 	if (!iPdlName.Length())
       
   607 		User::Leave(KErrGeneral); // !! find a better error number
       
   608 	LoadLibraryL(iPdlLibrary,KPdlExtension,TUid::Uid(KPdlUidVal));
       
   609 	TLibraryFunction f = iPdlLibrary.Lookup(1);
       
   610 	iPrinterDevice=(CPrinterDevice*)((*f)());
       
   611 	TInt i;
       
   612 	for (i=0; (i<iNumModels) && (aModelUid!=iModelList[i].iEntry.iUid); i++)
       
   613 		{
       
   614 		}
       
   615 	GDI_ASSERT_DEBUG(i<iNumModels,EPdrModelUidNotFound);
       
   616 	User::LeaveIfError(iPrinterDevice->SetModel(iModelList[i],*iPdrStore));
       
   617 	iPrinterDevice->RestorePropertiesL();
       
   618 	}
       
   619 
       
   620 //
       
   621 // CPdrModelList
       
   622 //
       
   623 
       
   624 
       
   625 EXPORT_C CPdrModelList* CPdrModelList::NewL()
       
   626 /** Constructs, and returns a pointer to a new instance of the printer model 
       
   627 list interface.
       
   628 @return Pointer to the new printer model list interface object. */
       
   629     {
       
   630 	CPdrModelList* modellist=new(ELeave) CPdrModelList();
       
   631 	CleanupStack::PushL(modellist);
       
   632 	modellist->ConstructL();
       
   633 	CleanupStack::Pop();
       
   634 	return modellist;
       
   635 	}
       
   636 
       
   637 
       
   638 EXPORT_C CPdrModelList::~CPdrModelList()
       
   639 /** Virtual destructor.
       
   640 Frees resources owned by the object, prior to its destruction. */
       
   641 	{
       
   642 	delete iModelArray;
       
   643 	delete iFileArray;
       
   644 	if (iDirectoryArray)
       
   645 		{// delete all the HBufC's
       
   646 		for (TInt i=iDirectoryArray->Count()-1 ; i>=0 ; i--)
       
   647 			delete (*iDirectoryArray)[i];
       
   648 		delete iDirectoryArray;
       
   649 		}
       
   650 	iFileServer.Close();
       
   651 	}
       
   652 
       
   653 
       
   654 EXPORT_C TInt CPdrModelList::ModelCount() const
       
   655 /** Gets the number of printer models in the printer model list.
       
   656 @return The number of printer models. */
       
   657     {
       
   658 	return iModelArray->Count();
       
   659 	}
       
   660 
       
   661 
       
   662 EXPORT_C const TPrinterModelEntry CPdrModelList::operator [] (TInt anIndex)
       
   663 /** Gets printer model name.
       
   664 
       
   665 This is the name of the printer model at the specified index within the list 
       
   666 of printer models.
       
   667 
       
   668 @param anIndex The index of the printer model within the array of printer 
       
   669 models. Note that this number must be between zero and ModelCount(). 
       
   670 
       
   671 @return Name of printer model, up to 32 characters long */
       
   672  	{
       
   673 	GDI_ASSERT_DEBUG(anIndex>=0,EPdrModelIndexOutOfRange);
       
   674 	GDI_ASSERT_DEBUG(anIndex<iModelArray->Count(),EPdrModelIndexOutOfRange);
       
   675 
       
   676 	return (*iModelArray)[anIndex].iEntry;
       
   677 	}
       
   678 
       
   679 
       
   680 EXPORT_C TInt CPdrModelList::UidToNum(TUid aModelUid) const
       
   681 /** Gets a printer model's index within the model list from its UID.
       
   682 
       
   683 @param aModelUid The UID of the printer model.
       
   684 @return The index of the printer model within the array of printer models if 
       
   685 found; KErrNotFound, otherwise. */
       
   686     {
       
   687 	TInt i,count=iModelArray->Count();
       
   688 	for (i=0; (i<count) && (aModelUid!=(*iModelArray)[i].iEntry.iUid); i++)
       
   689 		{
       
   690 		}
       
   691 
       
   692 	if (i==count)
       
   693 		i=KErrNotFound;
       
   694 
       
   695 	return i;
       
   696 	}
       
   697 
       
   698 
       
   699 EXPORT_C void CPdrModelList::AddDirectoryL(const TDesC& aDir)
       
   700 /** Adds a directory to the list of directories to be scanned for printer models.
       
   701 
       
   702 @param aDir The directory to be added to the list. */
       
   703 	{
       
   704 	HBufC* buf = HBufC::NewL(aDir.Length());
       
   705 	CleanupStack::PushL(buf);
       
   706 	*buf = aDir;
       
   707 	iDirectoryArray->AppendL(buf);
       
   708 	CleanupStack::Pop(); //buf
       
   709 	}
       
   710 
       
   711 LOCAL_C void DereferenceAndDeleteHBufC8(TAny* aPointerToPointerToHBufC8)
       
   712 	{
       
   713 	delete *STATIC_CAST(HBufC8**, aPointerToPointerToHBufC8);
       
   714 	}
       
   715 
       
   716 
       
   717 EXPORT_C CPrinterModelList* CPdrModelList::ScanForModelsL()
       
   718 /** Scans through through the list of directories for all .pdr files and generates 
       
   719 a list of printer models.
       
   720 
       
   721 @return The list of model names. */
       
   722 	{
       
   723 	iModelArray->Reset();
       
   724 	iFileArray->Reset();
       
   725 	// check that there is at least one directory to parse?
       
   726 	// get a list of *.pdr files in all directories specified (using AddDirectory())
       
   727 	for (TInt index=iDirectoryArray->Count()-1 ; index>=0 ; index--)
       
   728 		ScanDirectoryL(index);
       
   729  	// then go through the files one at a time, adding all models to the list
       
   730 	TParse* parser = new(ELeave) TParse;
       
   731 	CleanupStack::PushL(parser);
       
   732 	TFileName* nameOfLoadedResourceFile=new(ELeave) TFileName;
       
   733 	CleanupStack::PushL(nameOfLoadedResourceFile);
       
   734 	TFileName* tempFileName=new(ELeave) TFileName;
       
   735 	CleanupStack::PushL(tempFileName);
       
   736 	RResourceFile resourceFile;
       
   737 	CleanupClosePushL(resourceFile);
       
   738 	HBufC8* resource=NULL;
       
   739 	CleanupStack::PushL(TCleanupItem(DereferenceAndDeleteHBufC8, &resource));
       
   740 	for (TInt fileNum=iFileArray->Count()-1 ; fileNum>=0 ; fileNum--)
       
   741 		ListModelsL(fileNum, *parser, *nameOfLoadedResourceFile, *tempFileName, resourceFile, resource);
       
   742 	CleanupStack::PopAndDestroy(5); // resource, resourceFile, tempFileName, nameOfLoadedResourceFile and parser
       
   743 	// return a handle to the array of model names
       
   744 	return this;
       
   745 	}
       
   746 
       
   747 
       
   748 EXPORT_C CPrinterDriver* CPdrModelList::CreatePrinterDriverL(TInt anIndex)
       
   749 /** Creates an object for accessing the specified store that contains printer specification 
       
   750 data.
       
   751 
       
   752 @param anIndex An index into a list of files containing printer specification 
       
   753 data. The files are the complete set of .pdr files found in the directories 
       
   754 known to this object.
       
   755 @return A pointer to the object representing the store containing the printer 
       
   756 specification data. */
       
   757  	{
       
   758 	GDI_ASSERT_DEBUG(anIndex>=0,EPdrModelIndexOutOfRange);
       
   759 	GDI_ASSERT_DEBUG(anIndex<iModelArray->Count(),EPdrModelIndexOutOfRange);
       
   760 
       
   761 	CPrinterDriver* driver = CPrinterDriver::NewL();
       
   762 	CleanupStack::PushL(driver);
       
   763 	HBufC* file = NewPathBufL(*((*iModelArray)[anIndex].iFile));
       
   764 	CleanupStack::PushL(file);
       
   765 	driver->OpenPdrL(*file);
       
   766 	driver->CreatePrinterDeviceL((*iModelArray)[anIndex].iEntry.iUid);
       
   767 	CleanupStack::PopAndDestroy();
       
   768 	CleanupStack::Pop();
       
   769 	return driver;
       
   770 	}
       
   771 
       
   772  
       
   773  CPdrModelList::CPdrModelList():
       
   774 	iModelArray(NULL),
       
   775 	iFileArray(NULL),
       
   776 	iDirectoryArray(NULL)
       
   777 	{
       
   778 	}
       
   779  
       
   780  void CPdrModelList::ConstructL()
       
   781 	{
       
   782 	__DECLARE_NAME(_S("CPdrModelList"));
       
   783 	iModelArray = new(ELeave) CArrayFixSeg<TModelEntry>(5);
       
   784 	iFileArray = new(ELeave) CArrayFixFlat<TFileEntry>(5);
       
   785 	iDirectoryArray = new(ELeave) CArrayFixFlat<HBufC*>(1);
       
   786 	User::LeaveIfError(iFileServer.Connect());
       
   787 	}
       
   788 
       
   789 void CPdrModelList::ScanDirectoryL(TInt aDirIndex)
       
   790 /** Scans the given directory, parsing all files found
       
   791  If a file is of the correct type it is appended to the file list*/
       
   792 	{
       
   793 	GDI_ASSERT_DEBUG(aDirIndex>=0,EPdrDirectoryIndexOutOfRange);
       
   794 	GDI_ASSERT_DEBUG(aDirIndex<iDirectoryArray->Count(),EPdrDirectoryIndexOutOfRange);
       
   795 
       
   796 	TDesC* dir = (*iDirectoryArray)[aDirIndex];
       
   797 	TParse path;
       
   798 	path.Set(KPdrExtension,dir,NULL);
       
   799 	CDir* fileList;
       
   800 	TInt ret = iFileServer.GetDir(path.FullName(),KEntryAttNormal,ESortByName,fileList);
       
   801 	if (ret == KErrNone)
       
   802 		{
       
   803 		CleanupStack::PushL(fileList);
       
   804 		for (TInt i=fileList->Count()-1 ; i>=0 ; i--) 
       
   805 			{
       
   806 			TFileEntry& entry = iFileArray->ExtendL();
       
   807 			entry.iFileName = (*fileList)[i].iName;
       
   808 			entry.iDirectory = dir;
       
   809 			}
       
   810 		CleanupStack::PopAndDestroy(); // fileList
       
   811 		}
       
   812 	else if (ret == KErrNoMemory) // Ignore errors other than KErrNoMemory
       
   813 		User::LeaveNoMemory();
       
   814 	}
       
   815 
       
   816 void CPdrModelList::ListModelsL(TInt aFileIndex, TParse& aParser, TFileName& aNameOfLoadedResourceFile, TFileName& aTempFileName, RResourceFile& aResourceFile, HBufC8*& aResource)
       
   817 /** given a pdr file list all the models it contains in the model array */
       
   818 	{
       
   819 	GDI_ASSERT_DEBUG(aFileIndex>=0,EPdrFileIndexOutOfRange);
       
   820 	GDI_ASSERT_DEBUG(aFileIndex<iFileArray->Count(),EPdrFileIndexOutOfRange);
       
   821 
       
   822 	CPrinterDriver* driver = CPrinterDriver::NewL() ;
       
   823 	CleanupStack::PushL(driver);
       
   824 	// open the file
       
   825 	HBufC* fullPath = NewPathBufL((*iFileArray)[aFileIndex]);
       
   826 	TRAPD(ret,driver->OpenPdrL(*fullPath));
       
   827 	delete fullPath;
       
   828 	if ((ret!=KErrNone) && (ret!=KErrNotSupported))
       
   829 		User::Leave(ret);
       
   830 	// get info on the models one by one and insert them into the array
       
   831 	if (ret==KErrNone)
       
   832 		{
       
   833 		TModelEntry modelentry;
       
   834 		modelentry.iFile = &(*iFileArray)[aFileIndex]; // set the file pointer for the entry
       
   835 		const TInt numberOfModels = driver->NumModels();
       
   836 		for (TInt i=0 ; i<numberOfModels ; i++)
       
   837 			{
       
   838 			modelentry.iEntry=driver->Model(i);
       
   839 			if (UidToNum(modelentry.iEntry.iUid)==KErrNotFound)
       
   840 				{
       
   841 				User::LeaveIfError(aParser.SetNoWild(KRscExtension, &modelentry.iFile->iFileName, modelentry.iFile->iDirectory));
       
   842 				aTempFileName=aParser.FullName();
       
   843 				BaflUtils::NearestLanguageFile(iFileServer, aTempFileName);
       
   844 				if (aNameOfLoadedResourceFile.CompareF(aTempFileName)!=0)
       
   845 					{
       
   846 					if (!BaflUtils::FileExists(iFileServer, aTempFileName))
       
   847 						{
       
   848 						iModelArray->AppendL(modelentry); // no resource file found, so reverting to old behaviour (i.e. where the model-name is set from the PDR file)
       
   849 						continue;
       
   850 						}
       
   851 					aNameOfLoadedResourceFile=KNullDesC;
       
   852 					aResourceFile.OpenL(iFileServer, aTempFileName);
       
   853 					HBufC8* resource=aResourceFile.AllocReadL(aResourceFile.Offset()+2); // read the first resource after the RSS_SIGNATURE resource
       
   854 					delete aResource;
       
   855 					aResource=resource;
       
   856 					aNameOfLoadedResourceFile=aTempFileName;
       
   857 					}
       
   858 				TResourceReader resourceReader;
       
   859 				resourceReader.SetBuffer(aResource);
       
   860 				for (TInt j=resourceReader.ReadUint16()-1; ; --j)
       
   861 					{
       
   862 					if (j<0)
       
   863 						{
       
   864 						iModelArray->AppendL(modelentry); // no matching uid found in the resource file, so reverting to old behaviour (i.e. where the model-name is set from the PDR file)
       
   865 						break;
       
   866 						}
       
   867 					TInt uid=resourceReader.ReadInt32();
       
   868 					TPtrC name=resourceReader.ReadTPtrC();
       
   869 					if (uid==modelentry.iEntry.iUid.iUid)
       
   870 						{
       
   871 						if (name.Length()>0)
       
   872 							{
       
   873 							modelentry.iEntry.iModelName=name;
       
   874 							iModelArray->AppendL(modelentry);
       
   875 							}
       
   876 						break;
       
   877 						}
       
   878 					}
       
   879 				}
       
   880 			}
       
   881 		}
       
   882 	CleanupStack::PopAndDestroy(); // driver
       
   883 	}
       
   884 
       
   885 
       
   886 HBufC* CPdrModelList::NewPathBufL(const TFileEntry& aFileEntry)  
       
   887 /** Create a buf of the right length and... 
       
   888  set its contents to the full filename of model aModel */
       
   889 	{
       
   890 	// Create a buf of the right length
       
   891 	HBufC* buf = HBufC::NewL(aFileEntry.iFileName.Length()+aFileEntry.iDirectory->Length());
       
   892 	// Insert the file path
       
   893 	TPtr filePtr = buf->Des();
       
   894 	filePtr.Append(*aFileEntry.iDirectory);
       
   895 	filePtr.Append(aFileEntry.iFileName);
       
   896 	return buf;
       
   897 	}
       
   898 
       
   899 // !!!!
       
   900 // Retained for binary compatibility only: remove if we make a binary incompatible release
       
   901 //
       
   902 
       
   903 IMPORT_C void GDI_Reserved();
       
   904 EXPORT_C void GDI_Reserved()
       
   905 	{}
       
   906