New (singleton) object psppire-window-register
authorJohn Darrington <john@darrington.wattle.id.au>
Thu, 1 Jan 2009 00:09:36 +0000 (09:09 +0900)
committerJohn Darrington <john@darrington.wattle.id.au>
Thu, 1 Jan 2009 00:09:36 +0000 (09:09 +0900)
src/ui/gui/automake.mk
src/ui/gui/psppire-data-window.c
src/ui/gui/psppire-syntax-window.c
src/ui/gui/psppire-window-register.c [new file with mode: 0644]
src/ui/gui/psppire-window-register.h [new file with mode: 0644]
src/ui/gui/psppire-window.c
src/ui/gui/psppire-window.h

index a458c0f435f6a84ef6248a902f9e576201536d75..b0264ead1a138231bf73bdc6bb7f555c3c0a150b 100644 (file)
@@ -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
index 5facbbd257dfc9f0c3bd78aece4bff2a9f6055b7..fdc4087b964be97201c9ca828fe55626e70fac3e 100644 (file)
@@ -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);
 }
 
index 5b3267441dc50140f495ee2883531e555382688f..766134b2678132abc7eea0425e9a18e62bfe9ea1 100644 (file)
 #include <libpspp/message.h>
 #include <stdlib.h>
 
-
 #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"
 #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 (file)
index 0000000..dfa46c6
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#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 (file)
index 0000000..cc24f4e
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>. */
+
+
+#include <glib-object.h>
+#include <glib.h>
+
+#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__ */
index 767e10541d679ee028cbbee3dae14327699855fb..3da046abdb98c8e54bda7edd3866e4c0af27d136 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <gtk/gtksignal.h>
 #include <gtk/gtkwindow.h>
+#include <gtk/gtkcheckmenuitem.h>
 
 #include <stdlib.h>
 
@@ -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);
-}
-
-
-
 \f
 
 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);
+}
index ca5136a7bafc32cd28696ab0c0efdc52479a5858..ef7feb2326884b746017957b54d7d4e0cfdc7830 100644 (file)
@@ -23,6 +23,7 @@
 #include <glib-object.h>
 #include <gtk/gtkwindow.h>
 #include <gtk/gtkaction.h>
+#include <gtk/gtkmenushell.h>
 
 G_BEGIN_DECLS
 
@@ -62,15 +63,18 @@ struct _PsppireWindow
 
   /* <private> */
   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);