Reimplement the Windows menu.
authorJohn Darrington <john@darrington.wattle.id.au>
Sat, 30 Jan 2016 10:45:28 +0000 (11:45 +0100)
committerJohn Darrington <john@darrington.wattle.id.au>
Sat, 30 Jan 2016 16:47:46 +0000 (17:47 +0100)
Fixes bug #45253

13 files changed:
src/ui/gui/automake.mk
src/ui/gui/data-editor.ui
src/ui/gui/output-window.ui
src/ui/gui/psppire-data-window.c
src/ui/gui/psppire-output-window.c
src/ui/gui/psppire-syntax-window.c
src/ui/gui/psppire-window-register.c
src/ui/gui/psppire-window-register.h
src/ui/gui/psppire-window.c
src/ui/gui/psppire-window.h
src/ui/gui/syntax-editor.ui
src/ui/gui/windows-menu.c [new file with mode: 0644]
src/ui/gui/windows-menu.h [new file with mode: 0644]

index 43068f2876c87d638ac82a3ccffb0034131ebc9c..a88e8e733dc5353602a43752276ca3d6a0c9e891 100644 (file)
@@ -322,7 +322,9 @@ src_ui_gui_psppire_SOURCES = \
        src/ui/gui/widget-io.c \
        src/ui/gui/widget-io.h \
        src/ui/gui/widgets.c \
-       src/ui/gui/widgets.h
+       src/ui/gui/widgets.h \
+       src/ui/gui/windows-menu.c \
+       src/ui/gui/windows-menu.h
 
 
 OBSOLETE = \
index 23f3ad8864d0af8e74f210e38560947f5c1bdbce..8829e4eca661a013a5c8b8efd0e41073bd0a496a 100644 (file)
             <property name="stock-id">utilities-data-file-comments</property>
           </object>
         </child>
-        <child>
-          <object class="GtkAction" id="windows">
-            <property name="name">windows</property>
-            <property name="label" translatable="yes">_Windows</property>
-          </object>
-        </child>
-        <child>
-          <object class="GtkAction" id="windows_minimise_all">
-            <property name="name">windows_minimise_all</property>
-            <property name="label" translatable="yes">_Minimize All Windows</property>
-            <property name="stock-id">windows-minimize-all</property>
-          </object>
-        </child>
-        <child>
-          <object class="GtkToggleAction" id="windows_split">
-            <property name="name">windows_split</property>
-            <property name="label" translatable="yes">_Split</property>
-            <property name="stock-id">windows-split</property>
-          </object>
-        </child>
       </object>
     </child>
     <ui>
           <menuitem action="utilities_variables"/>
           <menuitem action="utilities_comments"/>
         </menu>
-        <menu action="windows">
-          <menuitem action="windows_minimise_all"/>
-          <menuitem action="windows_split"/>
-        </menu>
       </menubar>
       <toolbar action="toolbar">
         <toolitem name="toolbar_open" action="file_open"/>
index a8aa42db42ec7b404c4063c850cbe68dd83c9fca..1a1a02f9405e4b4067f781cfd8ad00a4f5155f63 100644 (file)
             <property name="label" translatable="yes">_Copy</property>
           </object>
         </child>
-        <child>
-          <object class="GtkAction" id="windows_menuitem">
-            <property name="name">windows_menuitem</property>
-            <property name="label" translatable="yes">_Windows</property>
-          </object>
-        </child>
-        <child>
-          <object class="GtkAction" id="windows_minimise-all">
-            <property name="stock-id">windows-minimize-all</property>
-            <property name="name">windows_minimise-all</property>
-            <property name="label" translatable="yes">_Minimize All Windows</property>
-          </object>
-        </child>
       </object>
     </child>
     <ui>
@@ -69,9 +56,6 @@
           <menuitem action="edit_copy"/>
           <menuitem action="edit_select-all"/>
         </menu>
-        <menu action="windows_menuitem">
-          <menuitem action="windows_minimise-all"/>
-        </menu>
       </menubar>
     </ui>
   </object>
index d7b8ae6f836d7277a66ec02e427bdcc288ef5bff..7917274da56a619284018ef89cc5f970d06db4c9 100644 (file)
@@ -36,6 +36,7 @@
 #include "ui/gui/psppire-encoding-selector.h"
 #include "ui/gui/psppire-syntax-window.h"
 #include "ui/gui/psppire-window.h"
+#include "ui/gui/windows-menu.h"
 #include "ui/gui/psppire.h"
 #include "ui/syntax-gen.h"
 
@@ -722,13 +723,6 @@ toggle_value_labels (PsppireDataWindow  *de, GtkToggleAction *ta)
   g_object_set (de->data_editor, "value-labels", gtk_toggle_action_get_active (ta), NULL);
 }
 
-static void
-toggle_split_window (PsppireDataWindow  *de, GtkToggleAction *ta)
-{
-  psppire_data_editor_split_window (de->data_editor,
-                                   gtk_toggle_action_get_active (ta));
-}
-
 
 static void
 file_quit (PsppireDataWindow *de)
@@ -906,15 +900,10 @@ enable_save (PsppireDataWindow *dw)
 static void
 psppire_data_window_init (PsppireDataWindow *de)
 {
-  GtkWidget *w ;
   de->builder = builder_new ("data-editor.ui");
 
   de->ui_manager = GTK_UI_MANAGER (get_object_assert (de->builder, "uimanager1", GTK_TYPE_UI_MANAGER));
 
-  w = gtk_ui_manager_get_widget (de->ui_manager, "/ui/menubar/windows/windows_minimise_all");
-
-  PSPPIRE_WINDOW (de)->menu = GTK_MENU_SHELL (gtk_widget_get_parent (w));
-
   de->uim = NULL;
   de->merge_id = 0;
 }
@@ -1110,10 +1099,7 @@ psppire_data_window_finish_init (PsppireDataWindow *de,
 
   connect_action (de, "transform_run-pending", G_CALLBACK (execute));
 
-  connect_action (de, "windows_minimise_all", G_CALLBACK (psppire_window_minimise_all));
-
-  g_signal_connect_swapped (get_action_assert (de->builder, "windows_split"), "toggled", G_CALLBACK (toggle_split_window), de);
-
+  gtk_menu_shell_append (GTK_MENU_SHELL (menubar),  create_windows_menu (GTK_WINDOW (de)));
   gtk_menu_shell_append (GTK_MENU_SHELL (menubar),  create_help_menu (GTK_WINDOW (de)));
   
   g_signal_connect (de->data_editor, "notify::ui-manager",
index 795804a82278d60fbf8810a0135ad010a72f7f00..469966af2325adf73faafbba8e29194dcfc7168a 100644 (file)
@@ -38,6 +38,7 @@
 #include "ui/gui/help-menu.h"
 #include "ui/gui/builder-wrapper.h"
 #include "ui/gui/psppire-output-view.h"
+#include "ui/gui/windows-menu.h"
 
 #include "gl/xalloc.h"
 
@@ -494,24 +495,14 @@ psppire_output_window_init (PsppireOutputWindow *window)
                    G_CALLBACK (cancel_urgency),
                    NULL);
 
-  g_signal_connect (get_action_assert (xml,"windows_minimise-all"),
-                   "activate",
-                   G_CALLBACK (psppire_window_minimise_all),
-                   NULL);
-
-  {
-    GtkWidget *w;
-    GtkUIManager *uim = GTK_UI_MANAGER (get_object_assert (xml, "uimanager1", GTK_TYPE_UI_MANAGER));
+  GtkWidget *menubar = get_widget_assert (xml, "menubar");
 
-    GtkWidget *menubar = get_widget_assert (xml, "menubar");
+  gtk_menu_shell_append (GTK_MENU_SHELL (menubar),
+                        create_windows_menu (GTK_WINDOW (window)));
+    
+  gtk_menu_shell_append (GTK_MENU_SHELL (menubar),
+                        create_help_menu (GTK_WINDOW (window)));
 
-    gtk_menu_shell_append (GTK_MENU_SHELL (menubar),  create_help_menu (GTK_WINDOW (window)));
-
-    w = gtk_ui_manager_get_widget (uim,"/ui/menubar/windows_menuitem/windows_minimise-all");
-
-    PSPPIRE_WINDOW (window)->menu =
-      GTK_MENU_SHELL (gtk_widget_get_parent (w));
-  }
 
   g_signal_connect_swapped (get_action_assert (xml, "file_export"), "activate",
                             G_CALLBACK (psppire_output_window_export), window);
index 66838dd307172943d0a59fd26097013192d8e6c4..f8758a0cd7e2e6a5a2b1b7dbbc6724677b9f289b 100644 (file)
@@ -36,8 +36,8 @@
 #include "ui/gui/psppire-encoding-selector.h"
 #include "ui/gui/psppire-lex-reader.h"
 #include "ui/gui/psppire-syntax-window.h"
-#include "ui/gui/psppire-window-register.h"
 #include "ui/gui/psppire.h"
+#include "ui/gui/windows-menu.h"
 
 #include "gl/localcharset.h"
 #include "gl/xalloc.h"
@@ -859,19 +859,11 @@ psppire_syntax_window_init (PsppireSyntaxWindow *window)
                    G_CALLBACK (on_run_to_end),
                    window);
 
-  g_signal_connect (get_action_assert (xml,"windows_minimise_all"),
-                   "activate",
-                   G_CALLBACK (psppire_window_minimise_all), NULL);
-
-
-  {
-    GtkUIManager *uim = GTK_UI_MANAGER (get_object_assert (xml, "uimanager1", GTK_TYPE_UI_MANAGER));
-    GtkWidget *w = gtk_ui_manager_get_widget (uim,"/ui/menubar/windows/windows_minimise_all");
-
-    gtk_menu_shell_append (GTK_MENU_SHELL (menubar),  create_help_menu (GTK_WINDOW (window)));
+  gtk_menu_shell_append (GTK_MENU_SHELL (menubar),
+                        create_windows_menu (GTK_WINDOW (window)));
 
-    PSPPIRE_WINDOW (window)->menu = GTK_MENU_SHELL (gtk_widget_get_parent (w));
-  }
+  gtk_menu_shell_append (GTK_MENU_SHELL (menubar),
+                        create_help_menu (GTK_WINDOW (window)));
 
   g_object_unref (xml);
 }
index dbab4b18c7d4f84bb56d773f29677621d113ee10..75fb6efcd309f73a459c978bc399b36240dc1aa4 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2008  Free Software Foundation
+   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
@@ -146,13 +146,11 @@ psppire_window_register_insert (PsppireWindowRegister *wr, PsppireWindow *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);
+  g_signal_emit (wr, signals[REMOVED], 0, name);
 }
 
 PsppireWindow *
index 14b2a9461ef9ace5d55d753d5bb575797ac3036c..cf4f4d8ec9a41773fae12e9e2cf8e85069a554d6 100644 (file)
@@ -87,6 +87,8 @@ void psppire_window_register_foreach (PsppireWindowRegister *wr, GHFunc func,
 
 gint psppire_window_register_n_items (PsppireWindowRegister *wr);
 
+GtkWidget *create_windows_menu (GtkWindow *toplevel);
+
 
 G_END_DECLS
 
index c0268e67b9d87e53bb3f84f51772ca80ea2beec6..6fb0b87c47209d6992d43db005dc0ecc9621cc29 100644 (file)
@@ -313,62 +313,15 @@ psppire_window_base_init (PsppireWindowClass *class)
 
 
 
-static void
-menu_toggled (GtkCheckMenuItem *mi, gpointer data)
-{
-#if GTK3_TRANSITION
-  /* Prohibit changes to the state */
-  mi->active = !mi->active;
-#endif
-}
-
-
-/* Look up the window associated with this menuitem and present it to the user */
-static void
-menu_activate (GtkMenuItem *mi, gpointer data)
-{
-  const gchar *key = data;
-
-  PsppireWindowRegister *reg = psppire_window_register_new ();
-
-  PsppireWindow *window = psppire_window_register_lookup (reg, key);
-
-  gtk_window_present (GTK_WINDOW (window));
-}
-
 static void
 insert_menuitem_into_menu (PsppireWindow *window, gpointer key)
 {
   gchar *filename;
   GtkWidget *item;
-
-  /* Add a separator before adding the first real item.  If we add a separator
-     at any other time, sometimes GtkUIManager removes it. */
-  if (!window->added_separator)
-    {
-      GtkWidget *separator = gtk_separator_menu_item_new ();
-      gtk_widget_show (separator);
-      gtk_menu_shell_append (window->menu, separator);
-      window->added_separator = TRUE;
-    }
-
   filename = g_filename_display_name (key);
   item = gtk_check_menu_item_new_with_label (filename);
   g_free (filename);
-
-  g_signal_connect (item, "toggled", G_CALLBACK (menu_toggled), NULL);
-  g_signal_connect (item, "activate", G_CALLBACK (menu_activate), key);
-
-  gtk_widget_show (item);
-
-  gtk_menu_shell_append (window->menu, item);
-
-#if GTK3_TRANSITION
-  /* Set the state without emitting a signal */
-  GTK_CHECK_MENU_ITEM (item)->active =
-   (psppire_window_register_lookup (psppire_window_register_new (), key) == window);
-#endif
-
+  
   g_hash_table_insert (window->menuitem_table, key, item);
 }
 
@@ -397,14 +350,7 @@ static void
 remove_menuitem (PsppireWindowRegister *reg, const gchar *key, gpointer data)
 {
   PsppireWindow *window = PSPPIRE_WINDOW (data);
-  GtkWidget *item ;
-
-  item = g_hash_table_lookup (window->menuitem_table, key);
-
   g_hash_table_remove (window->menuitem_table, key);
-
-  if (GTK_IS_CONTAINER (window->menu))
-    gtk_container_remove (GTK_CONTAINER (window->menu), item);
 }
 
 static void
@@ -452,7 +398,6 @@ on_delete (PsppireWindow *w, GdkEvent *event, gpointer user_data)
 static void
 psppire_window_init (PsppireWindow *window)
 {
-  window->menu = NULL;
   window->filename = NULL;
   window->basename = NULL;
   window->id = NULL;
@@ -619,7 +564,7 @@ psppire_window_model_get_type (void)
       window_model_type =
        g_type_register_static (G_TYPE_INTERFACE, "PsppireWindowModel",
                                &window_model_info, 0);
-
+      
       g_type_interface_add_prerequisite (window_model_type, G_TYPE_OBJECT);
     }
 
index 0e57b4d78de57965160e67a9802a758649983691..bc1b0f0b280770b87ae1414b7da4dc10b63c2e97 100644 (file)
@@ -68,7 +68,6 @@ struct _PsppireWindow
   gchar *list_name;            /* Name for "Windows" menu list. */
 
   GHashTable *menuitem_table;
-  GtkMenuShell *menu;
 
   guint insert_handler;
   guint remove_handler;
index 7b48bc6f750de6bb32379fc46c88d0554da68675..797a7f04e0309483e357ab671800f17b9868ea5b 100644 (file)
             <property name="label" translatable="yes">To End</property>
           </object>
         </child>
-        <child>
-          <object class="GtkAction" id="windows">
-            <property name="name">windows</property>
-            <property name="label" translatable="yes">_Windows</property>
-          </object>
-        </child>
-        <child>
-          <object class="GtkAction" id="windows_minimise_all">
-            <property name="stock-id">windows-minimize-all</property>
-            <property name="name">windows_minimise_all</property>
-            <property name="label" translatable="yes">_Minimize All Windows</property>
-          </object>
-        </child>
       </object>
     </child>
     <ui>
           <menuitem action="run_current_line"/>
           <menuitem action="run_to_end"/>
         </menu>
-        <menu action="windows">
-          <menuitem action="windows_minimise_all"/>
-        </menu>
       </menubar>
     </ui>
   </object>
diff --git a/src/ui/gui/windows-menu.c b/src/ui/gui/windows-menu.c
new file mode 100644 (file)
index 0000000..5390b0e
--- /dev/null
@@ -0,0 +1,151 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2016 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 "windows-menu.h"
+#include "psppire-window-register.h"
+#include "psppire-data-window.h"
+
+#include <gettext.h>
+#define _(msgid) gettext (msgid)
+#define N_(msgid) msgid
+
+static void
+minimise (gpointer key, gpointer value, gpointer user_data)
+{
+  PsppireWindow *pw = PSPPIRE_WINDOW (value);
+  gtk_window_iconify (GTK_WINDOW (pw));
+}
+
+static void
+min_all (GtkWidget *widget, gpointer ud)
+{
+  PsppireWindowRegister *reg = psppire_window_register_new ();
+
+  psppire_window_register_foreach (reg, minimise, NULL);
+}
+
+static void
+reset_check_state (GtkWidget *widget, gpointer ud)
+{
+  /* Prevent the state from actually changing */
+  g_signal_handlers_block_by_func (widget, reset_check_state, ud);
+  gboolean state = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget));
+  gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (widget), !state);
+  g_signal_handlers_unblock_by_func (widget, reset_check_state, ud);
+}
+
+static gboolean
+raise_window (GtkWidget *widget, GdkEvent *ev, gpointer ud)
+{
+  GtkWindow *win = GTK_WINDOW (ud);
+  gtk_window_present_with_time (win, ((GdkEventButton *)ev)->time);
+  
+  return FALSE;
+}
+
+
+static void
+add_menuitem (gpointer key, gpointer value, gpointer user_data)
+{
+  GtkMenu *menu = GTK_MENU (user_data);
+  PsppireWindow *pw = PSPPIRE_WINDOW (value);
+
+  GtkWidget *mi = gtk_check_menu_item_new_with_label (key);
+
+  gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi),
+                                 pw == g_object_get_data (G_OBJECT (menu), "toplevel"));
+
+  g_signal_connect (mi, "toggled", G_CALLBACK (reset_check_state), pw);
+
+  g_signal_connect (mi, "button-press-event", G_CALLBACK (raise_window), pw);
+  
+
+  gtk_container_add (GTK_CONTAINER(menu), mi);
+}
+
+static void
+toggle_split_window (PsppireDataWindow  *de, GtkCheckMenuItem *ta)
+{
+  psppire_data_editor_split_window (de->data_editor,
+                                   gtk_check_menu_item_get_active (ta));
+}
+
+
+
+static void
+repopulate_windows_menu (GObject *inst, gchar *name, gpointer data)
+{
+  PsppireWindowRegister *reg = psppire_window_register_new ();
+  GtkMenuItem *mi = GTK_MENU_ITEM (data);
+
+  GtkWidget *menu = gtk_menu_new ();
+
+  GtkWindow *toplevel = g_object_get_data (G_OBJECT (mi), "toplevel");
+
+  GtkWidget *minimize = gtk_menu_item_new_with_mnemonic (_("_Minimize all Windows"));
+  GtkWidget *split = gtk_check_menu_item_new_with_mnemonic (_("_Split"));
+
+  
+  GtkWidget *sep = gtk_separator_menu_item_new ();
+    
+  gtk_menu_attach (GTK_MENU (menu), minimize, 0, 1, 0, 1);
+
+  if (PSPPIRE_DATA_WINDOW_TYPE == G_OBJECT_TYPE (toplevel) )
+    {
+      gtk_menu_attach (GTK_MENU (menu), split, 0, 1, 1, 2);
+      g_signal_connect_swapped (split, "toggled",
+                               G_CALLBACK (toggle_split_window), toplevel);
+    }
+    
+  gtk_container_add (GTK_CONTAINER (menu), sep);
+
+  gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), menu);
+
+  g_object_set_data (G_OBJECT (menu), "toplevel", toplevel);
+  
+  g_hash_table_foreach (reg->name_table, add_menuitem, menu);
+
+  g_signal_connect (minimize, "activate", G_CALLBACK (min_all), NULL);
+  
+  gtk_widget_show_all (GTK_WIDGET (mi));
+}
+
+static void
+on_destroy (GtkWindow *w, gpointer data)
+{
+  PsppireWindowRegister *reg = psppire_window_register_new ();
+
+  g_signal_handlers_disconnect_by_func (reg, repopulate_windows_menu, w);
+}
+
+GtkWidget *
+create_windows_menu (GtkWindow *toplevel)
+{
+  PsppireWindowRegister *reg = psppire_window_register_new ();
+  
+  GtkWidget *menuitem = gtk_menu_item_new_with_mnemonic (_("_Windows"));
+
+  g_object_set_data (G_OBJECT (menuitem), "toplevel", toplevel);
+  
+  g_signal_connect (reg, "removed", G_CALLBACK (repopulate_windows_menu), menuitem);
+  g_signal_connect (reg, "inserted", G_CALLBACK (repopulate_windows_menu), menuitem);
+
+  g_signal_connect (menuitem, "destroy", G_CALLBACK (on_destroy), NULL);
+
+  return menuitem;
+}
diff --git a/src/ui/gui/windows-menu.h b/src/ui/gui/windows-menu.h
new file mode 100644 (file)
index 0000000..538c0fd
--- /dev/null
@@ -0,0 +1,25 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2016 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/>. */
+
+
+#ifndef WINDOWS_MENU_H
+#define WINDOWS_MENU_H
+
+#include <gtk/gtk.h>
+
+GtkWidget * create_windows_menu (GtkWindow *toplevel);
+
+#endif