c++-gtk-utils
file_print_manager.h
Go to the documentation of this file.
1 /* Copyright (C) 2006 to 2018 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 
31 
32 #ifdef CGU_USE_GTK
33 #include <gtk/gtk.h>
34 #include <gdk/gdk.h>
35 #if GTK_CHECK_VERSION(2,14,0)
36 #include <gtk/gtkunixprint.h>
37 #else
38 #include <gtk/gtkprintunixdialog.h>
39 #include <gtk/gtkprintjob.h>
40 #include <gtk/gtkprinter.h>
41 #endif
42 #endif
43 
44 #include <c++-gtk-utils/window.h>
45 #include <c++-gtk-utils/notifier.h>
46 #include <c++-gtk-utils/mutex.h>
49 #include <c++-gtk-utils/emitter.h>
50 
51 
52 namespace Cgu {
53 
54 #if defined(DOXYGEN_PARSING) || defined(CGU_USE_GTK)
55 
56 /**
57  * @class FilePrintDialog file_print_manager.h c++-gtk-utils/file_print_manager.h
58  * @brief A print dialog class for FilePrintManager.
59  * @sa FilePrintManager
60  *
61  * This class is not compiled into the library if the library is built
62  * with the \--without-gtk configuration option.
63  */
64 
65 class FilePrintDialog: public WinBase {
66 protected:
67 /**
68  * Closes the dialog, cleans up and emits the rejected Emitter object.
69  * It will not throw, even if a method connected to the rejected
70  * Emitter object throws (the exception is caught and reported in
71  * order to prevent it trying to propagate through the GTK+ event
72  * system).
73  *
74  * This function is only used where the library is compiled against
75  * GTK+4. Where this library is compiled against GTK+2 or GTK+3, the
76  * on_delete_event() function is used instead.
77  *
78  * Since 2.2.16
79  */
80 #if defined(DOXYGEN_PARSING) || GTK_CHECK_VERSION(3,94,0)
81  virtual void on_close_request();
82 #endif
83 
84 /**
85  * Closes the dialog, cleans up and emits the rejected Emitter object.
86  * It will not throw, even if a method connected to the rejected
87  * Emitter object throws (the exception is caught and reported in
88  * order to prevent it trying to propagate through the GTK+ event
89  * system).
90  *
91  * This function is only used where the library is compiled against
92  * GTK+2 and GTK+3. Where this library is compiled against GTK+4, the
93  * on_close_request() function is used instead.
94  */
95 #if defined(DOXYGEN_PARSING) || !GTK_CHECK_VERSION(3,94,0)
96  virtual void on_delete_event();
97 #endif
98 
99 public:
100 #ifndef DOXYGEN_PARSING
101  // this helper class avoids exposing GObject callbacks with C
102  // linkage to the global namespace
103  class CB;
104  friend class CB;
105 #endif
106 
107 /**
108  * The accepted Emitter object emits if the user choses OK in the
109  * print dialog. Emission of accepted by this class will not throw,
110  * even if a method connected to the accepted Emitter object throws
111  * (the exception is caught and reported in order to prevent it trying
112  * to propagate through the GTK+ event system).
113  */
115 
116 /**
117  * The rejected Emitter object emits if the user choses Cancel in the
118  * print dialog. Emission of rejected by this class will not throw,
119  * even if a method connected to the rejected Emitter object throws
120  * (the exception is caught and reported in order to prevent it trying
121  * to propagate through the GTK+ event system).
122  */
124 
125 /**
126  * Gets the currently selected printer from the print dialog. It will
127  * not throw. It must be called in the thread in which the main GTK+
128  * event loop runs.
129  * @return The currently selected printer in the print dialog. The
130  * return value is owned by GTK+ - do not unreference it.
131  */
132  GtkPrinter* get_printer() const;
133 
134 /**
135  * Gets the print settings from the print dialog. It will not throw.
136  * It must be called in the thread in which the main GTK+ event loop
137  * runs.
138  * @return The currently selected printer in the print dialog.
139  * Ownership is taken of the return value, by GobjHandle.
140  */
142 
143 /**
144  * Gets the printer page set-up from the print dialog. It will not
145  * throw. It must be called in the thread in which the main GTK+
146  * event loop runs.
147  * @return The printer page set-up in the print dialog. The return
148  * value is owned by GTK+ - do not unreference it.
149  */
150  GtkPageSetup* get_page_setup() const;
151 
152 /**
153  * The constructor will not throw. A FIlePrintDialog object must be
154  * created in the thread in which the main GTK+ event loop runs.
155  * @param parent The parent of the print dialog (NULL may be passed).
156  * @param print_settings The print settings from a previous print job
157  * (if any, NULL may be passed if none).
158  * @param caption Window caption (optional, NULL may be passed).
159  * @param window_icon An image which will comprise the window icon
160  * (optional, NULL may be passed). For GTK+ < 3.93 this is of type
161  * GdkPixbuf*. For GTK+ >= 3.93 this is of type GdkTexture*.
162  */
163 #ifdef DOXYGEN_PARSING
164  FilePrintDialog(GtkWindow* parent, GtkPrintSettings* print_settings = 0,
165  const char* caption = 0, GdkPixbuf/GdkTexture* window_icon = 0);
166 #elif GTK_CHECK_VERSION(3,93,0)
167  FilePrintDialog(GtkWindow* parent, GtkPrintSettings* print_settings = 0,
168  const char* caption = 0, GdkTexture* window_icon = 0);
169 #else
170  FilePrintDialog(GtkWindow* parent, GtkPrintSettings* print_settings = 0,
171  const char* caption = 0, GdkPixbuf* window_icon = 0);
172 #endif
173 
174  /* we inherit glib memory slice functions from WinBase */
175 };
176 
177 
178 /**
179  * @class FilePrintManager file_print_manager.h c++-gtk-utils/file_print_manager.h
180  * @brief A class to print a file using the GTK+ print system.
181  *
182  * The FilePrintManager class prints a file printable by the print
183  * system (eg lpr or CUPS) using the GTK+ printer interface. All
184  * print systems on Unix-like systems will print Postscript (PS)
185  * files. Some may also print PDF files. To obtain a
186  * FilePrintManager object, call FilePrintManager::create_manager().
187  * FilePrintManager::set_filename() passes the name of the file to be
188  * printed. To print the file, call FilePrintManager::print(). If
189  * FilePrintManager::print() returns true, the FilePrintManager class
190  * will unlink() (ie delete) the file to be printed when it has been
191  * finished with if true is passed as the second argument of
192  * FilePrintManager::set_filename(), even if printing failed.
193  *
194  * Once FilePrintManager::print() has been called, the
195  * FilePrintManager class owns a reference to itself and so manages
196  * its own lifetime - so once that method has been called it doesn't
197  * matter if the IntrusivePtr object returned by
198  * FilePrintManager::create_manager() goes out of scope (however, once
199  * FilePrintManager::print() has been called, the FilePrintManager
200  * object will not be deleted until both printing has completed or
201  * failed AND the IntrusivePtr object returned by
202  * FilePrintManager::create_manager() has gone out of scope or has
203  * been reset()).
204  *
205  * If the print dialog which is displayed on calling
206  * FilePrintManager::print() is to display a window icon, then pass
207  * FilePrintManager::create_manager() a GobjHandle<GdkPixbuf> icon as
208  * the second argument.
209  *
210  * Normally, a user would probably only want to use any one
211  * FilePrintManager object to print a single print job (it has been
212  * designed with that in mind). Nevertheless, if a reference to the
213  * object is kept alive via an active IntrusivePtr object, it can be
214  * used to print more than one print job. However, if that is done it
215  * is not possible to call FilePrintManager::print() or
216  * FilePrintManager::set_filename() until the previous print job (if
217  * any) has been dispatched to the GTK+ print system (or cancelled).
218  * If the FilePrintManager object is not ready because it is in the
219  * middle of handling an earlier print job, then the call to
220  * FilePrintManager::print() or FilePrintManager::set_filename() will
221  * return false; if however the new print job was successfully started
222  * or file name successfully set, they will return true. It is not
223  * necessary to check the return value of these methods for the first
224  * print job despatched by any one FilePrintManager object.
225  *
226  * For printing plain text (say, from a GtkTextBuffer class, or from a
227  * plain text file), see the TextPrintManager class.
228  *
229  * This class is not compiled into the library if the library is built
230  * with the \--without-gtk configuration option.
231  */
232 
234  Thread::Mutex mutex;
235  GtkWindow* parent_p;
236  std::string caption;
237 #if GTK_CHECK_VERSION(3,93,0)
238  GobjHandle<GdkTexture> window_icon_h;
239 #else
240  GobjHandle<GdkPixbuf> window_icon_h;
241 #endif
242  bool manage;
243  std::string filename;
244  FilePrintDialog* dialog_p;
245  Notifier print_notifier;
246  bool ready;
247 
248  static GobjHandle<GtkPrintSettings> print_settings_h;
249 
250  void show_dialog();
251  void print_file();
252  void print_cancel();
253  void clean_up();
254  // private constructor
255  FilePrintManager() {}
256 public:
257 #ifndef DOXYGEN_PARSING
258  // this helper class avoids exposing GObject callbacks with C
259  // linkage to the global namespace
260  class CB;
261  friend class CB;
262 #endif
263 /**
264  * This class cannot be copied: it is intended to be held by
265  * IntrusivePtr. The copy constructor is deleted.
266  */
267  FilePrintManager(const FilePrintManager&) = delete;
268 
269 /**
270  * This class cannot be copied: it is intended to be held by
271  * IntrusivePtr. The assignment operator is deleted.
272  */
273  FilePrintManager& operator=(const FilePrintManager&) = delete;
274 
275 /**
276  * Creates a new FilePrintManager object. No GTK+/GDK functions are
277  * called by this method, and it is thread safe provided that, if it
278  * is called in a thread other than the one in which the GTK+ event
279  * loop runs, Cgu::Notifier::init() has previously been called in the
280  * GTK+ event loop thread.
281  * @param parent The parent of the print dialog which will be created
282  * by the FilePrintManager object (optional, NULL may be passed).
283  * @param caption Window caption of the print dialog which will be
284  * created by the FilePrintManager object (optional, an empty string
285  * may be passed).
286  * @param window_icon An image which will comprise the window icon of
287  * the print dialog which will be created by the FilePrintManager
288  * object (optional, an empty GobjHandle object may be passed). For
289  * GTK+ < 3.93 this is of type GobjHandle<GdkPixbuf>. For GTK+ >=
290  * 3.93 this is of type GobjHandle<GdkTexture>.
291  * @exception std::bad_alloc This method might throw std::bad_alloc if
292  * memory is exhausted and the system throws in that case.
293  * @exception Cgu::Thread::MutexError This method might throw
294  * Cgu::Thread::MutexError if initialisation of the contained mutex
295  * fails. (It is often not worth checking for this, as it means
296  * either memory is exhausted or pthread has run out of other
297  * resources to create new mutexes.)
298  * @exception Cgu::PipeError This method might throw Cgu::PipeError if
299  * the contained Notifier object is the first Notifier object in the
300  * program to be constructed and Cgu::Notifier::init() has not
301  * previously been called.
302  */
303 #ifdef DOXYGEN_PARSING
304  static Cgu::IntrusivePtr<Cgu::FilePrintManager> create_manager(GtkWindow* parent = 0,
305  const std::string& caption = "",
307 #elif GTK_CHECK_VERSION(3,93,0)
308  static Cgu::IntrusivePtr<Cgu::FilePrintManager> create_manager(GtkWindow* parent = 0,
309  const std::string& caption = "",
310  const GobjHandle<GdkTexture>& window_icon = GobjHandle<GdkTexture>(0));
311 #else
312  static Cgu::IntrusivePtr<Cgu::FilePrintManager> create_manager(GtkWindow* parent = 0,
313  const std::string& caption = "",
314  const GobjHandle<GdkPixbuf>& window_icon = GobjHandle<GdkPixbuf>(0));
315 #endif
316 
317 /**
318  * Sets the filename of the file to be printed. This method is
319  * thread-safe and may be called in any thread. No GTK+/GDK functions
320  * are called.
321  * @param filename The filename of the file to be printed.
322  * @param manage_file If this argument is set to true, then if print()
323  * returns true, after printing succeeds or fails the file being
324  * printed will be deleted.
325  * @return Returns true, unless the same FilePrintManager object is
326  * being used to print more than one print job and when this method is
327  * called it is already printing another print job (in which case it
328  * returns false).
329  * @exception std::bad_alloc This method might throw std::bad_alloc if
330  * memory is exhausted and the system throws in that case.
331  */
332  bool set_filename(const char* filename, bool manage_file = false);
333 
334 /**
335  * Prints the file set with set_filename(). This method is
336  * thread-safe and may be called in any thread (it hands off its work
337  * to the main program thread via a Cgu::Notifier object), unless the
338  * program by which it is called calls GTK+ directly in more than one
339  * thread and thus employs gdk_threads_enter()/gdk_threads_leave()
340  * (rather than, say, Cgu::Notifier or Cgu::Callback::post()), in
341  * which case it must be called in the main GUI thread only and
342  * surrounded by gdk_threads_enter()/gdk_threads_leave() if called
343  * otherwise than in a GTK+ signal handler. (The best approach
344  * however is for a program only to address GTK+/GDK in the main
345  * program thread, for which purpose this library provides various
346  * functions and classes for inter-thread communication, such as
347  * Cgu::Notifier and Cgu::Callback::post().)
348  * @return Returns true, unless the same FilePrintManager object is
349  * being used to print more than one print job and when this method is
350  * called it is already printing another print job (in which case it
351  * returns false).
352  * @exception std::bad_alloc This method might throw std::bad_alloc if
353  * memory is exhausted and the system throws in that case, but only if
354  * it is called in the main program thread. Otherwise it will not
355  * throw.
356  */
357  bool print();
358 
359 /**
360  * The destructor will not throw. It is thread safe (the
361  * FilePrintManager object may be destroyed in any thread), and does
362  * not call any GTK+/GDK functions.
363  */
365 
366 #ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
368 #endif
369 };
370 
371 #endif // CGU_USE_GTK
372 
373 } // namespace Cgu
374 
375 #endif // CGU_FILE_PRINTMANAGER_H
FilePrintManager & operator=(const FilePrintManager &)=delete
FilePrintDialog(GtkWindow *parent, GtkPrintSettings *print_settings=0, const char *caption=0, GdkPixbuf/GdkTexture *window_icon=0)
Emitter accepted
Definition: file_print_manager.h:114
virtual void on_delete_event()
Provides thread-safe signalling between a worker thread and the main program thread.
Definition: notifier.h:214
This is a smart pointer for managing objects allocated on freestore which maintain their own referenc...
Definition: intrusive_ptr.h:98
static Cgu::IntrusivePtr< Cgu::FilePrintManager > create_manager(GtkWindow *parent=0, const std::string &caption="", const GobjHandle< GdkPixbuf/GdkTexture > &window_icon=GobjHandle< GdkPixbuf/GdkTexture >(0))
Emitter rejected
Definition: file_print_manager.h:123
This is a class for managing the lifetime of top level widgets.
Definition: window.h:227
A wrapper class for pthread mutexes.
Definition: mutex.h:117
A print dialog class for FilePrintManager.
Definition: file_print_manager.h:65
This is a counter class providing the ref() and unref() functions required by IntrusivePtr, with a thread safe reference count..
Definition: intrusive_ptr.h:349
This file provides a thread-safe signal/slot mechanism, with automatic disconnection.
Provides wrapper classes for pthread mutexes and condition variables, and scoped locking classes for ...
Definition: application.h:44
virtual void on_close_request()
bool set_filename(const char *filename, bool manage_file=false)
A class to print a file using the GTK+ print system.
Definition: file_print_manager.h:233
A class to execute callbacks connected to it, with provision for automatic disconnection.
Definition: emitter.h:326
GobjHandle< GtkPrintSettings > get_settings() const
GtkPrinter * get_printer() const
GtkPageSetup * get_page_setup() const
#define CGU_GLIB_MEMORY_SLICES_FUNCS
Definition: cgu_config.h:84
This file provides a Notifier class to provide thread-safe signalling between a worker thread and the...