c++-gtk-utils

file_print_manager.h

Go to the documentation of this file.
00001 /* Copyright (C) 2006 to 2011 Chris Vine
00002 
00003 The library comprised in this file or of which this file is part is
00004 distributed by Chris Vine under the GNU Lesser General Public
00005 License as follows:
00006 
00007    This library is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Lesser General Public License
00009    as published by the Free Software Foundation; either version 2.1 of
00010    the License, or (at your option) any later version.
00011 
00012    This library is distributed in the hope that it will be useful, but
00013    WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015    Lesser General Public License, version 2.1, for more details.
00016 
00017    You should have received a copy of the GNU Lesser General Public
00018    License, version 2.1, along with this library (see the file LGPL.TXT
00019    which came with this source code package in the c++-gtk-utils
00020    sub-directory); if not, write to the Free Software Foundation, Inc.,
00021    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00022 
00023 */
00024 
00025 #ifndef CGU_FILE_PRINTMANAGER_H
00026 #define CGU_FILE_PRINTMANAGER_H
00027 
00028 #include <string>
00029 
00030 #include <gtk/gtk.h>
00031 #include <gdk/gdk.h>
00032 #if GTK_CHECK_VERSION(2,14,0)
00033 #include <gtk/gtkunixprint.h>
00034 #else
00035 #include <gtk/gtkprintunixdialog.h>
00036 #include <gtk/gtkprintjob.h>
00037 #include <gtk/gtkprinter.h>
00038 #endif
00039 
00040 
00041 #include <c++-gtk-utils/window.h>
00042 #include <c++-gtk-utils/notifier.h>
00043 #include <c++-gtk-utils/mutex.h>
00044 #include <c++-gtk-utils/gobj_handle.h>
00045 #include <c++-gtk-utils/intrusive_ptr.h>
00046 #include <c++-gtk-utils/emitter.h>
00047 #include <c++-gtk-utils/cgu_config.h>
00048 
00049 
00050 namespace Cgu {
00051 
00052 /**
00053  * @class FilePrintDialog file_print_manager.h c++-gtk-utils/file_print_manager.h
00054  * @brief A print dialog class for FilePrintManager.
00055  * @sa FilePrintManager
00056  */
00057 
00058 class FilePrintDialog: public WinBase {
00059 protected:
00060 /**
00061  * Closes the dialog, cleans up and emits the rejected Emitter object.
00062  * It will not throw, even if a method connected to the rejected
00063  * Emitter object throws (the exception is caught and reported in
00064  * order to prevent it trying to propagate through the GTK+ event
00065  * system).
00066  */
00067   virtual void on_delete_event();
00068 public:
00069 #ifndef DOXYGEN_PARSING
00070   // this helper class avoids exposing GObject callbacks with C
00071   // linkage to the global namespace
00072   class CB;
00073   friend class CB;
00074 #endif
00075 
00076 /**
00077  * The accepted Emitter object emits if the user choses OK in the
00078  * print dialog.  Emission of accepted by this class will not throw,
00079  * even if a method connected to the accepted Emitter object throws
00080  * (the exception is caught and reported in order to prevent it trying
00081  * to propagate through the GTK+ event system).
00082  */
00083   Emitter accepted;
00084 
00085 /**
00086  * The rejected Emitter object emits if the user choses Cancel in the
00087  * print dialog.  Emission of rejected by this class will not throw,
00088  * even if a method connected to the rejected Emitter object throws
00089  * (the exception is caught and reported in order to prevent it trying
00090  * to propagate through the GTK+ event system).
00091  */
00092   Emitter rejected;
00093 
00094 /**
00095  * Gets the currently selected printer from the print dialog.  It will
00096  * not throw.  It must be called in the thread in which the main GTK+
00097  * event loop runs.
00098  * @return The currently selected printer in the print dialog.  The
00099  * return value is owned by GTK+ - do not unreference it.
00100  */
00101   GtkPrinter* get_printer() const;
00102 
00103 /**
00104  * Gets the print settings from the print dialog.  It will not throw.
00105  * It must be called in the thread in which the main GTK+ event loop
00106  * runs.
00107  * @return The currently selected printer in the print dialog.
00108  * Ownership is taken of the return value, by GobjHandle.
00109  */
00110   GobjHandle<GtkPrintSettings> get_settings() const;
00111 
00112 /**
00113  * Gets the printer page set-up from the print dialog.  It will not
00114  * throw.  It must be called in the thread in which the main GTK+
00115  * event loop runs.
00116  * @return The printer page set-up in the print dialog.  The return
00117  * value is owned by GTK+ - do not unreference it.
00118  */
00119   GtkPageSetup* get_page_setup() const;
00120 
00121 /**
00122  * The constructor will not throw.  A FIlePrintDialog object must be
00123  * created in the thread in which the main GTK+ event loop runs.
00124  * @param parent The parent of the print dialog (NULL may be passed).
00125  * @param print_settings The print settings from a previous print job
00126  * (if any, NULL may be passed if none).
00127  * @param caption Window caption (optional, NULL may be passed).
00128  * @param window_icon A pixbuf which will comprise the window icon
00129  * (optional, NULL may be passed).
00130  */
00131   FilePrintDialog(GtkWindow* parent, GtkPrintSettings* print_settings = 0,
00132                   const char* caption = 0, GdkPixbuf* window_icon = 0);
00133 
00134   /* we inherit glib memory slice functions from WinBase */
00135 };
00136 
00137 
00138 /**
00139  * @class FilePrintManager file_print_manager.h c++-gtk-utils/file_print_manager.h
00140  * @brief A class to print a file using the GTK+ print system.
00141  *
00142  * The FilePrintManager class prints a file printable by the print
00143  * system (eg lpr or CUPS) using the GTK+ printer interface.  All
00144  * print systems on Unix-like systems will print Postscript (PS)
00145  * files.  Some may also print PDF files.  To obtain a
00146  * FilePrintManager object, call FilePrintManager::create_manager().
00147  * FilePrintManager::set_filename() passes the name of the file to be
00148  * printed.  To print the file, call FilePrintManager::print().  If
00149  * FilePrintManager::print() returns true, the FilePrintManager class
00150  * will unlink() (ie delete) the file to be printed when it has been
00151  * finished with if true is passed as the second argument of
00152  * FilePrintManager::set_filename(), even if printing failed.
00153  *
00154  * Once FilePrintManager::print() has been called, the
00155  * FilePrintManager class owns a reference to itself and so manages
00156  * its own lifetime - so once that method has been called it doesn't
00157  * matter if the IntrusivePtr object returned by
00158  * FilePrintManager::create_manager() goes out of scope (however, once
00159  * FilePrintManager::print() has been called, the FilePrintManager
00160  * object will not be deleted until both printing has completed or
00161  * failed AND the IntrusivePtr object returned by
00162  * FilePrintManager::create_manager() has gone out of scope or has
00163  * been reset()).
00164  *
00165  * If the print dialog which is displayed on calling
00166  * FilePrintManager::print() is to display a window icon, then pass
00167  * FilePrintManager::create_manager() a GobjHandle<GdkPixbuf> icon as
00168  * the second argument.
00169  *
00170  * Normally, a user would probably only want to use any one
00171  * FilePrintManager object to print a single print job (it has been
00172  * designed with that in mind).  Nevertheless, if a reference to the
00173  * object is kept alive via an active IntrusivePtr object, it can be
00174  * used to print more than one print job.  However, if that is done it
00175  * is not possible to call FilePrintManager::print() or
00176  * FilePrintManager::set_filename() until the previous print job (if
00177  * any) has been dispatched to the GTK+ print system (or cancelled).
00178  * If the FilePrintManager object is not ready because it is in the
00179  * middle of handling an earlier print job, then the call to
00180  * FilePrintManager::print() or FilePrintManager::set_filename() will
00181  * return false; if however the new print job was successfully started
00182  * or file name successfully set, they will return true.  It is not
00183  * necessary to check the return value of these methods for the first
00184  * print job despatched by any one FilePrintManager object.
00185  *
00186  * For printing plain text (say, from a GtkTextBuffer class, or from a
00187  * plain text file), see the TextPrintManager class.
00188 */
00189 
00190 class FilePrintManager: public IntrusiveLockCounter {
00191   Thread::Mutex mutex;
00192   GtkWindow* parent_p;
00193   std::string caption;
00194   GobjHandle<GdkPixbuf> window_icon_h;
00195   bool manage;
00196   std::string filename;
00197   FilePrintDialog* dialog_p;
00198   Notifier print_notifier;
00199   bool ready;
00200 
00201   static GobjHandle<GtkPrintSettings> print_settings_h;
00202 
00203   void show_dialog();
00204   void print_file();
00205   void print_cancel();
00206   void clean_up();
00207   // private constructor
00208   FilePrintManager() {}
00209 public:
00210 #ifndef DOXYGEN_PARSING
00211   // this helper class avoids exposing GObject callbacks with C
00212   // linkage to the global namespace
00213   class CB;
00214   friend class CB;
00215 #endif
00216 /**
00217  * This class cannot be copied: it is intended to be held by
00218  * IntrusivePtr.  The copy constructor is deleted.
00219  */
00220   FilePrintManager(const FilePrintManager&) = delete;
00221 
00222 /**
00223  * This class cannot be copied: it is intended to be held by
00224  * IntrusivePtr.  The assignment operator is deleted.
00225  */
00226   FilePrintManager& operator=(const FilePrintManager&) = delete;
00227 
00228 /**
00229  * Creates a new FilePrintManager object.  No GTK+/GDK functions are
00230  * called by this method, and it is thread safe provided that, if it
00231  * is called in a thread other than the one in which the GTK+ event
00232  * loop runs, Cgu::Notifier::init() has previously been called in the
00233  * GTK+ event loop thread.
00234  * @param parent The parent of the print dialog which will be created
00235  * by the FilePrintManager object (optional, NULL may be passed).
00236  * @param caption Window caption of the print dialog which will be
00237  * created by the FilePrintManager object (optional, an empty string
00238  * may be passed).
00239  * @param window_icon A pixbuf which will comprise the window icon of
00240  * the print dialog which will be created by the FilePrintManager
00241  * object (optional, an empty GobjHandle object may be passed).
00242  * @exception std::bad_alloc This method might throw std::bad_alloc if
00243  * memory is exhausted and the system throws in that case.
00244  * @exception Cgu::Thread::MutexError This method might throw
00245  * Cgu::Thread::MutexError if initialisation of the contained mutex
00246  * fails.  (It is often not worth checking for this, as it means
00247  * either memory is exhausted or pthread has run out of other
00248  * resources to create new mutexes.)
00249  * @exception Cgu::PipeError This method might throw Cgu::PipeError if
00250  * the contained Notifier object is the first Notifier object in the
00251  * program to be constructed and Cgu::Notifier::init() has not
00252  * previously been called.
00253  */
00254   static Cgu::IntrusivePtr<Cgu::FilePrintManager> create_manager(GtkWindow* parent = 0,
00255                                                                  const std::string& caption = "",
00256                                                                  const GobjHandle<GdkPixbuf>& window_icon = GobjHandle<GdkPixbuf>(0));
00257 
00258 /**
00259  * Sets the filename of the file to be printed.  This method is
00260  * thread-safe and may be called in any thread.  No GTK+/GDK functions
00261  * are called.
00262  * @param filename The filename of the file to be printed.
00263  * @param manage_file If this argument is set to true, then if print()
00264  * returns true, after printing succeeds or fails the file being
00265  * printed will be deleted.
00266  * @return Returns true, unless the same FilePrintManager object is
00267  * being used to print more than one print job and when this method is
00268  * called it is already printing another print job (in which case it
00269  * returns false).
00270  * @exception std::bad_alloc This method might throw std::bad_alloc if
00271  * memory is exhausted and the system throws in that case.
00272  */
00273   bool set_filename(const char* filename, bool manage_file = false);
00274 
00275 /**
00276  * Prints the file set with set_filename().  This method is
00277  * thread-safe and may be called in any thread (it hands off its work
00278  * to the main program thread via a Cgu::Notifier object), unless the
00279  * program by which it is called calls GTK+ directly in more than one
00280  * thread and thus employs gdk_threads_enter()/gdk_threads_leave()
00281  * (rather than, say, Cgu::Notifier or Cgu::Callback::post()), in
00282  * which case it must be called in the main GUI thread only and
00283  * surrounded by gdk_threads_enter()/gdk_threads_leave() if called
00284  * otherwise than in a GTK+ signal handler.  (The best approach
00285  * however is for a program only to address GTK+/GDK in the main
00286  * program thread, for which purpose this library provides various
00287  * functions and classes for inter-thread communication, such as
00288  * Cgu::Notifier and Cgu::Callback::post().)
00289  * @return Returns true, unless the same FilePrintManager object is
00290  * being used to print more than one print job and when this method is
00291  * called it is already printing another print job (in which case it
00292  * returns false).
00293  * @exception std::bad_alloc This method might throw std::bad_alloc if
00294  * memory is exhausted and the system throws in that case, but only if
00295  * it is called in the main program thread.  Otherwise it will not
00296  * throw.
00297  */
00298   bool print();
00299 
00300 /**
00301  * The destructor will not throw.  It is thread safe (the
00302  * FilePrintManager object may be destroyed in any thread), and does
00303  * not call any GTK+/GDK functions.
00304  */
00305   ~FilePrintManager();
00306 
00307 #ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
00308   CGU_GLIB_MEMORY_SLICES_FUNCS
00309 #endif
00310 };
00311 
00312 } // namespace Cgu
00313 
00314 #endif // CGU_FILE_PRINTMANAGER_H