diff --git a/src/gnome/Makefile.am b/src/gnome/Makefile.am index 5a009df3b4..88602f2828 100644 --- a/src/gnome/Makefile.am +++ b/src/gnome/Makefile.am @@ -42,6 +42,7 @@ libgncgnome_la_SOURCES = \ druid-hierarchy.c \ druid-loan.c \ druid-stock-split.c \ + gnc-embedded-window.c \ gnc-main-window.c \ gnc-plugin.c \ gnc-plugin-account-tree.c \ @@ -87,6 +88,7 @@ noinst_HEADERS = \ druid-hierarchy.h \ druid-loan.h \ druid-stock-split.h \ + gnc-embedded-window.h \ gnc-main-window.h \ gnc-plugin.h \ gnc-plugin-account-tree.h \ diff --git a/src/gnome/gnc-embedded-window.c b/src/gnome/gnc-embedded-window.c new file mode 100644 index 0000000000..c592ad1e5a --- /dev/null +++ b/src/gnome/gnc-embedded-window.c @@ -0,0 +1,313 @@ +/* + * gnc-main-window.c -- GtkWindow which represents the + * GnuCash main window. + * + * Copyright (C) 2003 Jan Arne Petersen + * Copyright (C) 2003 David Hampton + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, contact: + * + * Free Software Foundation Voice: +1-617-542-5942 + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 + * Boston, MA 02111-1307, USA gnu@gnu.org + */ + +#include "config.h" + +#include + +#include "eggtoolbar.h" +#include "egg-action-group.h" +#include "egg-menu-merge.h" +#include "egg-toggle-action.h" + +#include "gnc-embedded-window.h" + +#include "gnc-engine.h" +#include "gnc-engine-util.h" +#include "gnc-gnome-utils.h" +#include "gnc-dir.h" +#include "gnc-file.h" +#include "gnc-gui-query.h" +#include "gnc-plugin.h" +#include "gnc-plugin-manager.h" +#include "gnc-session.h" +#include "gnc-ui.h" +#include "messages.h" + +/** Static Globals *******************************************************/ +static short module = MOD_GUI; + +/** Declarations *********************************************************/ +static void gnc_embedded_window_class_init (GncEmbeddedWindowClass *klass); +static void gnc_embedded_window_init (GncEmbeddedWindow *window); +static void gnc_embedded_window_finalize (GObject *object); +static void gnc_embedded_window_dispose (GObject *object); + +static void gnc_embedded_window_setup_window (GncEmbeddedWindow *window); + + +struct GncEmbeddedWindowPrivate +{ + GtkWidget *menu_dock; + GtkWidget *toolbar_dock; + GtkWidget *statusbar; + + EggActionGroup *action_group; + + GncPluginPage *page; +}; + +static GObjectClass *parent_class = NULL; + +static GQuark window_type = 0; + +GType +gnc_embedded_window_get_type (void) +{ + static GType gnc_embedded_window_type = 0; + + if (gnc_embedded_window_type == 0) { + static const GTypeInfo our_info = { + sizeof (GncEmbeddedWindowClass), + NULL, + NULL, + (GClassInitFunc) gnc_embedded_window_class_init, + NULL, + NULL, + sizeof (GncEmbeddedWindow), + 0, + (GInstanceInitFunc) gnc_embedded_window_init + }; + + gnc_embedded_window_type = g_type_register_static (GTK_TYPE_VBOX, + "GncEmbeddedWindow", + &our_info, 0); + } + + return gnc_embedded_window_type; +} + +void +gnc_embedded_window_open_page (GncEmbeddedWindow *window, + GncPluginPage *page) +{ + ENTER("window %p, page %p", window, page); + g_return_if_fail (GNC_IS_EMBEDDED_WINDOW (window)); + g_return_if_fail (GNC_IS_PLUGIN_PAGE (page)); + g_return_if_fail (window->priv->page == NULL); + + window->priv->page = page; + page->window = GTK_WIDGET(window); + page->notebook_page = gnc_plugin_page_create_widget (page); + g_object_set_data (G_OBJECT (page->notebook_page), PLUGIN_PAGE_LABEL, page); + + gtk_box_pack_end(GTK_BOX(window), page->notebook_page, TRUE, TRUE, 2); + gnc_plugin_page_inserted (page); + + gnc_plugin_page_merge_actions (page, window->ui_merge); + LEAVE(" "); +} + +void +gnc_embedded_window_close_page (GncEmbeddedWindow *window, + GncPluginPage *page) +{ + ENTER("window %p, page %p", window, page); + g_return_if_fail (GNC_IS_EMBEDDED_WINDOW (window)); + g_return_if_fail (GNC_IS_PLUGIN_PAGE (page)); + + if (!page->notebook_page) { + LEAVE("no displayed widget"); + return; + } + + gtk_container_remove (GTK_CONTAINER(window), GTK_WIDGET(window->priv->page)); + window->priv->page = NULL; + gnc_plugin_page_removed (page); + + gnc_plugin_page_unmerge_actions (page, window->ui_merge); + egg_menu_merge_ensure_update (window->ui_merge); + + gnc_plugin_page_destroy_widget (page); + g_object_unref(page); + LEAVE(" "); +} + +GncPluginPage * +gnc_embedded_window_get_page (GncEmbeddedWindow *window) +{ + return window->priv->page; +} + + +static void +gnc_embedded_window_class_init (GncEmbeddedWindowClass *klass) +{ + ENTER("klass %p", klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + window_type = g_quark_from_static_string ("gnc-embedded-window"); + + object_class->finalize = gnc_embedded_window_finalize; + object_class->dispose = gnc_embedded_window_dispose; + LEAVE(" "); +} + +static void +gnc_embedded_window_init (GncEmbeddedWindow *window) +{ + ENTER("window %p", window); + window->priv = g_new0 (GncEmbeddedWindowPrivate, 1); + + gnc_embedded_window_setup_window (window); + LEAVE(" "); +} + +static void +gnc_embedded_window_finalize (GObject *object) +{ + GncEmbeddedWindow *window; + + ENTER("object %p", object); + g_return_if_fail (object != NULL); + g_return_if_fail (GNC_IS_EMBEDDED_WINDOW (object)); + + window = GNC_EMBEDDED_WINDOW (object); + + g_return_if_fail (window->priv != NULL); + + g_free (window->priv); + + G_OBJECT_CLASS (parent_class)->finalize (object); + LEAVE(" "); +} + +static void +gnc_embedded_window_dispose (GObject *object) +{ + GncEmbeddedWindow *window; + + ENTER("object %p", object); + g_return_if_fail (object != NULL); + g_return_if_fail (GNC_IS_EMBEDDED_WINDOW (object)); + + window = GNC_EMBEDDED_WINDOW (object); + if (window->priv->page) { + DEBUG("unreffing page %p (count currently %d)", window->priv->page, + G_OBJECT(window->priv->page)->ref_count); + g_object_unref(window->priv->page); + window->priv->page = NULL; + } + + G_OBJECT_CLASS (parent_class)->dispose (object); + LEAVE(" "); +} + +static void +gnc_embedded_window_add_widget (EggMenuMerge *merge, + GtkWidget *widget, + GncEmbeddedWindow *window) +{ + ENTER("merge %p, new widget %p, window %p", merge, widget, window); + if (EGG_IS_TOOLBAR (widget)) { + window->priv->toolbar_dock = widget; + } + + gtk_box_pack_start (GTK_BOX (window->priv->menu_dock), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + LEAVE(" "); +} + +static void +gnc_embedded_window_setup_window (GncEmbeddedWindow *window) +{ + GncEmbeddedWindowPrivate *priv; + + ENTER("window %p", window); + priv = window->priv; + + /* Create widgets and add them to the window */ + gtk_widget_show (GTK_WIDGET(window)); + + priv->menu_dock = gtk_vbox_new (FALSE, 0); + gtk_widget_show (priv->menu_dock); + gtk_box_pack_start (GTK_BOX (window), priv->menu_dock, FALSE, TRUE, 0); + + priv->statusbar = gtk_statusbar_new (); + gtk_widget_show (priv->statusbar); + gtk_box_pack_end (GTK_BOX (window), priv->statusbar, FALSE, TRUE, 0); + + window->ui_merge = egg_menu_merge_new (); + g_signal_connect (G_OBJECT (window->ui_merge), "add_widget", + G_CALLBACK (gnc_embedded_window_add_widget), window); + + priv->action_group = NULL; + LEAVE(" "); +} + +GncEmbeddedWindow * +gnc_embedded_window_new (const gchar *action_group_name, + EggActionEntry *action_entries, + gint n_action_entries, + const gchar *ui_filename, + GtkWindow *enclosing_win, + gpointer user_data) +{ + GncEmbeddedWindowPrivate *priv; + GncEmbeddedWindow *window; + gchar *ui_fullname; + GError *error = NULL; + guint merge_id; + + ENTER("group %s, first %p, num %d, ui file %s, parent %p, user data %p", + action_group_name, action_entries, n_action_entries, ui_filename, + enclosing_win, user_data); + window = g_object_new (GNC_TYPE_EMBEDDED_WINDOW, NULL); + priv = window->priv; + + /* Determine the full pathname of the ui file */ + ui_fullname = g_strdup_printf("%s/%s", GNC_UI_DIR, ui_filename); + + /* Create menu and toolbar information */ + priv->action_group = egg_action_group_new (action_group_name); + egg_action_group_add_actions (priv->action_group, action_entries, + n_action_entries, user_data); + egg_menu_merge_insert_action_group (window->ui_merge, priv->action_group, 0); + merge_id = egg_menu_merge_add_ui_from_file (window->ui_merge, ui_fullname, + &error); + + /* Error checking */ + g_assert(merge_id || error); + if (error) { + g_critical("Failed to load ui file.\n Filename %s\n Error %s", + ui_fullname, error->message); + g_error_free(error); + g_free(ui_fullname); + LEAVE("window %p", window); + return window; + } + + /* Add accelerators (if wanted) */ + if (enclosing_win) + gtk_window_add_accel_group (enclosing_win, window->ui_merge->accel_group); + + egg_menu_merge_ensure_update (window->ui_merge); + g_free(ui_fullname); + LEAVE("window %p", window); + return window; +} + diff --git a/src/gnome/gnc-embedded-window.h b/src/gnome/gnc-embedded-window.h new file mode 100644 index 0000000000..75b8e07920 --- /dev/null +++ b/src/gnome/gnc-embedded-window.h @@ -0,0 +1,88 @@ +/* + * gnc-embedded-window.h -- GtkWindow which represents an + * emvedded GnuCash window. + * + * Copyright (C) 2003 Jan Arne Petersen + * Author: Jan Arne Petersen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, contact: + * + * Free Software Foundation Voice: +1-617-542-5942 + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 + * Boston, MA 02111-1307, USA gnu@gnu.org + */ + +#ifndef __GNC_EMBEDDED_WINDOW_H +#define __GNC_EMBEDDED_WINDOW_H + +#include + +#include "egg-menu-merge.h" + +#include "gnc-plugin-page.h" + +G_BEGIN_DECLS + +#define PLUGIN_PAGE_LABEL "plugin-page" + +/* type macros */ +#define GNC_TYPE_EMBEDDED_WINDOW (gnc_embedded_window_get_type ()) +#define GNC_EMBEDDED_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNC_TYPE_EMBEDDED_WINDOW, GncEmbeddedWindow)) +#define GNC_EMBEDDED_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNC_TYPE_EMBEDDED_WINDOW, GncEmbeddedWindowClass)) +#define GNC_IS_EMBEDDED_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNC_TYPE_EMBEDDED_WINDOW)) +#define GNC_IS_EMBEDDED_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNC_TYPE_EMBEDDED_WINDOW)) +#define GNC_EMBEDDED_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GNC_TYPE_EMBEDDED_WINDOW, GncEmbeddedWindowClass)) + +/* typedefs & structures */ +typedef struct GncEmbeddedWindowPrivate GncEmbeddedWindowPrivate; + +typedef struct { + GtkVBox parent; + + GncEmbeddedWindowPrivate *priv; + + EggMenuMerge *ui_merge; +} GncEmbeddedWindow; + +typedef struct { + GtkVBoxClass parent; +} GncEmbeddedWindowClass; + +typedef struct gnc_embedded_window { + EggMenuMerge *ui_merge; + EggActionGroup *action_group; + GtkWidget *main_vbox; + GtkWidget *menu_dock; + GtkWidget *toolbar_dock; +} gnc_embedded_window; + +/* function prototypes */ +GType gnc_embedded_window_get_type (void); + +GncEmbeddedWindow * gnc_embedded_window_new (const gchar *action_group_name, + EggActionEntry *action_entries, + gint n_action_entries, + const gchar *ui_filename, + GtkWindow *enclosing_win, + gpointer user_data); + +void gnc_embedded_window_open_page (GncEmbeddedWindow *window, + GncPluginPage *page); +void gnc_embedded_window_close_page (GncEmbeddedWindow *window, + GncPluginPage *page); +GncPluginPage *gnc_embedded_window_get_page (GncEmbeddedWindow *window); + +G_END_DECLS + +#endif /* __GNC_EMBEDDED_WINDOW_H */