From f130490a5cf37625ee3b4d16356ba59725ca40b7 Mon Sep 17 00:00:00 2001 From: John Darrington Date: Thu, 1 Jan 2009 09:09:36 +0900 Subject: [PATCH] New (singleton) object psppire-window-register --- src/ui/gui/automake.mk | 2 + src/ui/gui/psppire-data-window.c | 8 +- src/ui/gui/psppire-syntax-window.c | 15 ++- src/ui/gui/psppire-window-register.c | 189 +++++++++++++++++++++++++++ src/ui/gui/psppire-window-register.h | 92 +++++++++++++ src/ui/gui/psppire-window.c | 151 +++++++++++++++------ src/ui/gui/psppire-window.h | 10 +- 7 files changed, 415 insertions(+), 52 deletions(-) create mode 100644 src/ui/gui/psppire-window-register.c create mode 100644 src/ui/gui/psppire-window-register.h diff --git a/src/ui/gui/automake.mk b/src/ui/gui/automake.mk index a458c0f4..b0264ead 100644 --- a/src/ui/gui/automake.mk +++ b/src/ui/gui/automake.mk @@ -200,6 +200,8 @@ src_ui_gui_psppire_SOURCES = \ src/ui/gui/psppire-output-window.h \ src/ui/gui/psppire-window.c \ src/ui/gui/psppire-window.h \ + src/ui/gui/psppire-window-register.c \ + src/ui/gui/psppire-window-register.h \ src/ui/gui/psppire-syntax-window.c \ src/ui/gui/psppire-syntax-window.h \ src/ui/gui/window-manager.h diff --git a/src/ui/gui/psppire-data-window.c b/src/ui/gui/psppire-data-window.c index 5facbbd2..fdc4087b 100644 --- a/src/ui/gui/psppire-data-window.c +++ b/src/ui/gui/psppire-data-window.c @@ -337,7 +337,7 @@ open_data_file (const gchar *file_name, PsppireDataWindow *de) if (execute_syntax (sss) ) { - // window_set_name_from_filename ((struct editor_window *) de, file_name); + psppire_window_set_filename (PSPPIRE_WINDOW (de), file_name); add_most_recent (file_name); } } @@ -544,7 +544,7 @@ data_save_as_dialog (GtkAction *action, PsppireDataWindow *de) save_file (de); - // window_set_name_from_filename (e, de->file_name); + psppire_window_set_filename (PSPPIRE_WINDOW (de), de->file_name); } break; default: @@ -1705,6 +1705,8 @@ psppire_data_window_init (PsppireDataWindow *de) de->data_sheet_cases_popup_menu = GTK_MENU (create_data_sheet_cases_popup_menu (de)); + PSPPIRE_WINDOW (de)->menu = GTK_MENU (get_widget_assert (de->xml,"Windows_menu")); + g_object_ref (PSPPIRE_WINDOW (de)->menu); g_object_set (de->data_editor, "datasheet-column-menu", de->data_sheet_variable_popup_menu, @@ -1712,7 +1714,7 @@ psppire_data_window_init (PsppireDataWindow *de) "varsheet-row-menu", de->var_sheet_variable_popup_menu, NULL); - gtk_widget_show (de->data_editor); + gtk_widget_show (GTK_WIDGET (de->data_editor)); gtk_widget_show (box); } diff --git a/src/ui/gui/psppire-syntax-window.c b/src/ui/gui/psppire-syntax-window.c index 5b326744..766134b2 100644 --- a/src/ui/gui/psppire-syntax-window.c +++ b/src/ui/gui/psppire-syntax-window.c @@ -24,10 +24,10 @@ #include #include - #include "psppire-syntax-window.h" #include "psppire-data-window.h" +#include "psppire-window-register.h" #include "about.h" #include "psppire-syntax-window.h" #include "syntax-editor-source.h" @@ -37,14 +37,11 @@ #define _(msgid) gettext (msgid) #define N_(msgid) msgid - - static void psppire_syntax_window_base_finalize (PsppireSyntaxWindowClass *, gpointer); static void psppire_syntax_window_base_init (PsppireSyntaxWindowClass *class); static void psppire_syntax_window_class_init (PsppireSyntaxWindowClass *class); static void psppire_syntax_window_init (PsppireSyntaxWindow *syntax_editor); - GType psppire_syntax_window_get_type (void) { @@ -73,12 +70,13 @@ psppire_syntax_window_get_type (void) return psppire_syntax_window_type; } - static void psppire_syntax_window_finalize (GObject *object) { GObjectClass *class = G_OBJECT_GET_CLASS (object); + PsppireSyntaxWindow *window = PSPPIRE_SYNTAX_WINDOW (object); + GObjectClass *parent_class = g_type_class_peek_parent (class); if (G_OBJECT_CLASS (parent_class)->finalize) @@ -474,6 +472,7 @@ open_syntax_window (GtkMenuItem *menuitem, gpointer parent) } + extern struct source_stream *the_source_stream ; static void @@ -574,8 +573,10 @@ psppire_syntax_window_init (PsppireSyntaxWindow *window) g_signal_connect (get_widget_assert (xml,"windows_minimise_all"), "activate", - G_CALLBACK (psppire_window_minimise_all), - NULL); + G_CALLBACK (psppire_window_minimise_all), NULL); + + PSPPIRE_WINDOW (window)->menu = GTK_MENU (get_widget_assert (xml,"windows_menu")); + g_object_ref (PSPPIRE_WINDOW (window)->menu); g_object_unref (xml); diff --git a/src/ui/gui/psppire-window-register.c b/src/ui/gui/psppire-window-register.c new file mode 100644 index 00000000..dfa46c65 --- /dev/null +++ b/src/ui/gui/psppire-window-register.c @@ -0,0 +1,189 @@ +/* PSPPIRE - a graphical user interface for PSPP. + Copyright (C) 2008 Free Software Foundation + + 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 3 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, see . */ + +#include + +#include "psppire-window-register.h" + +static void psppire_window_register_init (PsppireWindowRegister *window_register); +static void psppire_window_register_class_init (PsppireWindowRegisterClass *class); + +static void psppire_window_register_finalize (GObject *object); +static void psppire_window_register_dispose (GObject *object); + +static GObjectClass *parent_class = NULL; + + +enum { + INSERTED, + REMOVED, + n_SIGNALS +}; + +static guint signals [n_SIGNALS]; + +GType +psppire_window_register_get_type (void) +{ + static GType window_register_type = 0; + + if (!window_register_type) + { + static const GTypeInfo window_register_info = + { + sizeof (PsppireWindowRegisterClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) psppire_window_register_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PsppireWindowRegister), + 0, + (GInstanceInitFunc) psppire_window_register_init, + }; + + window_register_type = g_type_register_static (G_TYPE_OBJECT, + "PsppireWindowRegister", + &window_register_info, 0); + } + + return window_register_type; +} + + +static void +psppire_window_register_finalize (GObject *object) +{ +} + +static void +psppire_window_register_dispose (GObject *object) +{ +} + +static PsppireWindowRegister *the_instance = NULL; + +static GObject* +psppire_window_register_construct (GType type, + guint n_construct_params, + GObjectConstructParam *construct_params) +{ + GObject *object; + + if (!the_instance) + { + object = G_OBJECT_CLASS (parent_class)->constructor (type, + n_construct_params, + construct_params); + the_instance = PSPPIRE_WINDOW_REGISTER (object); + } + else + object = g_object_ref (G_OBJECT (the_instance)); + + return object; +} + +static void +psppire_window_register_class_init (PsppireWindowRegisterClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + object_class = (GObjectClass*) class; + + object_class->finalize = psppire_window_register_finalize; + object_class->dispose = psppire_window_register_dispose; + object_class->constructor = psppire_window_register_construct; + + signals [INSERTED] = + g_signal_new ("inserted", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, + 1, + G_TYPE_POINTER); + + signals [REMOVED] = + g_signal_new ("removed", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, + 1, + G_TYPE_POINTER); +} + +static void +psppire_window_register_init (PsppireWindowRegister *window_register) +{ + window_register->dispose_has_run = FALSE; + window_register->name_table = g_hash_table_new (g_str_hash, g_str_equal); +} + +void +psppire_window_register_insert (PsppireWindowRegister *wr, PsppireWindow *window, const gchar *name) +{ + g_hash_table_insert (wr->name_table, (gpointer) name, window); + + g_signal_emit (wr, signals[INSERTED], 0, name); +} + + +void +psppire_window_register_remove (PsppireWindowRegister *wr, const gchar *name) +{ + g_signal_emit (wr, signals[REMOVED], 0, name); + + g_hash_table_remove (wr->name_table, (gpointer) name); +} + +PsppireWindow * +psppire_window_register_lookup (PsppireWindowRegister *wr, const gchar *name) +{ + return g_hash_table_lookup (wr->name_table, name); +} + +void +psppire_window_register_foreach (PsppireWindowRegister *wr, GHFunc func, PsppireWindow *win) +{ + g_hash_table_foreach (wr->name_table, func, win); +} + +static void +minimise_window (gpointer key, gpointer value, gpointer data) +{ + gtk_window_iconify (GTK_WINDOW (value)); +} + + +void +psppire_window_register_minimise_all (PsppireWindowRegister *wr) +{ + g_hash_table_foreach (wr->name_table, minimise_window, wr); +} + + + +PsppireWindowRegister * +psppire_window_register_new (void) +{ + return g_object_new (psppire_window_register_get_type (), NULL); +} diff --git a/src/ui/gui/psppire-window-register.h b/src/ui/gui/psppire-window-register.h new file mode 100644 index 00000000..cc24f4ef --- /dev/null +++ b/src/ui/gui/psppire-window-register.h @@ -0,0 +1,92 @@ +/* PSPPIRE - a graphical user interface for PSPP. + Copyright (C) 2008 Free Software Foundation + + 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 3 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, see . */ + + +#include +#include + +#include "psppire-window.h" + +#ifndef __PSPPIRE_WINDOW_REGISTER_H__ +#define __PSPPIRE_WINDOW_REGISTER_H__ + +G_BEGIN_DECLS + + +#define PSPPIRE_TYPE_WINDOW_REGISTER (psppire_window_register_get_type ()) + +#define PSPPIRE_WINDOW_REGISTER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + PSPPIRE_TYPE_WINDOW_REGISTER, PsppireWindowRegister)) + +#define PSPPIRE_WINDOW_REGISTER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + PSPPIRE_TYPE_WINDOW_REGISTER, \ + PsppireWindowRegisterClass)) + + +#define PSPPIRE_IS_WINDOW_REGISTER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PSPPIRE_TYPE_WINDOW_REGISTER)) + +#define PSPPIRE_IS_WINDOW_REGISTER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), PSPPIRE_TYPE_WINDOW_REGISTER)) + + +#define PSPPIRE_WINDOW_REGISTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + PSPPIRE_TYPE_WINDOW_REGISTER, \ + PsppireWindowRegisterClass)) + +typedef struct _PsppireWindowRegister PsppireWindowRegister; +typedef struct _PsppireWindowRegisterClass PsppireWindowRegisterClass; + + +struct _PsppireWindowRegister +{ + GObject parent; + + /*< private >*/ + gboolean dispose_has_run ; + GHashTable *name_table; +}; + + +struct _PsppireWindowRegisterClass +{ + GObjectClass parent_class; +}; + + +GType psppire_window_register_get_type (void) G_GNUC_CONST; + +PsppireWindowRegister * psppire_window_register_new (void); + +void psppire_window_register_insert (PsppireWindowRegister *wr, PsppireWindow *window, + const gchar *name); + +void psppire_window_register_remove (PsppireWindowRegister *wr, const gchar *name); + + +PsppireWindow *psppire_window_register_lookup (PsppireWindowRegister *wr, const gchar *name); + + +void psppire_window_register_foreach (PsppireWindowRegister *wr, GHFunc func, PsppireWindow *); + +void psppire_window_register_minimise_all (PsppireWindowRegister *wr); + + +G_END_DECLS + +#endif /* __PSPPIRE_WINDOW_REGISTER_H__ */ diff --git a/src/ui/gui/psppire-window.c b/src/ui/gui/psppire-window.c index 767e1054..3da046ab 100644 --- a/src/ui/gui/psppire-window.c +++ b/src/ui/gui/psppire-window.c @@ -18,6 +18,7 @@ #include #include +#include #include @@ -26,7 +27,7 @@ #define N_(msgid) msgid #include "psppire-window.h" - +#include "psppire-window-register.h" static void psppire_window_base_finalize (PsppireWindowClass *, gpointer); static void psppire_window_base_init (PsppireWindowClass *class); @@ -49,7 +50,7 @@ psppire_window_get_type (void) sizeof (PsppireWindowClass), (GBaseInitFunc) psppire_window_base_init, (GBaseFinalizeFunc) psppire_window_base_finalize, - (GClassInitFunc)psppire_window_class_init, + (GClassInitFunc) psppire_window_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (PsppireWindow), @@ -91,7 +92,6 @@ psppire_window_set_property (GObject *object, { PsppireWindow *window = PSPPIRE_WINDOW (object); - PsppireWindowClass *class = PSPPIRE_WINDOW_CLASS (G_OBJECT_GET_CLASS (object)); switch (prop_id) { case PROP_USAGE: @@ -105,7 +105,9 @@ psppire_window_set_property (GObject *object, gchar *candidate_name = strdup (name); int x = 0; - while ( g_hash_table_lookup (class->name_table, candidate_name)) + PsppireWindowRegister *reg = psppire_window_register_new (); + + while ( psppire_window_register_lookup (reg, candidate_name)) { free (candidate_name); candidate_name = uniquify (name, &x); @@ -134,11 +136,13 @@ psppire_window_set_property (GObject *object, gtk_window_set_title (GTK_WINDOW (window), title); + if ( window->name) + psppire_window_register_remove (reg, window->name); + free (window->name); window->name = candidate_name; - - g_hash_table_insert (class->name_table, window->name, window); + psppire_window_register_insert (reg, window, window->name); free (basename); free (title); @@ -179,11 +183,20 @@ static void psppire_window_finalize (GObject *object) { PsppireWindow *window = PSPPIRE_WINDOW (object); - PsppireWindowClass *class = PSPPIRE_WINDOW_CLASS (G_OBJECT_GET_CLASS (object)); + + PsppireWindowRegister *reg = psppire_window_register_new (); - g_hash_table_remove (class->name_table, window->name); + psppire_window_register_remove (reg, window->name); free (window->name); + g_signal_handler_disconnect (psppire_window_register_new (), + window->remove_handler); + + g_signal_handler_disconnect (psppire_window_register_new (), + window->insert_handler); + + g_hash_table_destroy (window->menuitem_table); + if (G_OBJECT_CLASS (parent_class)->finalize) G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -194,8 +207,6 @@ psppire_window_class_init (PsppireWindowClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); - - GParamSpec *use_class_spec = g_param_spec_enum ("usage", "Usage", @@ -226,10 +237,6 @@ psppire_window_class_init (PsppireWindowClass *class) use_class_spec); - class->name_table = g_hash_table_new (g_str_hash, g_str_equal); - - g_hash_table_insert (class->name_table, "Untitled", NULL); - the_class = class; parent_class = g_type_class_peek_parent (class); } @@ -249,16 +256,86 @@ static void psppire_window_base_finalize (PsppireWindowClass *class, gpointer class_data) { - g_hash_table_destroy (class->name_table); } +static void +insert_menuitem_into_menu (PsppireWindow *window, gpointer key) +{ + GtkWidget *item = gtk_check_menu_item_new_with_label (key); + + gtk_widget_show (item); + + gtk_menu_shell_append (window->menu, item); + + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), + (psppire_window_register_lookup (psppire_window_register_new (), key) == window)); + + g_hash_table_insert (window->menuitem_table, key, item); +} + +static void +insert_item (gpointer key, gpointer value, gpointer data) +{ + PsppireWindow *window = PSPPIRE_WINDOW (data); + + if ( NULL != g_hash_table_lookup (window->menuitem_table, key)) + return; + + insert_menuitem_into_menu (window, key); +} + +/* Insert a new item into the window menu */ +static void +insert_menuitem (GObject *reg, const gchar *key, gpointer data) +{ + PsppireWindow *window = PSPPIRE_WINDOW (data); + + insert_menuitem_into_menu (window, (gpointer) key); +} + + +static void +remove_menuitem (PsppireWindowRegister *reg, const gchar *key, gpointer data) +{ + PsppireWindow *window = PSPPIRE_WINDOW (data); + GtkWidget *item ; + + if ( !GTK_WIDGET_REALIZED (window)) + return; + + item = g_hash_table_lookup (window->menuitem_table, key); + + g_hash_table_remove (window->menuitem_table, key); + + gtk_container_remove (GTK_CONTAINER (window->menu), item); +} +static void +insert_existing_items (PsppireWindow *window) +{ + psppire_window_register_foreach (psppire_window_register_new (), insert_item, window); +} static void psppire_window_init (PsppireWindow *window) { window->name = NULL; - window->finalized = FALSE; + window->menu = NULL; + + window->menuitem_table = g_hash_table_new (g_str_hash, g_str_equal); + + + g_signal_connect (window, "realize", G_CALLBACK (insert_existing_items), NULL); + + window->insert_handler = g_signal_connect (psppire_window_register_new (), + "inserted", + G_CALLBACK (insert_menuitem), + window); + + window->remove_handler = g_signal_connect (psppire_window_register_new (), + "removed", + G_CALLBACK (remove_menuitem), + window); } @@ -287,27 +364,6 @@ psppire_window_set_filename (PsppireWindow *w, const gchar *filename) g_object_set (w, "filename", filename, NULL); } - -static void -minimise_all (gpointer key, - gpointer value, - gpointer user_data) -{ - PsppireWindow *w = PSPPIRE_WINDOW (value); - - gtk_window_iconify (GTK_WINDOW (w)); -} - - - -void -psppire_window_minimise_all (void) -{ - g_hash_table_foreach (the_class->name_table, minimise_all, NULL); -} - - - GType @@ -329,9 +385,26 @@ psppire_window_usage_get_type (void) { 0, NULL, NULL } }; - etype = g_enum_register_static - (g_intern_static_string ("PsppireWindowUsage"), values); + etype = g_enum_register_static (g_intern_static_string ("PsppireWindowUsage"), + values); } return etype; } + + + +static void +minimise_window (gpointer key, gpointer value, gpointer data) +{ + gtk_window_iconify (GTK_WINDOW (value)); +} + + +void +psppire_window_minimise_all (void) +{ + PsppireWindowRegister *reg = psppire_window_register_new (); + + g_hash_table_foreach (reg->name_table, minimise_window, NULL); +} diff --git a/src/ui/gui/psppire-window.h b/src/ui/gui/psppire-window.h index ca5136a7..ef7feb23 100644 --- a/src/ui/gui/psppire-window.h +++ b/src/ui/gui/psppire-window.h @@ -23,6 +23,7 @@ #include #include #include +#include G_BEGIN_DECLS @@ -62,15 +63,18 @@ struct _PsppireWindow /* */ gchar *name; - gboolean finalized; PsppireWindowUsage usage; + + GHashTable *menuitem_table; + GtkMenuShell *menu; + + guint insert_handler; + guint remove_handler; }; struct _PsppireWindowClass { GtkWindowClass parent_class; - - GHashTable *name_table; }; GType psppire_window_get_type (void); -- 2.30.2