|
The printing system in the initial versions of Mac OS X
supported a limited print Apple event but there was no way to specify any options
or settings to the printing application. As of Mac OS X 10.3 (Panther), the printing
system supports an enhanced print Apple event
that provides scripters with control over settings such as number of copies,
collation, page range, etc.
This document describes the enhanced print event and the changes applications
must make to support the new scriptable printing features. Printer Modules and
CUPS filters will not need to change.
[Dec 09, 2003]
|
The Enhanced Print Apple event
As of Mac OS X 10.3, the print Apple event has been extended to include an optional
print settings parameter that defines the settings for the print job or jobs,
and an optional print dialog parameter that specifies whether the application
should display the Print dialog. By default, the application should not show the
Print dialog if the caller doesn't specify a print dialog parameter.
print: Print the specified object(s)
print reference -- Objects to print. Can be a list of files or an object specifier.
[with properties print settings] -- The print settings
[print dialog boolean] -- Should the application show the Print dialog?
The print settings parameter allows a scripter to specify the following information.
Class print settings:
Properties:
copies integer [r/o] -- The number of copies of a document to be printed
collating boolean [r/o] -- Should printed copies be collated?
starting page integer [r/o] -- The first page of the document to be printed
ending page integer [r/o] -- The last page of the document to be printed
pages across integer [r/o] -- Number of logical pages laid across a physical page
pages down integer [r/o] -- Number of logical pages laid out down a physical page
requested print time date [r/o] -- The time at which the desktop printer should print the document
error handling standard/summarized/detailed [r/o] -- How errors are handled
fax number text [r/o] -- The number to which to fax the document
target printer text [r/o] -- The name of the destination print queue
For example, the following script prints three copies of the second page of a document to the printer "Prints Charming" after showing the Print dialog.
set theDoc to alias "Macintosh HD:ReadMe"
set printConfig to {copies:3, starting page:2, ending page:2,
target printer:"Prints Charming"}
print theDoc with properties printConfig with print dialog
|
These optional parameters to the print event provide much finer control than was previously possible.
Back to top
Application Changes Required
Applications will need to be revised to support the optional print settings parameter for the
print event. While every effort has been made to minimize the number of changes you will need
to make to your application, the actual amount of work is dependent upon the current state of
the application's printing code. This section describes the changes needed to support the
extended print event. In addition, there is sample code accompanying this Technote which shows
how to add scriptable printing support to an application.
Download Sample code
There are 4 steps required to update your application to support scriptable printing and the optional parameters.
- Update your application's
'aete' resource to indicate support for the
new, optional print parameter and for the print settings class. An example 'aete'
is included with the sample code for this Technote in the file "AESupport.r"
- Revise the application's print event handler to respond to the optional
print settings parameter. The optional
print settings parameter for the print event uses the key keyAEPropData . An application's print handler
retrieves the keyAEPropData parameter and coerces it into a PMPrintSettings object in one step using
AEGetParamPtr . If the optional parameter was successfully coerced into a PMPrintSettings object,
use those print settings for the current print job. The PMPageFormat information
for the document to be printed comes from the page format stored with the document or from a newly
defaulted page format.
- Check to see if the optional
print settings parameter also contains a target printer object by calling
AEGetParamPtr with a key of keyAEPropData and a type of kPMPrinterAEType . If the resulting
PMPrinter is non-NULL, then it should be used as the target printer for the print session by calling
PMSessionSetCurrentPrinter .
- Finally, check for the presence of the optional
print dialog parameter that specifies whether or not your
application should display the Print dialog to the user. If this parameter is missing, you should
not display the Print dialog. In the case of multiple documents being printed with the same print event,
the Print dialog should only be shown once and those settings should be used for each document.
The following code shows how to retrieve, coerce, and apply the PMPrintSettings object
found in the optional print settings parameter.
OSErr AEPrintDocument ( const AppleEvent *inputEvent,
AppleEvent *outputEvent,
SInt32 handlerRefCon )
{
#pragma unused (outputEvent,handlerRefCon)
assert( inputEvent != NULL );
OSStatus status = noErr;
PMPrintSettings printSettings = kPMNoPrintSettings;
PMPrinter printer = NULL;
Boolean showPrintDialog = false;
PMPrintSession session = NULL;
PMPageFormat pageFormat = kPMNoPageFormat;
Boolean printIt = true;
#define kDontCare NULL
// In this next section, grab the parameters from the incoming
// Apple event. Note that since everything is optional, we're
// ignoring status - if the data isn't present then move on.
// Grab the print settings
// They may not have requested any specific print settings.
// Later on, we'll use the default print settings in this case.
status = AEGetParamPtr( inputEvent,
keyAEPropData, kPMPrintSettingsAEType,
kDontCare, &printSettings,
sizeof( void* ), kDontCare );
// Grab the requested printer, if any
// They may not have requested a target printer.
status = AEGetParamPtr( inputEvent,
keyAEPropData, kPMPrinterAEType,
kDontCare, &printer, sizeof( void* ),
kDontCare );
// See if we need to show the print dialog - default is no.
status = AEGetParamPtr( inputEvent,
kPMShowPrintDialogAEType, typeBoolean,
kDontCare, &showPrintDialog,
sizeof( Boolean ), kDontCare );
// Now that we've retrieved the PMPrintSettings, PMPrinter,
// and showPrintDialog items from the event, print the files.
// Create the session we'll use to print.
status = PMCreateSession( &session );
if ( status == noErr )
{
// Set the output to the target printer.
if ( printer != NULL )
{
status = PMSessionSetCurrentPMPrinter( session, printer);
}
// If the scripter didn't request any specific print
// settings, load up the default set
if ( printSettings == kPMNoPrintSettings )
{
status = PMCreatePrintSettings( &printSettings );
if ( status == noErr )
{
status = PMSessionDefaultPrintSettings(session,
printSettings);
}
}
// Create a default PMPageFormat
// In a real application, unflatten the page format stored
// with the document and use that
status = PMCreatePageFormat(&pageFormat);
if ( (status == noErr) && (pageFormat != kPMNoPageFormat) )
{
PMSessionDefaultPageFormat(session, pageFormat);
}
// Show the print dialog?
// Only show the print dialog once for a given pdoc event.
// Use the resulting settings for all files in the event.
if ( showPrintDialog )
{
status = PMSessionPrintDialog( session, printSettings,
pageFormat, &printIt );
}
if ( printIt )
{
AEDescList docList;
long index, itemsInList;
// Get the file list.
status = AEGetParamDesc( inputEvent, keyDirectObject,
typeAEList, &docList );
if ( status == noErr )
{
// How many files are we supposed to print?
status = AECountItems( &docList, &itemsInList );
// Walk the list of files.
for ( index = 1; index <= itemsInList; index++ )
{
AEKeyword keywd;
DescType returnedType;
Size actualSize;
HFSUniStr255 fileName;
CFStringRef fileNameRef=NULL;
WindowRef windowRef = NULL;
char buffer[ kFileBufferSize ];
long count = sizeof( buffer );
FSRef fileRef;
// Get the file ref.
status = AEGetNthPtr( &docList, index, typeFSRef,
&keywd, &returnedType,
(Ptr)(&fileRef),
sizeof( fileRef ),
&actualSize );
// Get the file name to use in the window's title.
if ( status == noErr )
{
status = FSGetCatalogInfo( &fileRef, 0, NULL,
&fileName,
NULL, NULL );
}
if ( status == noErr )
{
fileNameRef = CFStringCreateWithCharacters(
kCFAllocatorDefault,
&fileName.unicode[0],
fileName.length );
}
// Open the file for reading.
if ( status == noErr )
{
status = ReadFileData( fileRef, &count,
&buffer[0] );
if ( status == noErr )
{
// Show a sample document window
windowRef = ShowDocumentWindow(
fileNameRef,buffer,count);
status = PrintDocument( session,
printSettings, pageFormat,
fileNameRef, buffer );
// We're done with the filename string
CFRelease( fileNameRef );
// We're done with the window
DisposeWindow( windowRef );
}
}
}
}
}
// Clean up.
PMRelease( pageFormat );
PMRelease( session );
}
// We're done so get rid of everything.
PMRelease( printSettings );
PMRelease( printer );
return status;
} // AEPrintDocument
|
Back to top
Summary
The introduction of the enhanced print Apple event with Mac OS X 10.3 allows users to script the
printing process with much finer control than before. Supporting this scriptability requires
that applications change their print loops to make use of the optional parameters.
The rewards for AppleScript users will be significant, since these changes will provide much more
flexibility in printing.
Back to top
References
Mac OS X Printing developer page
Mac OS X Printing Technical Documentation
Mac OS X Printing Q&As
Mac OS X Printing Technotes
AppleScript developer page
AppleScript on Mac OS X
AppleScript documentation
Back to top
Downloadables
Back to top
|