c++-gtk-utils
|
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