c++-gtk-utils
|
00001 /* Copyright (C) 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_APPLICATION_H 00026 #define CGU_APPLICATION_H 00027 00028 #include <list> 00029 #include <exception> 00030 #include <utility> 00031 00032 #include <gio/gio.h> 00033 #include <gtk/gtk.h> 00034 00035 #include <c++-gtk-utils/gobj_handle.h> 00036 #include <c++-gtk-utils/window.h> 00037 #include <c++-gtk-utils/emitter.h> 00038 #include <c++-gtk-utils/cgu_config.h> 00039 00040 namespace Cgu { 00041 00042 #if defined(DOXYGEN_PARSING) || GTK_CHECK_VERSION(2,99,0) 00043 00044 /** 00045 * @class Cgu::ApplicationNameError application.h c++-gtk-utils/application.h 00046 * @brief This class is thrown when the program id name passed to the 00047 * constructor of Cgu::Application is invalid. 00048 */ 00049 struct ApplicationNameError: public std::exception { 00050 virtual const char* what() const throw() {return "ApplicationNameError\n";} 00051 }; 00052 00053 /** 00054 * @class Cgu::Application application.h c++-gtk-utils/application.h 00055 * @brief This is a class for constructing and managing GtkApplication 00056 * objects. 00057 * 00058 * @details It is available since version 2.0.0-rc2. It is only 00059 * compiled in with a GTK+3 installation. 00060 * 00061 * In typical usage, a Cgu::Application object is created in main(), 00062 * and then a callback is attached to the 'activate', 'command_line' 00063 * or 'open' emitter, depending on the flag passed to the Application 00064 * object's constructor. The run() method of the Application object 00065 * is then called, and a window deriving from Cgu::WinBase is 00066 * constructed in the callback and added to the Application object or, 00067 * if the program is a single instance program with only one main 00068 * window and an instance is already running, a function is called to 00069 * present that window. 00070 * 00071 * The gio/gtk+ documentation at the time of writing does not explain 00072 * key concepts, and in particular how the GtkApplication sub-class 00073 * interacts with GApplication's g_application_run(). Here is an 00074 * explanation: 00075 * 00076 * (a) If a Cgu::Application object is constructed with the 00077 * G_APPLICATION_FLAGS_NONE flag set, then calling the 00078 * Cgu::Application::run() method (which hands off to 00079 * g_application_run()) will cause the 'activate' emitter to emit. No 00080 * command line parameter should be passed to the run method (argc 00081 * should be 0 or 1), otherwise GtkApplication will cause the start-up 00082 * to abort. Unlike with gtk_main(), g_application_run() (and so 00083 * Cgu::Application::run()) does not consume any recognised glib/gtk+ 00084 * options, such as --display, but regards these as application 00085 * parameters. Such stripping out can be achieved by calling 00086 * gtk_init() before constructing the Cgu::Application object (but 00087 * gtk_init() does not need to be called for any other purpose), or by 00088 * using the GOptionGroup/GOptionEntry interface. 00089 * g_application_run(), and so Cgu::Application::run(), can be called 00090 * with argc and argv set to 0, and that is generally the best 00091 * approach if the G_APPLICATION_FLAGS_NONE flag is set. 00092 * 00093 * (b) If a Cgu::Application object is constructed with the 00094 * G_APPLICATION_HANDLES_OPEN flag set, then calling the 00095 * Cgu::Application::run() method will cause the 'activate' emitter to 00096 * emit if no command line parameters were provided when the program 00097 * was started (that is, if argc is 0 or 1), or cause the 'open' 00098 * emitter to emit if parameters are passed (argc > 1). Such 00099 * parameters will be construed as files/uris, and will be passed to 00100 * the 'open' emitter by array of GFile*'s. Unlike with gtk_main(), 00101 * g_application_run() (and so Cgu::Application::run()) does not 00102 * consume any recognised glib/gtk+ options, such as --display, but 00103 * regards these as application parameters and so as file/uri names. 00104 * Such stripping out can be achieved by calling gtk_init() before 00105 * constructing the Cgu::Application object (but gtk_init() does not 00106 * need to be called for any other purpose), or by using the 00107 * GOptionGroup/GOptionEntry interface. 00108 * 00109 * (c) If a Cgu::Application object is constructed with the 00110 * G_APPLICATION_HANDLES_COMMAND_LINE flag set, then calling the 00111 * Cgu::Application::run() method will cause the 'command_line' 00112 * emitter to emit. All the command line parameters will be passed 00113 * on, and they can be obtained via the GApplicationCommandLine 00114 * argument of the 'command_line' emitter. Unlike with gtk_main(), 00115 * g_application_run() (and so Cgu::Application::run()) does not 00116 * consume any recognised glib/gtk+ options, such as --display, but 00117 * regards these as command line parameters. Such stripping out can 00118 * be achieved by calling gtk_init() before constructing the 00119 * Cgu::Application object (but gtk_init() does not need to be called 00120 * for any other purpose), or by using the GOptionGroup/GOptionEntry 00121 * interface. 00122 * 00123 * There is little in this class that cannot also be done using the 00124 * @ref prog_presenterAnchor "Cgu::prog_present" interface, which has 00125 * the advantage of being more portable (@ref prog_presenterAnchor 00126 * "Cgu::prog_present" does not depend on GTK+3), but this class is 00127 * more convenient to use where a program requires multiple main 00128 * application windows which can be independently opened and any of 00129 * which are to keep the program alive until the last one is closed. 00130 * 00131 * Cgu::Application objects are not singletons. It is possible to 00132 * drop an Application object out of scope or destroy it in some other 00133 * way after closing or removing all its windows, then construct 00134 * another with a different flag and then call run() on the second one 00135 * (although it would be a curious application that wanted to do so). 00136 * It is also possible, but even more off-the-wall, to have two 00137 * Application objects in existence in the same process at the same 00138 * time provided different dbus identifiers are supplied to the 00139 * constructor for each, although run() may only be called on one of 00140 * them at any one time. However, this is something of a curiosity: 00141 * in nearly all cases an application will only have one 00142 * Cgu::Application object, since the main purpose of Cgu::Application 00143 * is to facilitate single instance programs. 00144 * 00145 * Cgu::WinBase objects, and so Cgu::Application, can be used with 00146 * widget heirarchies or top level windows created using GtkBuilder. 00147 * See @ref GtkBuilder for particulars about that. 00148 * 00149 * Here is a compilable example, demonstrating the use of the 00150 * GApplicationFlags options: 00151 * 00152 * @code 00153 * #include <iostream> 00154 * #include <ostream> 00155 * #include <string> 00156 * 00157 * #include <gtk/gtk.h> 00158 * 00159 * #include <c++-gtk-utils/callback.h> 00160 * #include <c++-gtk-utils/application.h> 00161 * #include <c++-gtk-utils/window.h> 00162 * #include <c++-gtk-utils/shared_handle.h> 00163 * 00164 * // SETUP HERE: uncomment the flag to be tested: 00165 * 00166 * //const GApplicationFlags app_flag = G_APPLICATION_FLAGS_NONE; 00167 * const GApplicationFlags app_flag = G_APPLICATION_HANDLES_OPEN; 00168 * //const GApplicationFlags app_flag = G_APPLICATION_HANDLES_COMMAND_LINE; 00169 * 00170 * using namespace Cgu; 00171 * 00172 * // *** Demonstration message class *** 00173 * 00174 * extern "C" void message_button_clicked(GtkWidget*, void*); 00175 * 00176 * class Message: public Cgu::WinBase { 00177 * public: 00178 * friend void message_button_clicked(GtkWidget*, void*); 00179 * Message(const char* text); 00180 * }; 00181 * 00182 * void message_button_clicked(GtkWidget* w, void*) { 00183 * std::cout << "Clicked" << std::endl; 00184 * } 00185 * 00186 * Message::Message(const char* text): WinBase{"Message", 0, false} { 00187 * GtkWidget* box = gtk_vbox_new(false, 2); 00188 * gtk_container_add(GTK_CONTAINER(get_win()), box); 00189 * GtkWidget* label = gtk_label_new(text); 00190 * gtk_box_pack_start(GTK_BOX(box), label, 00191 * true, false, 0); 00192 * GtkWidget* button_box = gtk_hbutton_box_new(); 00193 * gtk_box_pack_start(GTK_BOX(box), button_box, 00194 * false, false, 0); 00195 * GtkWidget* button = gtk_button_new_from_stock(GTK_STOCK_OK); 00196 * gtk_container_add(GTK_CONTAINER(button_box), button); 00197 * g_signal_connect(G_OBJECT(button), "clicked", 00198 * G_CALLBACK(message_button_clicked), 0); 00199 * gtk_widget_set_can_default(button, true); 00200 * } 00201 * 00202 * // *** callbacks *** 00203 * 00204 * void activate(Cgu::Application* app) { 00205 * std::cout << "activate() called" << std::endl; 00206 * 00207 * // probably if no arguments are passed, only one window is wanted, 00208 * // which is now to present itself if it already exists: comment this 00209 * // 'if' block out if a new window is to be added on each occasion 00210 * // the program is started 00211 * if (app->get_win_count() > 0) { 00212 * gtk_window_present(app->get_windows().front()->get_win()); 00213 * return; 00214 * } 00215 * WinBase* dialog = new Message("This is a message"); 00216 * app->add(dialog); 00217 * dialog->show_all(); 00218 * } 00219 * 00220 * void startup(Cgu::Application*) { 00221 * std::cout << "startup() called" << std::endl; 00222 * } 00223 * 00224 * void command_line(Cgu::Application* app, GApplicationCommandLine* cl, gint&) { 00225 * std::cout << "command_line() called" << std::endl; 00226 * 00227 * // probably if the G_APPLICATION_HANDLES_COMMAND_LINE flag is set, 00228 * // only one window is wanted, which is now to present itself if it 00229 * // already exists: comment this 'if' block out if a new window is to 00230 * // be added on each occasion the program is started 00231 * if (app->get_win_count() > 0) { 00232 * gtk_window_present(app->get_windows().front()->get_win()); 00233 * return; 00234 * } 00235 * std::string text("Command line options are:\n"); 00236 * int argc = 0; 00237 * gchar** argv = g_application_command_line_get_arguments(cl, &argc); 00238 * for (int count = 0; count < argc; ++count) { 00239 * try { 00240 * text += argv[count]; 00241 * text += '\n'; 00242 * } 00243 * catch (...) { 00244 * g_strfreev(argv); 00245 * throw; // exceptions will be consumed by the callback handler and 00246 * // a g_critical warning issued, but let's not leak memory 00247 * } 00248 * } 00249 * g_strfreev(argv); 00250 * WinBase* dialog = new Message(text.c_str()); 00251 * app->add(dialog); 00252 * dialog->show_all(); 00253 * } 00254 * 00255 * void open(Cgu::Application* app, std::pair<GFile**, gint> files, gchar*) { 00256 * std::cout << "open() called" << std::endl; 00257 * 00258 * // probably if the G_APPLICATION_HANDLES_OPEN flag is set and an 00259 * // argument is passed, the adding of a new window is wanted on each 00260 * // occasion the program is started 00261 * std::string text("Files are:\n"); 00262 * for (int count = 0; count < files.second; ++count) { 00263 * GcharScopedHandle uri(g_file_get_uri(files.first[count])); 00264 * text += uri; 00265 * text += '\n'; 00266 * } 00267 * WinBase* dialog = new Message(text.c_str()); 00268 * app->add(dialog); 00269 * dialog->show_all(); 00270 * } 00271 * 00272 * // *** main() *** 00273 * 00274 * int main(int argc, char* argv[]) { 00275 * 00276 * // gtk_init() is only relevant for the purposes of stripping out 00277 * // glib/gtk+ recognised options - gtk_application_new() (and so the 00278 * // Cgu::Application constructor) will call g_type_init() if the type 00279 * // system needs initialization 00280 * gtk_init(&argc, &argv); 00281 * 00282 * Application app{"my_prog", app_flag}; 00283 * app.activate.connect(Callback::make(activate)); 00284 * app.startup.connect(Callback::make(startup)); 00285 * app.command_line.connect(Callback::make(command_line)); 00286 * app.open.connect(Callback::make(open)); 00287 * if (app_flag == G_APPLICATION_FLAGS_NONE) 00288 * app.run(0, 0); 00289 * else 00290 * app.run(argc, argv); 00291 * 00292 * return 0; 00293 * } 00294 * @endcode 00295 * 00296 * One thing to note about this example is that the callbacks 00297 * connected to the Cgu::Application object always execute in the 00298 * first instance of the program to be started (the instance in which 00299 * Cgu::Application::run() blocks). If the program is then restarted, 00300 * Cgu::Application::run() returns in the new program instance as soon 00301 * as it has invoked the existing instance via dbus, following which 00302 * the new program instance exits, so immediately disposing of the 00303 * Cgu::Application object and callbacks which were constructed on the 00304 * restart. This is a feature of GApplication/GtkApplication: given 00305 * the overhead of starting a new process, and that restarting a 00306 * single-instance program is in any event an exceptional event, any 00307 * additional overhead created by constructing and then destroying the 00308 * Cgu::Application object and callbacks in the new instance is 00309 * trivial. 00310 */ 00311 00312 class Application { 00313 00314 std::list<WinBase*> win_list; 00315 GobjHandle<GtkApplication> app; 00316 00317 void* reserved; // for future use 00318 public: 00319 00320 typedef std::list<WinBase*>::size_type size_type; 00321 00322 /** 00323 * This class cannot be copied. The copy constructor is deleted. 00324 */ 00325 Application(const Application&) = delete; 00326 00327 /** 00328 * This class cannot be copied. The assignment operator is deleted. 00329 */ 00330 Application& operator=(const Application&) = delete; 00331 00332 /** 00333 * This SafeEmitterArg object emits (and so executes any connected 00334 * callback) when the underlying GApplication object emits its 00335 * @a activate signal. The argument passed to the emitter's 00336 * callback(s) is a pointer to the Cgu::Application object. 00337 * @note When the callback executes, thread cancellation is blocked, 00338 * and any exceptions are consumed with a g_critical message issued. 00339 * The callback will always execute in the main GUI thread when 00340 * executed in response to the run() method. Because a SafeEmitterArg 00341 * object is used, the emitter object itself is thread safe. 00342 * 00343 * Since 2.0.0-rc2 00344 */ 00345 Cgu::SafeEmitterArg<Cgu::Application*> activate; 00346 00347 /** 00348 * This SafeEmitterArg object emits (and so executes any connected 00349 * callback) when the underlying GApplication object emits its 00350 * @a startup signal. The argument passed to the emitter's callback(s) 00351 * is a pointer to the Cgu::Application object. However, you usually 00352 * won't need to do anything in response to the @a startup signal. 00353 * @note When the callback executes, thread cancellation is blocked, 00354 * and any exceptions are consumed with a g_critical message issued. 00355 * The callback will always execute in the main GUI thread when 00356 * executed in response to the run() method. Because a SafeEmitterArg 00357 * object is used, the emitter object itself is thread safe. 00358 * 00359 * Since 2.0.0-rc2 00360 */ 00361 Cgu::SafeEmitterArg<Cgu::Application*> startup; 00362 00363 /** 00364 * This SafeEmitterArg object emits (and so executes any connected 00365 * callback) when the underlying GApplication object emits its 00366 * @a command-line signal. The second argument passed to the 00367 * emitter's callback(s) is the one passed by that signal, that is to 00368 * say the arguments are: 00369 * 00370 * first: a pointer to the Cgu::Application object. 00371 * 00372 * second: a pointer to a GApplicationCommandLine object representing 00373 * the passed command line (this is owned by gio and should not be 00374 * unref'ed). 00375 * 00376 * third: a gint& reference to which the value to be returned to the 00377 * GApplication's command-line signal can be passed: if no value is 00378 * assigned to it or no callback has been attached to the signal, 0 00379 * will be returned, except that if an exception from a callback is 00380 * consumed, -1 will be returned. If more than one callback is 00381 * attached to the signal and no exception is consumed, the last one 00382 * to assign a value will be have its value returned. 00383 * 00384 * @note When the callback executes, thread cancellation is blocked, 00385 * and any exceptions are consumed with a g_critical message issued 00386 * and a return value of -1 set. The callback will always execute in 00387 * the main GUI thread when executed in response to the run() method. 00388 * Because a SafeEmitterArg object is used, the emitter object itself 00389 * is thread safe. 00390 * 00391 * Since 2.0.0-rc2 00392 */ 00393 Cgu::SafeEmitterArg<Cgu::Application*, GApplicationCommandLine*, gint&> command_line; 00394 00395 /** 00396 * This SafeEmitterArg object emits (and so executes any connected 00397 * callback) when the underlying GApplication object emits its @a open 00398 * signal. The second and third arguments passed to the emitter's 00399 * callback(s) are those passed by that signal, that is to say the 00400 * arguments are: 00401 * 00402 * first: a pointer to the Cgu::Application object. 00403 * 00404 * second: a std::pair object where the first member is an array of 00405 * GFile*'s representing the files/uris passed as arguments, and the 00406 * second member is the length of that array (the array is owned by 00407 * gio and should not be freed). 00408 * 00409 * third: a gchar* argument comprising the text of the "hint" (this is 00410 * owned by gio and should not be freed). 00411 * 00412 * @note When the callback executes, thread cancellation is blocked, 00413 * and any exceptions are consumed with a g_critical message issued. 00414 * The callback will always execute in the main GUI thread when 00415 * executed in response to the run() method. Because a SafeEmitterArg 00416 * object is used, the emitter object itself is thread safe. 00417 * 00418 * Since 2.0.0-rc2 00419 */ 00420 Cgu::SafeEmitterArg<Cgu::Application*, std::pair<GFile**, gint>, gchar*> open; 00421 00422 /** 00423 * Add a Cgu::WinBase object to the Cgu::Application object, and so 00424 * also add its managed GtkWindow object to the GtkApplication object. 00425 * Any Cgu::WinBase object passed to this method should not normally 00426 * be modal and must have been constructed on free store with the new 00427 * expression, and will be self owning, although if it is removed from 00428 * this Cgu::Application object with remove(), the delete expression 00429 * can (and normally should) be called on it. If a delete event 00430 * occurs on the WinBase object so that the WinBase object destroys 00431 * itself (say, by clicking on the window's close/delete button), or 00432 * it destroys itself in some other way (say, by calling the 00433 * WinBase::close() method), it will automatically be removed from 00434 * this Application object without further action being necessary. 00435 * The WinBase::exec() method should never be called on a WinBase 00436 * object which has been added to an Application object. The 00437 * Cgu::Application class, and thus this method, does not employ 00438 * mutexes to make it thread safe, as there should never be a reason 00439 * to call Cgu::Application methods in other than the main GUI thread. 00440 * @param win The Cgu::WinBase object to be added. 00441 * @exception std::bad_alloc This method might throw std::bad_alloc if 00442 * memory is exhausted and the system throws in that case. 00443 * @note As well as this method only being called in the main GUI 00444 * thread, if the program by which it is called calls GTK+ directly in 00445 * more than one thread and thus employs 00446 * gdk_threads_enter()/gdk_threads_leave() (rather than, say, 00447 * Cgu::Notifier or Cgu::Callback::post()), it must be surrounded by 00448 * gdk_threads_enter()/gdk_threads_leave() if called otherwise than in 00449 * a GTK+ signal handler. (The best approach however is for a program 00450 * only to address GTK+/GDK in the main program thread, for which 00451 * purpose this library provides various functions and classes for 00452 * inter-thread communication, such as Cgu::Notifier and 00453 * Cgu::Callback::post(): see @ref Threading for particulars about 00454 * GTK+ thread safety.) 00455 * 00456 * Since 2.0.0-rc2 00457 */ 00458 void add(Cgu::WinBase* win); 00459 00460 /** 00461 * Remove a Cgu::WinBase object from the Cgu::Application object, and 00462 * so also remove its managed GtkWindow object from the GtkApplication 00463 * object. This method will not throw assuming that merely iterating 00464 * through a list does not throw (as it would not on any sane 00465 * implementation). The Cgu::Application class, and thus this method, 00466 * does not employ mutexes to make it thread safe, as there should 00467 * never be a reason to call Cgu::Application methods in other than 00468 * the main GUI thread. Calling this method does not destroy the 00469 * WinBase object. 00470 * @param win The Cgu::WinBase object to be removed. 00471 * @return true if the Cgu::WinBase object was found in the 00472 * Cgu::Application object and so removed, otherwise false. 00473 * @note As well as this method only being called in the main GUI 00474 * thread, if the program by which it is called calls GTK+ directly in 00475 * more than one thread and thus employs 00476 * gdk_threads_enter()/gdk_threads_leave() (rather than, say, 00477 * Cgu::Notifier or Cgu::Callback::post()), it must be surrounded by 00478 * gdk_threads_enter()/gdk_threads_leave() if called otherwise than in 00479 * a GTK+ signal handler. (The best approach however is for a program 00480 * only to address GTK+/GDK in the main program thread, for which 00481 * purpose this library provides various functions and classes for 00482 * inter-thread communication, such as Cgu::Notifier and 00483 * Cgu::Callback::post(): see @ref Threading for particulars about 00484 * GTK+ thread safety.) 00485 * 00486 * Since 2.0.0-rc2 00487 */ 00488 bool remove(Cgu::WinBase* win); 00489 00490 /** 00491 * Calls g_application_run() in respect of the underlying 00492 * GtkApplication object, so invoking one of this Cgu::Application 00493 * class's emitters (the exact behaviour depends on the GApplication 00494 * flags passed to the constructor and is explained in the 00495 * introductory remarks above). This method is thread safe (although 00496 * that is irrelevant to its purpose) and will not throw. In 00497 * addition, if a callback connected to an emitter throws, the 00498 * exception is consumed and a g_critical warning issued. This 00499 * function blocks until the last WinBase object associated with this 00500 * Application object is destroyed or removed. 00501 * @param argc The argc from main() or 0. 00502 * @param argv The argv from main() or 0. 00503 * @return The exit status from g_application_run(). 00504 * 00505 * Since 2.0.0-rc2 00506 */ 00507 int run(int argc, char** argv) { 00508 return g_application_run(G_APPLICATION(app.get()), argc, argv); 00509 } 00510 00511 /** 00512 * Get the underlying GApplication object (note, not the 00513 * GtkApplication object, although the GApplication object can be cast 00514 * to GtkApplication), so allowing any of gio's g_application_*() 00515 * functions to be applied to it. In normal usage it will not be 00516 * necessary to call this method. This method is thread safe and will 00517 * not throw. 00518 * @return The underlying GApplication object. 00519 * 00520 * Since 2.0.0-rc2 00521 */ 00522 GApplication* get_g_app() const {return (GApplication*)app.get();} 00523 00524 /** 00525 * Get the list of Cgu::WinBase objects associated with the 00526 * application. The Cgu::Application class, and thus this method, 00527 * does not employ mutexes to make it thread safe, as there should 00528 * never be a reason to call Cgu::Application methods in other than 00529 * the main GUI thread. 00530 * @return A list of the top level Cgu::WinBase objects associated 00531 * with the application, which will appear in the order in which they 00532 * were added. If you need to access these, you will probably want to 00533 * do a dynamic_cast or static_cast to the child type. 00534 * @exception std::bad_alloc This method might throw std::bad_alloc if 00535 * memory is exhausted and the system throws in that case. 00536 * 00537 * Since 2.0.0-rc2 00538 */ 00539 std::list<Cgu::WinBase*> get_windows() const {return win_list;} 00540 00541 /** 00542 * Gets the current count of Cgu::WinBase objects associated with this 00543 * Cgu::Application object. When it reaches 0, the application will 00544 * normally end (but this can be prevented by calling 00545 * g_application_hold()/g_application_release() on the GApplication 00546 * object returned by get_g_app()). This method can be used in the 00547 * callback of one of this class's emitters to determine whether this 00548 * is the first instance of a program to be started (assuming the 00549 * first instance calls add() to bring up a window), because in that 00550 * case it will return 0 until add() is called. Calling 00551 * get_windows().size() will give the same result, but using this 00552 * method is more efficient as it will avoid a copy of the list of 00553 * windows. This method will not throw assuming that calling 00554 * std::list::size() does not throw (as it would not on any sane 00555 * implementation). The Cgu::Application class, and thus this method, 00556 * does not employ mutexes to make it thread safe, as there should 00557 * never be a reason to call Cgu::Application methods in other than 00558 * the main GUI thread. 00559 * @return The number of Cgu::WinBase objects currently associated 00560 * with this Cgu::Application object. 00561 * 00562 * Since 2.0.0-rc2 00563 */ 00564 size_type get_win_count() const {return win_list.size();} 00565 00566 /** 00567 * This constructor will, via gtk_application_new(), cause 00568 * g_type_init() to be called. If any GTK+ functions are to be called 00569 * before an Application object is constructed, g_type_init() (or 00570 * gtk_init()) must be called explicitly. 00571 * @param prog_name An identifier name. This can comprise any valid 00572 * ASCII characters "[A-Z][a-z][0-9]_-", although it is usually best 00573 * to pass the program name. Unlike with gtk_application_new(), it 00574 * does not need to comprise a full dbus bus name: this method will 00575 * construct its own valid dbus bus name from prog_name in the org.cgu 00576 * domain. 00577 * @param flags The GApplicationFlags to be passed to the 00578 * Cgu::Application object. This class does not contain its own 00579 * sub-class of GApplication to customize this, but adopts the 00580 * behaviour of GtkApplication. That behaviour is explained in the 00581 * introductory remarks. 00582 * @exception Cgu::ApplicationNameError This exception will be thrown 00583 * if the prog_name parameter does not meet the requirements referred 00584 * to above. 00585 * @exception std::bad_alloc This method might throw std::bad_alloc if 00586 * memory is exhausted and the system throws in that case. 00587 * 00588 * Since 2.0.0-rc2 00589 */ 00590 Application(const char* prog_name, GApplicationFlags flags); 00591 00592 /** 00593 * From version 2.0.0-rc3, as a safety feature the destructor removes 00594 * any remaining WinBase objects associated with this Application 00595 * object (this would only be relevant if the user constructs the 00596 * Application object on free store, and then deletes it while the 00597 * run() method is still blocking for the purpose of constructing a 00598 * different Application object, but does not call the remove() method 00599 * on all associated WinBase objects before doing so: constructing an 00600 * Application object on free store in this way would be highly 00601 * unusual however). 00602 * 00603 * Since 2.0.0-rc3 00604 */ 00605 ~Application() {while (!win_list.empty()) remove(win_list.front());} 00606 00607 /* Only has effect if --with-glib-memory-slices-compat or 00608 * --with-glib-memory-slices-no-compat option picked */ 00609 CGU_GLIB_MEMORY_SLICES_FUNCS 00610 }; 00611 00612 #endif // GTK_CHECK_VERSION(2,99,0) 00613 00614 } // namespace Cgu 00615 00616 #endif // CGU_APPLICATION_H