GnuCash 2.4.99
gnc-embedded-window.c
00001 /*
00002  * gnc-main-window.c -- GtkWindow which represents the
00003  *      GnuCash main window.
00004  *
00005  * Copyright (C) 2003 Jan Arne Petersen <jpetersen@uni-bonn.de>
00006  * Copyright (C) 2003 David Hampton <hampton@employees.org>
00007  *
00008  * This program is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU General Public License as
00010  * published by the Free Software Foundation; either version 2 of
00011  * the License, or (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, contact:
00020  *
00021  * Free Software Foundation           Voice:  +1-617-542-5942
00022  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
00023  * Boston, MA  02110-1301,  USA       gnu@gnu.org
00024  */
00025 
00026 #include "config.h"
00027 
00028 #include <gtk/gtk.h>
00029 
00030 #include "gnc-embedded-window.h"
00031 
00032 #include "gnc-engine.h"
00033 #include "gnc-gnome-utils.h"
00034 #include "gnc-gobject-utils.h"
00035 #include "gnc-gui-query.h"
00036 #include "gnc-plugin.h"
00037 #include "gnc-plugin-manager.h"
00038 #include "gnc-ui.h"
00039 #include "gnc-window.h"
00040 
00041 /* Static Globals *******************************************************/
00042 
00044 static QofLogModule log_module = GNC_MOD_GUI;
00046 static GObjectClass *parent_class = NULL;
00047 
00048 
00049 /* Declarations *********************************************************/
00050 static void gnc_embedded_window_class_init (GncEmbeddedWindowClass *klass);
00051 static void gnc_embedded_window_init (GncEmbeddedWindow *window, GncEmbeddedWindowClass *klass);
00052 static void gnc_embedded_window_finalize (GObject *object);
00053 static void gnc_embedded_window_dispose (GObject *object);
00054 
00055 static void gnc_window_embedded_window_init (GncWindowIface *iface);
00056 
00057 static void gnc_embedded_window_setup_window (GncEmbeddedWindow *window);
00058 
00059 
00061 typedef struct GncEmbeddedWindowPrivate
00062 {
00067     GtkWidget *menu_dock;
00068     /* The toolbar created by the UI manager.  This pointer provides
00069      * easy access for showing/hiding the toolbar. */
00070     GtkWidget *toolbar;
00074     GtkWidget *statusbar;
00075 
00079     GtkActionGroup *action_group;
00080 
00082     GncPluginPage *page;
00085     GtkWidget *parent_window;
00086 } GncEmbeddedWindowPrivate;
00087 
00088 #define GNC_EMBEDDED_WINDOW_GET_PRIVATE(o)  \
00089    (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_EMBEDDED_WINDOW, GncEmbeddedWindowPrivate))
00090 
00091 
00092 
00093 /*  Get the type of a gnc embedded window. */
00094 GType
00095 gnc_embedded_window_get_type (void)
00096 {
00097     static GType gnc_embedded_window_type = 0;
00098 
00099     if (gnc_embedded_window_type == 0)
00100     {
00101         static const GTypeInfo our_info =
00102         {
00103             sizeof (GncEmbeddedWindowClass),
00104             NULL,
00105             NULL,
00106             (GClassInitFunc) gnc_embedded_window_class_init,
00107             NULL,
00108             NULL,
00109             sizeof (GncEmbeddedWindow),
00110             0,
00111             (GInstanceInitFunc) gnc_embedded_window_init
00112         };
00113 
00114         static const GInterfaceInfo plugin_info =
00115         {
00116             (GInterfaceInitFunc) gnc_window_embedded_window_init,
00117             NULL,
00118             NULL
00119         };
00120 
00121         gnc_embedded_window_type = g_type_register_static (GTK_TYPE_VBOX,
00122                                    "GncEmbeddedWindow",
00123                                    &our_info, 0);
00124         g_type_add_interface_static (gnc_embedded_window_type,
00125                                      GNC_TYPE_WINDOW,
00126                                      &plugin_info);
00127     }
00128 
00129     return gnc_embedded_window_type;
00130 }
00131 
00132 
00133 /*  Display a data plugin page in a window. */
00134 void
00135 gnc_embedded_window_open_page (GncEmbeddedWindow *window,
00136                                GncPluginPage *page)
00137 {
00138     GncEmbeddedWindowPrivate *priv;
00139 
00140     g_return_if_fail (GNC_IS_EMBEDDED_WINDOW (window));
00141     g_return_if_fail (GNC_IS_PLUGIN_PAGE (page));
00142     priv = GNC_EMBEDDED_WINDOW_GET_PRIVATE(window);
00143     g_return_if_fail (priv->page == NULL);
00144 
00145     ENTER("window %p, page %p", window, page);
00146     priv->page = page;
00147     page->window = GTK_WIDGET(window);
00148     page->notebook_page = gnc_plugin_page_create_widget (page);
00149 
00150     gtk_box_pack_end(GTK_BOX(window), page->notebook_page, TRUE, TRUE, 2);
00151     gnc_plugin_page_inserted (page);
00152 
00153     gnc_plugin_page_merge_actions (page, window->ui_merge);
00154     LEAVE(" ");
00155 }
00156 
00157 
00158 /*  Remove a data plugin page from a window. */
00159 void
00160 gnc_embedded_window_close_page (GncEmbeddedWindow *window,
00161                                 GncPluginPage *page)
00162 {
00163     GncEmbeddedWindowPrivate *priv;
00164 
00165     g_return_if_fail (GNC_IS_EMBEDDED_WINDOW (window));
00166     g_return_if_fail (GNC_IS_PLUGIN_PAGE (page));
00167     priv = GNC_EMBEDDED_WINDOW_GET_PRIVATE(window);
00168     g_return_if_fail (priv->page == page);
00169 
00170     ENTER("window %p, page %p", window, page);
00171 
00172     if (!page->notebook_page)
00173     {
00174         LEAVE("no displayed widget");
00175         return;
00176     }
00177 
00178     gtk_container_remove (GTK_CONTAINER(window), GTK_WIDGET(page->notebook_page));
00179     priv->page = NULL;
00180     gnc_plugin_page_removed (page);
00181 
00182     gnc_plugin_page_unmerge_actions (page, window->ui_merge);
00183     gtk_ui_manager_ensure_update (window->ui_merge);
00184 
00185     gnc_plugin_page_destroy_widget (page);
00186     g_object_unref(page);
00187     LEAVE(" ");
00188 }
00189 
00190 
00191 /*  Retrieve the plugin that is embedded in the specified window. */
00192 GncPluginPage *
00193 gnc_embedded_window_get_page (GncEmbeddedWindow *window)
00194 {
00195     GncEmbeddedWindowPrivate *priv;
00196 
00197     priv = GNC_EMBEDDED_WINDOW_GET_PRIVATE(window);
00198     return priv->page;
00199 }
00200 
00201 
00208 static void
00209 gnc_embedded_window_class_init (GncEmbeddedWindowClass *klass)
00210 {
00211     GObjectClass *object_class;
00212     ENTER("klass %p", klass);
00213     object_class = G_OBJECT_CLASS (klass);
00214 
00215     parent_class = g_type_class_peek_parent (klass);
00216 
00217     object_class->finalize = gnc_embedded_window_finalize;
00218     object_class->dispose = gnc_embedded_window_dispose;
00219 
00220     g_type_class_add_private(klass, sizeof(GncEmbeddedWindowPrivate));
00221     LEAVE(" ");
00222 }
00223 
00224 
00233 static void
00234 gnc_embedded_window_init (GncEmbeddedWindow *window,
00235                           GncEmbeddedWindowClass *klass)
00236 {
00237     ENTER("window %p", window);
00238 
00239     gnc_embedded_window_setup_window (window);
00240 
00241     gnc_gobject_tracking_remember(G_OBJECT(window),
00242                                   G_OBJECT_CLASS(klass));
00243     LEAVE(" ");
00244 }
00245 
00246 
00250 static void
00251 gnc_embedded_window_finalize (GObject *object)
00252 {
00253     GncEmbeddedWindow *window;
00254     GncEmbeddedWindowPrivate *priv;
00255 
00256     g_return_if_fail (object != NULL);
00257     g_return_if_fail (GNC_IS_EMBEDDED_WINDOW (object));
00258 
00259     ENTER("object %p", object);
00260     window = GNC_EMBEDDED_WINDOW (object);
00261     priv = GNC_EMBEDDED_WINDOW_GET_PRIVATE(window);
00262 
00263     gnc_gobject_tracking_forget(object);
00264     G_OBJECT_CLASS (parent_class)->finalize (object);
00265     LEAVE(" ");
00266 }
00267 
00268 
00273 static void
00274 gnc_embedded_window_dispose (GObject *object)
00275 {
00276     GncEmbeddedWindow *window;
00277     GncEmbeddedWindowPrivate *priv;
00278 
00279     g_return_if_fail (object != NULL);
00280     g_return_if_fail (GNC_IS_EMBEDDED_WINDOW (object));
00281 
00282     ENTER("object %p", object);
00283     window = GNC_EMBEDDED_WINDOW (object);
00284     priv = GNC_EMBEDDED_WINDOW_GET_PRIVATE(window);
00285     if (priv->page)
00286     {
00287         DEBUG("unreffing page %p (count currently %d)", priv->page,
00288               G_OBJECT(priv->page)->ref_count);
00289         g_object_unref(priv->page);
00290         priv->page = NULL;
00291     }
00292 
00293     G_OBJECT_CLASS (parent_class)->dispose (object);
00294     LEAVE(" ");
00295 }
00296 
00297 
00298 static void
00299 gnc_embedded_window_add_widget (GtkUIManager *merge,
00300                                 GtkWidget *widget,
00301                                 GncEmbeddedWindow *window)
00302 {
00303     GncEmbeddedWindowPrivate *priv;
00304 
00305     ENTER("merge %p, new widget %p, window %p", merge, widget, window);
00306     priv = GNC_EMBEDDED_WINDOW_GET_PRIVATE(window);
00307     if (GTK_IS_TOOLBAR (widget))
00308     {
00309         priv->toolbar = widget;
00310     }
00311 
00312     gtk_box_pack_start (GTK_BOX (priv->menu_dock), widget, FALSE, FALSE, 0);
00313     gtk_widget_show (widget);
00314     LEAVE(" ");
00315 }
00316 
00317 
00321 static void
00322 gnc_embedded_window_setup_window (GncEmbeddedWindow *window)
00323 {
00324     GncEmbeddedWindowPrivate *priv;
00325 
00326     ENTER("window %p", window);
00327     priv = GNC_EMBEDDED_WINDOW_GET_PRIVATE(window);
00328 
00329     /* Create widgets and add them to the window */
00330     gtk_widget_show (GTK_WIDGET(window));
00331 
00332     priv->menu_dock = gtk_vbox_new (FALSE, 0);
00333     gtk_widget_show (priv->menu_dock);
00334     gtk_box_pack_start (GTK_BOX (window), priv->menu_dock, TRUE, TRUE, 0);
00335 
00336     priv->statusbar = gtk_statusbar_new ();
00337     gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR(priv->statusbar), FALSE);
00338     gtk_widget_show (priv->statusbar);
00339     gtk_box_pack_end (GTK_BOX (window), priv->statusbar, FALSE, TRUE, 0);
00340 
00341     window->ui_merge = gtk_ui_manager_new ();
00342     g_signal_connect (G_OBJECT (window->ui_merge), "add_widget",
00343                       G_CALLBACK (gnc_embedded_window_add_widget), window);
00344 
00345     priv->action_group = NULL;
00346     LEAVE(" ");
00347 }
00348 
00349 
00351 GncEmbeddedWindow *
00352 gnc_embedded_window_new (const gchar *action_group_name,
00353                          GtkActionEntry *action_entries,
00354                          gint n_action_entries,
00355                          const gchar *ui_filename,
00356                          GtkWidget *enclosing_win,
00357                          gboolean add_accelerators,
00358                          gpointer user_data)
00359 {
00360     GncEmbeddedWindowPrivate *priv;
00361     GncEmbeddedWindow *window;
00362     gchar *ui_fullname;
00363     GError *error = NULL;
00364     guint merge_id;
00365 
00366     ENTER("group %s, first %p, num %d, ui file %s, parent %p, add accelerators %d, user data %p",
00367           action_group_name, action_entries, n_action_entries, ui_filename,
00368           enclosing_win, add_accelerators, user_data);
00369     window = g_object_new (GNC_TYPE_EMBEDDED_WINDOW, NULL);
00370     priv = GNC_EMBEDDED_WINDOW_GET_PRIVATE(window);
00371 
00372     /* Determine the full pathname of the ui file */
00373     ui_fullname = gnc_gnome_locate_ui_file(ui_filename);
00374 
00375     priv->parent_window = enclosing_win;
00376 
00377     /* Create menu and toolbar information */
00378     priv->action_group = gtk_action_group_new (action_group_name);
00379     gnc_gtk_action_group_set_translation_domain(priv->action_group, GETTEXT_PACKAGE);
00380     gtk_action_group_add_actions (priv->action_group, action_entries,
00381                                   n_action_entries, user_data);
00382     gtk_ui_manager_insert_action_group (window->ui_merge, priv->action_group, 0);
00383     merge_id = gtk_ui_manager_add_ui_from_file (window->ui_merge, ui_fullname,
00384                &error);
00385 
00386     /* Error checking */
00387     g_assert(merge_id || error);
00388     if (error)
00389     {
00390         g_critical("Failed to load ui file.\n  Filename %s\n  Error %s",
00391                    ui_fullname, error->message);
00392         g_error_free(error);
00393         g_free(ui_fullname);
00394         LEAVE("window %p", window);
00395         return window;
00396     }
00397 
00398     /* Add accelerators (if wanted) */
00399     if (add_accelerators)
00400         gtk_window_add_accel_group (GTK_WINDOW(enclosing_win),
00401                                     gtk_ui_manager_get_accel_group(window->ui_merge));
00402 
00403     gtk_ui_manager_ensure_update (window->ui_merge);
00404     g_free(ui_fullname);
00405     LEAVE("window %p", window);
00406     return window;
00407 }
00408 
00409 
00415 static GtkWindow *
00416 gnc_embedded_window_get_gtk_window (GncWindow *window_in)
00417 {
00418     GncEmbeddedWindow *window;
00419     GncEmbeddedWindowPrivate *priv;
00420 
00421     g_return_val_if_fail (GNC_IS_EMBEDDED_WINDOW (window_in), NULL);
00422 
00423     window = GNC_EMBEDDED_WINDOW(window_in);
00424     priv = GNC_EMBEDDED_WINDOW_GET_PRIVATE(window);
00425     return GTK_WINDOW(priv->parent_window);
00426 }
00427 
00428 
00434 static GtkWidget *
00435 gnc_embedded_window_get_statusbar (GncWindow *window_in)
00436 {
00437     GncEmbeddedWindowPrivate *priv;
00438     GncEmbeddedWindow *window;
00439 
00440     g_return_val_if_fail (GNC_IS_EMBEDDED_WINDOW (window_in), NULL);
00441 
00442     window = GNC_EMBEDDED_WINDOW(window_in);
00443     priv = GNC_EMBEDDED_WINDOW_GET_PRIVATE(window);
00444     return priv->statusbar;
00445 }
00446 
00447 
00452 static void
00453 gnc_window_embedded_window_init (GncWindowIface *iface)
00454 {
00455     iface->get_gtk_window = gnc_embedded_window_get_gtk_window;
00456     iface->get_statusbar = gnc_embedded_window_get_statusbar;
00457 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines