1/* Copyright (C) 2006 The gtkmm Development Team
2 *
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
16 */
17
18#include <glibmm/object.h>
19
20#include <gtkmm/pagesetup.h>
21#include <gtkmm/printcontext.h>
22#include <gtkmm/printoperationpreview.h>
23#include <gtkmm/printsettings.h>
24#include <gtkmm/window.h>
25
26_DEFS(gtkmm,gtk)
27_PINCLUDE(glibmm/private/object_p.h)
28_PINCLUDE(gtk/gtk.h)
29
30namespace Gtk
31{
32
33_WRAP_ENUM(PrintStatus, GtkPrintStatus)
34_WRAP_ENUM(PrintOperationResult, GtkPrintOperationResult)
35_WRAP_ENUM(PrintOperationAction, GtkPrintOperationAction)
36_WRAP_GERROR(PrintError, GtkPrintError, GTK_PRINT_ERROR)
37
38/** @defgroup Printing Printing
39 */
40
41/** PrintOperation is the high-level, portable printing API. It looks a bit different than other
42 * GTK+ dialogs such as the FileChooser, since some platforms don't expose enough infrastructure
43 * to implement a good print dialog. On such platforms, PrintOperation uses the native print
44 * dialog. On platforms which do not provide a native print dialog, GTK+ uses its own, see PrintUnixDialog.
45 *
46 * The typical way to use the high-level printing API is to create a PrintOperation object
47 * when the user chooses to print. Then you set some properties on it,such as the page size, any PrintSettings
48 * from previous print operations, the number of  pages, the current page, etc.
49 *
50 * Then you start the print operation by calling run(). It will then show a dialog to
51 * let the user select a printer and options. When the user finishes the dialog various signals will be
52 * emitted by the PrintOperation for you to handle, the main one being draw_page. You should then
53 * render the page on the provided PrintContext using Cairo.
54 *
55 * @newin{2,10}
56 *
57 * @ingroup Printing
58 */
59class PrintOperation :
60  public Glib::Object,
61  public PrintOperationPreview
62{
63  _CLASS_GOBJECT(PrintOperation, GtkPrintOperation, GTK_PRINT_OPERATION, Glib::Object, GObject)
64  _IMPLEMENTS_INTERFACE(PrintOperationPreview)
65
66protected:
67  _CTOR_DEFAULT
68
69public:
70  _WRAP_CREATE()
71
72  _WRAP_METHOD(void set_default_page_setup(const Glib::RefPtr<PageSetup>& default_page_setup),
73               gtk_print_operation_set_default_page_setup)
74
75  _WRAP_METHOD(Glib::RefPtr<PageSetup> get_default_page_setup(), gtk_print_operation_get_default_page_setup, refreturn)
76  _WRAP_METHOD(Glib::RefPtr<const PageSetup> get_default_page_setup() const, gtk_print_operation_get_default_page_setup, refreturn, constversion)
77
78  _WRAP_METHOD(void set_print_settings(const Glib::RefPtr<PrintSettings>& print_settings),
79               gtk_print_operation_set_print_settings)
80
81  _WRAP_METHOD(Glib::RefPtr<PrintSettings> get_print_settings(), gtk_print_operation_get_print_settings, refreturn)
82  _WRAP_METHOD(Glib::RefPtr<const PrintSettings> get_print_settings() const, gtk_print_operation_get_print_settings, refreturn, constversion)
83
84  _WRAP_METHOD(void set_job_name(const Glib::ustring& job_name), gtk_print_operation_set_job_name)
85  _WRAP_METHOD(void set_n_pages(int n_pages), gtk_print_operation_set_n_pages)
86  _WRAP_METHOD(void set_current_page(int current_page), gtk_print_operation_set_current_page)
87  _WRAP_METHOD(void set_use_full_page(bool use_full_page = true), gtk_print_operation_set_use_full_page)
88  _WRAP_METHOD(void set_unit(Unit unit), gtk_print_operation_set_unit)
89  _WRAP_METHOD(void set_export_filename(const std::string& filename), gtk_print_operation_set_export_filename)
90  _WRAP_METHOD(void set_track_print_status(bool track_status = true), gtk_print_operation_set_track_print_status)
91  _WRAP_METHOD(void set_show_progress (bool show_progress = true), gtk_print_operation_set_show_progress)
92  _WRAP_METHOD(void set_allow_async(bool allow_async = true), gtk_print_operation_set_allow_async)
93  _WRAP_METHOD(void set_custom_tab_label(const Glib::ustring& label), gtk_print_operation_set_custom_tab_label)
94
95  #m4 _CONVERSION(`GtkPrintOperationAction',`PrintOperationAction',`($2)$3')
96
97  /** See the run() method that takes both action and parent parameters.
98   */
99  PrintOperationResult run(PrintOperationAction action = PRINT_OPERATION_ACTION_PRINT_DIALOG);
100
101  _WRAP_METHOD(PrintOperationResult run(PrintOperationAction action, Window& parent), gtk_print_operation_run, errthrow)
102
103  _WRAP_METHOD(PrintStatus get_status() const, gtk_print_operation_get_status)
104  _WRAP_METHOD(Glib::ustring get_status_string() const, gtk_print_operation_get_status_string)
105  _WRAP_METHOD(void cancel(), gtk_print_operation_cancel)
106  _WRAP_METHOD(bool is_finished() const, gtk_print_operation_is_finished)
107
108  _WRAP_METHOD(void draw_page_finish(), gtk_print_operation_draw_page_finish)
109  _WRAP_METHOD(void set_defer_drawing(), gtk_print_operation_set_defer_drawing)
110
111
112  _WRAP_METHOD(void set_support_selection(bool support_selection = true), gtk_print_operation_set_support_selection)
113  _WRAP_METHOD(bool get_support_selection() const, gtk_print_operation_get_support_selection)
114  _WRAP_METHOD(void set_has_selection(bool has_selection = true), gtk_print_operation_set_has_selection)
115  _WRAP_METHOD(bool get_has_selection() const, gtk_print_operation_get_has_selection)
116
117  _WRAP_METHOD(void set_embed_page_setup(bool embed = true), gtk_print_operation_set_embed_page_setup)
118  _WRAP_METHOD(bool get_embed_page_setup() const, gtk_print_operation_get_embed_page_setup)
119  _WRAP_METHOD(int get_n_pages_to_print() const, gtk_print_operation_get_n_pages_to_print)
120
121  _IGNORE(gtk_print_run_page_setup_dialog, gtk_print_run_page_setup_dialog_async)
122
123  #m4 _CONVERSION(`GtkPrintOperationResult',`PrintOperationResult',`($2)$3')
124
125  _IGNORE(gtk_print_operation_get_error)
126
127  //TODO: point out in the docs that the PrintOperationResult enum may also indicate
128  // that an error occurred, and in that case it is up to him to handle it.
129  _WRAP_SIGNAL(void done(PrintOperationResult result), "done")
130
131  #m4 _CONVERSION(`GtkPrintContext*',`const Glib::RefPtr<PrintContext>&',`Glib::wrap($3, true)')
132  _WRAP_SIGNAL(void begin_print(const Glib::RefPtr<PrintContext>& context), "begin_print")
133  _WRAP_SIGNAL(bool paginate(const Glib::RefPtr<PrintContext>& context), "paginate")
134
135  #m4 _CONVERSION(`GtkPageSetup*',`const Glib::RefPtr<PageSetup>&',`Glib::wrap($3, true)')
136  _WRAP_SIGNAL(void request_page_setup(const Glib::RefPtr<PrintContext>& context, int page_no, const Glib::RefPtr<PageSetup>& setup), "request_page_setup")
137  _WRAP_SIGNAL(void draw_page(const Glib::RefPtr<PrintContext>& context, int page_nr), "draw_page")
138  _WRAP_SIGNAL(void end_print(const Glib::RefPtr<PrintContext>& context), "end_print")
139  _WRAP_SIGNAL(void status_changed(), "status_changed")
140
141  #m4 _CONVERSION(`Widget*',`GObject*',`G_OBJECT(Glib::unwrap($3))')
142  #m4 _CONVERSION(`GObject*',`Widget*',`Glib::wrap(GTK_WIDGET($3))')
143  _WRAP_SIGNAL(Widget* create_custom_widget(), "create_custom_widget")
144
145  _WRAP_SIGNAL(void custom_widget_apply(Widget* widget), "custom_widget_apply")
146
147  #m4 _CONVERSION(`GtkPrintOperationPreview*', `const Glib::RefPtr<PrintOperationPreview>&', `Glib::wrap($3, true)')
148  #m4 _CONVERSION(`const Glib::RefPtr<PrintOperationPreview>&', `GtkPrintOperationPreview*', `(Glib::unwrap($3))')
149
150  #m4 _CONVERSION(`Window*',`GtkWindow*',`Glib::unwrap($3)')
151
152  //TODO: This is causing crashes. Is it still causing crashes? murrayc.
153  _WRAP_SIGNAL(bool preview(const Glib::RefPtr<PrintOperationPreview>& preview, const Glib::RefPtr<PrintContext>& context, Window* parent), "preview")
154
155  //TODO: Remove no_default_handler when we can break ABI.
156  #m4 _CONVERSION(`GtkPrintSettings*', `const Glib::RefPtr<PrintSettings>&', `Glib::wrap($3, true)')
157  _WRAP_SIGNAL(void update_custom_widget(Widget* widget, const Glib::RefPtr<PageSetup>& setup, const Glib::RefPtr<PrintSettings>& settings), "update_custom_widget", no_default_handler)
158
159  _WRAP_PROPERTY("default_page_setup", Glib::RefPtr<PageSetup>)
160  _WRAP_PROPERTY("print_settings", Glib::RefPtr<PrintSettings>)
161  _WRAP_PROPERTY("job_name", Glib::ustring)
162  _WRAP_PROPERTY("n_pages", int)
163  _WRAP_PROPERTY("current_page", int)
164  _WRAP_PROPERTY("use_full_page", bool)
165  _WRAP_PROPERTY("track-print-status", bool)
166  _WRAP_PROPERTY("unit", Unit)
167  _WRAP_PROPERTY("show_progress", bool)
168  _WRAP_PROPERTY("allow_async", bool)
169  _WRAP_PROPERTY("export_filename", std::string)
170  _WRAP_PROPERTY("status", PrintStatus)
171  _WRAP_PROPERTY("status_string", Glib::ustring)
172  _WRAP_PROPERTY("custom_tab_label", Glib::ustring)
173  _WRAP_PROPERTY("support-selection", bool)
174  _WRAP_PROPERTY("has-selection", bool)
175  _WRAP_PROPERTY("embed-page-setup", bool)
176  _WRAP_PROPERTY("n-pages-to-print", int)
177};
178
179  //TODO: Make these static members of a class instead of non-class functions?
180
181  //Note: gtk_run_page_setup_dialog() can take a null page_setup object, but the application should always
182  //store and reuse a page_setup object, so I see no need to provide an overload for that. murrayc.
183  //TODO: The parent parameter may also be null, so maybe we should add an overload for that.
184
185  /** Runs a page setup dialog, letting the user modify the values from page_setup.
186   * If the user cancels the dialog, the returned PageSetup is identical to that passed in @a page_setup,
187   * otherwise it contains the modifications done in the dialog.
188   *
189   * Note that this function may use a recursive mainloop to show the page setup dialog.
190   * See run_page_setup_dialog_async() if this is a problem.
191   *
192   * @param parent Transient parent.
193   * @param page_setup An existing GtkPageSetup.
194   * @param print_settings Print settings.
195   * @result A new PageSetup object.
196   *
197   * @since 2.10
198   */
199  Glib::RefPtr<PageSetup> run_page_setup_dialog(Window& parent,
200                                                const Glib::RefPtr<const PageSetup>& page_setup,
201                                                const Glib::RefPtr<const PrintSettings>& print_settings);
202
203  /** Runs a page setup dialog, letting the user modify the values from page_setup.
204   * If the user cancels the dialog, the returned PageSetup is identical to that passed in @a page_setup,
205   * otherwise it contains the modifications done in the dialog.
206   *
207   * Note that this function may use a recursive mainloop to show the page setup dialog.
208   * See run_page_setup_dialog_async() if this is a problem.
209   *
210   * @param parent Transient parent.
211   * @param print_settings Print settings.
212   * @result A new PageSetup object.
213   *
214   * @since 2.22
215   */
216  Glib::RefPtr<PageSetup> run_page_setup_dialog(Window& parent,
217                                                const Glib::RefPtr<const PrintSettings>& print_settings);
218
219  /** For example,
220   * void on_setup_done(const Glib::RefPtr<PageSetup>& page_setup);
221   */
222  typedef sigc::slot< void, const Glib::RefPtr<PageSetup>& > SlotPrintSetupDone;
223
224  /** Runs a page setup dialog, letting the user modify the values from page_setup.
225   *
226   * In contrast to run_page_setup_dialog(), this function returns after showing the
227   * page setup dialog on platforms that support this, and calls the @a slot from a
228   * signal handler for the ::response signal of the dialog.
229   *
230   * @param parent Transient parent.
231   * @param page_setup An existing GtkPageSetup.
232   * @param print_settings Print settings.
233   * @result A new PageSetup object.
234   * @param slot
235   *
236   * @since 2.10
237   */
238  void run_page_setup_dialog_async(Window& parent,
239                                   const Glib::RefPtr<const PageSetup>& page_setup,
240                                   const Glib::RefPtr<const PrintSettings>& print_settings,
241                                   const SlotPrintSetupDone& slot);
242
243  /** Runs a page setup dialog, letting the user modify the values from page_setup.
244   *
245   * In contrast to run_page_setup_dialog(), this function returns after showing the
246   * page setup dialog on platforms that support this, and calls the @a slot from a
247   * signal handler for the ::response signal of the dialog.
248   *
249   * @param parent Transient parent.
250   * @param print_settings Print settings.
251   * @result A new PageSetup object.
252   * @param slot
253   *
254   * @since 2.22
255   */
256  void run_page_setup_dialog_async(Window& parent,
257                                   const Glib::RefPtr<const PrintSettings>& print_settings,
258                                   const SlotPrintSetupDone& slot);
259
260} // namespace Gtk
261