c++-gtk-utils
file_print_manager.h
Go to the documentation of this file.
1 /* Copyright (C) 2006 to 2011 Chris Vine
2 
3 The library comprised in this file or of which this file is part is
4 distributed by Chris Vine under the GNU Lesser General Public
5 License as follows:
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Lesser General Public License
9  as published by the Free Software Foundation; either version 2.1 of
10  the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful, but
13  WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Lesser General Public License, version 2.1, for more details.
16 
17  You should have received a copy of the GNU Lesser General Public
18  License, version 2.1, along with this library (see the file LGPL.TXT
19  which came with this source code package in the c++-gtk-utils
20  sub-directory); if not, write to the Free Software Foundation, Inc.,
21  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 
23 */
24 
25 #ifndef CGU_FILE_PRINTMANAGER_H
26 #define CGU_FILE_PRINTMANAGER_H
27 
28 #include <string>
29 
30 #include <gtk/gtk.h>
31 #include <gdk/gdk.h>
32 #if GTK_CHECK_VERSION(2,14,0)
33 #include <gtk/gtkunixprint.h>
34 #else
35 #include <gtk/gtkprintunixdialog.h>
36 #include <gtk/gtkprintjob.h>
37 #include <gtk/gtkprinter.h>
38 #endif
39 
40 
41 #include <c++-gtk-utils/window.h>
42 #include <c++-gtk-utils/notifier.h>
43 #include <c++-gtk-utils/mutex.h>
46 #include <c++-gtk-utils/emitter.h>
48 
49 
50 namespace Cgu {
51 
52 /**
53  * @class FilePrintDialog file_print_manager.h c++-gtk-utils/file_print_manager.h
54  * @brief A print dialog class for FilePrintManager.
55  * @sa FilePrintManager
56  */
57 
58 class FilePrintDialog: public WinBase {
59 protected:
60 /**
61  * Closes the dialog, cleans up and emits the rejected Emitter object.
62  * It will not throw, even if a method connected to the rejected
63  * Emitter object throws (the exception is caught and reported in
64  * order to prevent it trying to propagate through the GTK+ event
65  * system).
66  */
67  virtual void on_delete_event();
68 public:
69 #ifndef DOXYGEN_PARSING
70  // this helper class avoids exposing GObject callbacks with C
71  // linkage to the global namespace
72  class CB;
73  friend class CB;
74 #endif
75 
76 /**
77  * The accepted Emitter object emits if the user choses OK in the
78  * print dialog. Emission of accepted by this class will not throw,
79  * even if a method connected to the accepted Emitter object throws
80  * (the exception is caught and reported in order to prevent it trying
81  * to propagate through the GTK+ event system).
82  */
84 
85 /**
86  * The rejected Emitter object emits if the user choses Cancel in the
87  * print dialog. Emission of rejected by this class will not throw,
88  * even if a method connected to the rejected Emitter object throws
89  * (the exception is caught and reported in order to prevent it trying
90  * to propagate through the GTK+ event system).
91  */
93 
94 /**
95  * Gets the currently selected printer from the print dialog. It will
96  * not throw. It must be called in the thread in which the main GTK+
97  * event loop runs.
98  * @return The currently selected printer in the print dialog. The
99  * return value is owned by GTK+ - do not unreference it.
100  */
101  GtkPrinter* get_printer() const;
102 
103 /**
104  * Gets the print settings from the print dialog. It will not throw.
105  * It must be called in the thread in which the main GTK+ event loop
106  * runs.
107  * @return The currently selected printer in the print dialog.
108  * Ownership is taken of the return value, by GobjHandle.
109  */
111 
112 /**
113  * Gets the printer page set-up from the print dialog. It will not
114  * throw. It must be called in the thread in which the main GTK+
115  * event loop runs.
116  * @return The printer page set-up in the print dialog. The return
117  * value is owned by GTK+ - do not unreference it.
118  */
119  GtkPageSetup* get_page_setup() const;
120 
121 /**
122  * The constructor will not throw. A FIlePrintDialog object must be
123  * created in the thread in which the main GTK+ event loop runs.
124  * @param parent The parent of the print dialog (NULL may be passed).
125  * @param print_settings The print settings from a previous print job
126  * (if any, NULL may be passed if none).
127  * @param caption Window caption (optional, NULL may be passed).
128  * @param window_icon A pixbuf which will comprise the window icon
129  * (optional, NULL may be passed).
130  */
131  FilePrintDialog(GtkWindow* parent, GtkPrintSettings* print_settings = 0,
132  const char* caption = 0, GdkPixbuf* window_icon = 0);
133 
134  /* we inherit glib memory slice functions from WinBase */
135 };
136 
137 
138 /**
139  * @class FilePrintManager file_print_manager.h c++-gtk-utils/file_print_manager.h
140  * @brief A class to print a file using the GTK+ print system.
141  *
142  * The FilePrintManager class prints a file printable by the print
143  * system (eg lpr or CUPS) using the GTK+ printer interface. All
144  * print systems on Unix-like systems will print Postscript (PS)
145  * files. Some may also print PDF files. To obtain a
146  * FilePrintManager object, call FilePrintManager::create_manager().
147  * FilePrintManager::set_filename() passes the name of the file to be
148  * printed. To print the file, call FilePrintManager::print(). If
149  * FilePrintManager::print() returns true, the FilePrintManager class
150  * will unlink() (ie delete) the file to be printed when it has been
151  * finished with if true is passed as the second argument of
152  * FilePrintManager::set_filename(), even if printing failed.
153  *
154  * Once FilePrintManager::print() has been called, the
155  * FilePrintManager class owns a reference to itself and so manages
156  * its own lifetime - so once that method has been called it doesn't
157  * matter if the IntrusivePtr object returned by
158  * FilePrintManager::create_manager() goes out of scope (however, once
159  * FilePrintManager::print() has been called, the FilePrintManager
160  * object will not be deleted until both printing has completed or
161  * failed AND the IntrusivePtr object returned by
162  * FilePrintManager::create_manager() has gone out of scope or has
163  * been reset()).
164  *
165  * If the print dialog which is displayed on calling
166  * FilePrintManager::print() is to display a window icon, then pass
167  * FilePrintManager::create_manager() a GobjHandle<GdkPixbuf> icon as
168  * the second argument.
169  *
170  * Normally, a user would probably only want to use any one
171  * FilePrintManager object to print a single print job (it has been
172  * designed with that in mind). Nevertheless, if a reference to the
173  * object is kept alive via an active IntrusivePtr object, it can be
174  * used to print more than one print job. However, if that is done it
175  * is not possible to call FilePrintManager::print() or
176  * FilePrintManager::set_filename() until the previous print job (if
177  * any) has been dispatched to the GTK+ print system (or cancelled).
178  * If the FilePrintManager object is not ready because it is in the
179  * middle of handling an earlier print job, then the call to
180  * FilePrintManager::print() or FilePrintManager::set_filename() will
181  * return false; if however the new print job was successfully started
182  * or file name successfully set, they will return true. It is not
183  * necessary to check the return value of these methods for the first
184  * print job despatched by any one FilePrintManager object.
185  *
186  * For printing plain text (say, from a GtkTextBuffer class, or from a
187  * plain text file), see the TextPrintManager class.
188 */
189 
191  Thread::Mutex mutex;
192  GtkWindow* parent_p;
193  std::string caption;
194  GobjHandle<GdkPixbuf> window_icon_h;
195  bool manage;
196  std::string filename;
197  FilePrintDialog* dialog_p;
198  Notifier print_notifier;
199  bool ready;
200 
201  static GobjHandle<GtkPrintSettings> print_settings_h;
202 
203  void show_dialog();
204  void print_file();
205  void print_cancel();
206  void clean_up();
207  // private constructor
208  FilePrintManager() {}
209 public:
210 #ifndef DOXYGEN_PARSING
211  // this helper class avoids exposing GObject callbacks with C
212  // linkage to the global namespace
213  class CB;
214  friend class CB;
215 #endif
216 /**
217  * This class cannot be copied: it is intended to be held by
218  * IntrusivePtr. The copy constructor is deleted.
219  */
220  FilePrintManager(const FilePrintManager&) = delete;
221 
222 /**
223  * This class cannot be copied: it is intended to be held by
224  * IntrusivePtr. The assignment operator is deleted.
225  */
226  FilePrintManager& operator=(const FilePrintManager&) = delete;
227 
228 /**
229  * Creates a new FilePrintManager object. No GTK+/GDK functions are
230  * called by this method, and it is thread safe provided that, if it
231  * is called in a thread other than the one in which the GTK+ event
232  * loop runs, Cgu::Notifier::init() has previously been called in the
233  * GTK+ event loop thread.
234  * @param parent The parent of the print dialog which will be created
235  * by the FilePrintManager object (optional, NULL may be passed).
236  * @param caption Window caption of the print dialog which will be
237  * created by the FilePrintManager object (optional, an empty string
238  * may be passed).
239  * @param window_icon A pixbuf which will comprise the window icon of
240  * the print dialog which will be created by the FilePrintManager
241  * object (optional, an empty GobjHandle object may be passed).
242  * @exception std::bad_alloc This method might throw std::bad_alloc if
243  * memory is exhausted and the system throws in that case.
244  * @exception Cgu::Thread::MutexError This method might throw
245  * Cgu::Thread::MutexError if initialisation of the contained mutex
246  * fails. (It is often not worth checking for this, as it means
247  * either memory is exhausted or pthread has run out of other
248  * resources to create new mutexes.)
249  * @exception Cgu::PipeError This method might throw Cgu::PipeError if
250  * the contained Notifier object is the first Notifier object in the
251  * program to be constructed and Cgu::Notifier::init() has not
252  * previously been called.
253  */
254  static Cgu::IntrusivePtr<Cgu::FilePrintManager> create_manager(GtkWindow* parent = 0,
255  const std::string& caption = "",
256  const GobjHandle<GdkPixbuf>& window_icon = GobjHandle<GdkPixbuf>(0));
257 
258 /**
259  * Sets the filename of the file to be printed. This method is
260  * thread-safe and may be called in any thread. No GTK+/GDK functions
261  * are called.
262  * @param filename The filename of the file to be printed.
263  * @param manage_file If this argument is set to true, then if print()
264  * returns true, after printing succeeds or fails the file being
265  * printed will be deleted.
266  * @return Returns true, unless the same FilePrintManager object is
267  * being used to print more than one print job and when this method is
268  * called it is already printing another print job (in which case it
269  * returns false).
270  * @exception std::bad_alloc This method might throw std::bad_alloc if
271  * memory is exhausted and the system throws in that case.
272  */
273  bool set_filename(const char* filename, bool manage_file = false);
274 
275 /**
276  * Prints the file set with set_filename(). This method is
277  * thread-safe and may be called in any thread (it hands off its work
278  * to the main program thread via a Cgu::Notifier object), unless the
279  * program by which it is called calls GTK+ directly in more than one
280  * thread and thus employs gdk_threads_enter()/gdk_threads_leave()
281  * (rather than, say, Cgu::Notifier or Cgu::Callback::post()), in
282  * which case it must be called in the main GUI thread only and
283  * surrounded by gdk_threads_enter()/gdk_threads_leave() if called
284  * otherwise than in a GTK+ signal handler. (The best approach
285  * however is for a program only to address GTK+/GDK in the main
286  * program thread, for which purpose this library provides various
287  * functions and classes for inter-thread communication, such as
288  * Cgu::Notifier and Cgu::Callback::post().)
289  * @return Returns true, unless the same FilePrintManager object is
290  * being used to print more than one print job and when this method is
291  * called it is already printing another print job (in which case it
292  * returns false).
293  * @exception std::bad_alloc This method might throw std::bad_alloc if
294  * memory is exhausted and the system throws in that case, but only if
295  * it is called in the main program thread. Otherwise it will not
296  * throw.
297  */
298  bool print();
299 
300 /**
301  * The destructor will not throw. It is thread safe (the
302  * FilePrintManager object may be destroyed in any thread), and does
303  * not call any GTK+/GDK functions.
304  */
306 
307 #ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
309 #endif
310 };
311 
312 } // namespace Cgu
313 
314 #endif // CGU_FILE_PRINTMANAGER_H