The
gtk:print-operation object is the high-level, portable printing
API.
It looks a bit different than other GTK dialogs such as the
gtk:file-chooser widget, since some platforms do not expose enough
infrastructure to implement a good print dialog. On such platforms, the
gtk:print-operation object uses the native print dialog. On
platforms which do not provide a native print dialog, GTK uses its own, see the
gtk:print-unix-dialog implementation.
The typical way to use the high-level printing API is to create a
gtk:print-operation object with the
gtk:print-operation-new
function when the user selects to print. Then you set some properties on it, for example the page size, any
gtk:print-settings settings from
previous print operations, the number of pages, the current page, and so on.
Then you start the print operation by calling the
gtk:print-operation-run function. It will then show a dialog, let the
user select a printer and options. When the user finished the dialog various signals will be emitted on the
gtk:print-operation object, the main one being the
"draw-page" signal, which you are supposed to catch and render the page on the provided the
gtk:print-context object using
Cairo.
By default the
gtk:print-operation object uses an external application
to do print preview. To implement a custom print preview, an application must connect to the
"preview" signal. The
gtk:print-operation-preview-render-page,
gtk:print-operation-preview-end-preview and
gtk:print-operation-preview-is-selected functions are useful when
implementing a print preview.
Examples
The high-level printing API.
(defvar *print-settings* nil)
(defun do-print-operation (window)
(let ((response nil)
(print (gtk:print-operation-new)))
;; Connect signal handlers for the print operation
(g:signal-connect print "draw-page" #'draw-page)
(g:signal-connect print "begin-print" #'begin-print)
;; Restore the print settings
(when *print-settings*
(setf (gtk:print-operation-print-settings print) *print-settings*))
;; Perform the print operation
(setf response (gtk:print-operation-run print :print-dialog window))
;; Check the response and save the print settings
(when (eq :apply response)
(setf *print-settings* (gtk:print-operation-print-settings print)))))
Signal Details
The "begin-print" signal
lambda (operation context) :run-last
- operation
- The gtk:print-operation object on which the signal was emitted.
- context
- The gtk:print-context object for the current operation.
Emitted after the user has finished changing print settings in the dialog,
before the actual rendering starts. A typical use for the "begin-print" signal is to use the parameters from the
gtk:print-context
object and paginate the document accordingly, and then set the number of pages with the
gtk:print-operation-n-pages function.
The "create-custom-widget" signal
lambda (operation) :run-last
- operation
- The gtk:print-operation object on which the signal was emitted.
- Returns
- A gtk:widget custom widget that gets embedded in the print dialog, or nil.
Emitted when displaying the print dialog. If you return a widget in a
handler for this signal it will be added to a custom tab in the print
dialog. You typically return a container widget with multiple widgets in
it. The print dialog owns the returned widget, and its lifetime is not
controlled by the application. However, the widget is guaranteed to stay around until the
"custom-widget-apply" signal is emitted on the
operation. Then you can read out any information you need from the
widgets.
The "custom-widget-apply" signal
lambda (operation widget) :run-last
- operation
- The gtk:print-operation object on which the signal was emitted.
- widget
- The gtk:widget custom widget added in a "create-custom-widget" signal handler.
Emitted right before the
"begin-print" signal if you added a custom widget in the
"create-custom-widget" signal handler. When
you get this signal you should read the information from the custom
widgets, as the widgets are not guaraneed to be around at a later time.
The "done" signal
lambda (operation result) :run-last
- operation
- The gtk:print-operation object on which the signal was emitted.
- result
- The result of type gtk:print-operation-result of the print operation.
Emitted when the print operation run has finished doing everything required for printing.
result gives you information about what happened during the run. If
result is
:error then you can call the
gtk_print_operation_get_error () function for more
information. If you enabled print status tracking then the
gtk:print-operation-is-finished function may still return
false after the
"done" signal was emitted.
The "draw-page" signal
lambda (operation context page-nr) :run-last
- operation
- The gtk:print-operation object on which the signal was emitted.
- context
- The gtk:print-context object for the current operation.
- page-nr
- The 0-based number of the currently printed page.
Emitted for every page that is printed. The signal handler must render the
page-nr's page onto the Cairo context obtained from
context using the
gtk:print-context-cairo-context function. Use the
gtk:print-operation-use-full-page and
gtk:print-operation-unit
functions before starting the print operation to set up the transformation
of the Cairo context according to your needs.
(defun draw-page (operation context page-nr)
(declare (ignore operation page-nr))
(let ((text-height 0)
(cr (gtk:print-context-cairo-context context))
(width (floor (gtk:print-context-get-width context)))
(layout (gtk:print-context-create-pango-layout context)))
;; Print a grey colored header
(cairo-rectangle cr 0 0 width *header-height*)
(cairo-set-source-rgb cr 0.9 0.9 0.9)
(cairo-fill cr)
;; Set the font and text to print
(setf (pango:layout-font-description layout)
(pango:font-description-from-string "sans 14"))
(setf (pango:layout-text layout) "Title")
(setf (pango:layout-width layout) (* width pango:+scale+))
(setf (pango:layout-alignment layout) :center)
;; Get the height of the text
(multiple-value-bind (width height)
(pango:layout-size layout)
(setf text-height (/ height pango:+scale+)))
;; Set color to black and center the text in header
(cairo-set-source-rgb cr 0.0 0.0 0.0)
(cairo-move-to cr 0 (floor (/ (- *header-height* text-height) 2)))
(pango:cairo-show-layout cr layout)))
The "end-print" signal
lambda (operation context) :run-last
- operation
- The gtk:print-operation object on which the signal was emitted.
- context
- The gtk:print-context object for the current operation.
Emitted after all pages have been rendered. A handler for this signal can
clean up any resources that have been allocated in the
"begin-print" signal handler.
The "paginate" signal
lambda (operation context) :run-last
- operation
- The gtk:print-operation object on which the signal was emitted.
- context
- The gtk:print-context object for the current operation.
Emitted after the
"begin-print" signal, but before the actual
rendering starts. It keeps getting emitted until a connected signal handler returns
true. The
"paginate" signal is intended to
be used for paginating a document in small chunks, to avoid blocking the
user interface for a long time. The signal handler should update the number of pages using the
gtk:print-operation-n-pages function, and return
true if the document has been completely paginated. If you do
not need to do pagination in chunks, you can simply do it all in the
"begin-print" signal handler, and set the number of pages from
there.
The "preview" signal
lambda (operation preview context parent) :run-last
- operation
- The gtk:print-operation object on which the signal was emitted.
- preview
- The gtk:print-preview-operation object for the current operation.
- context
- The gtk:print-context object that will be used.
- parent
- The gtk:window widget to use as window parent, or nil.
- Returns
- True if the listener wants to take over control of the preview.
Gets emitted when a preview is requested from the native dialog. The
default handler for this signal uses an external viewer application to
preview. To implement a custom print preview, an application must return
true from its handler for this signal. In order to use the provided
context for the preview implementation, it must be given a suitable Cairo context with the
gtk:print-context-set-cairo-context function. The
custom preview implementation can use the
gtk:print-operation-preview-is-selected and
gtk:print-operation-preview-render-page functions to find pages
which are selected for print and render them. The preview must be finished by calling the
gtk:print-operation-preview-end-preview function,
typically in response to the user clicking a Close button.
The "request-page-setup" signal
lambda (operation context page-nr setup) :run-last
- operation
- The gtk:print-operation object on which the signal was emitted.
- context
- The gtk:print-context object for the current operation.
- page-nr
- The 0-based number of the currently printed page.
- setup
- The gtk:page-setup object.
Emitted once for every page that is printed, to give the application a
chance to modify the page setup. Any changes done to the page setup will
be in force only for printing this page.
The "status-changed" signal
lambda (operation) :run-last
- operation
- The gtk:print-operation object on which the signal was emitted.
Emitted at between the various phases of the print operation. See the
gtk:print-status enumeration for the phases that are being discriminated. Use the
gtk:print-operation-status function to
find out the current status.
The "update-custom-widget" signal
lambda (operation widget setup settings) :run-last
- operation
- The gtk:print-operation object on which the signal was emitted.
- widget
- The gtk:widget custom widget added in the "create-custom-widget" signal handler.
- setup
- Actual gtk:page-setup object.
- settings
- Actual gtk:print-settings object.
Emitted after change of the selected printer. The actual page setup and
print settings are passed to the custom widget, which can actualize
itself according to this change.