1 /* PSPPIRE - a graphical user interface for PSPP.
2    Copyright (C) 2016 Free Software Foundation
3 
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16 
17 #include <config.h>
18 
19 #include "windows-menu.h"
20 #include "psppire-window-register.h"
21 #include "psppire-data-window.h"
22 
23 #include <gettext.h>
24 #define _(msgid) gettext (msgid)
25 #define N_(msgid) msgid
26 
27 static void
minimise(gpointer key,gpointer value,gpointer user_data)28 minimise (gpointer key, gpointer value, gpointer user_data)
29 {
30   PsppireWindow *pw = PSPPIRE_WINDOW (value);
31   gtk_window_iconify (GTK_WINDOW (pw));
32 }
33 
34 static void
min_all(GtkWidget * widget,gpointer ud)35 min_all (GtkWidget *widget, gpointer ud)
36 {
37   PsppireWindowRegister *reg = psppire_window_register_new ();
38 
39   psppire_window_register_foreach (reg, minimise, NULL);
40 }
41 
42 static void
reset_check_state(GtkWidget * widget,gpointer ud)43 reset_check_state (GtkWidget *widget, gpointer ud)
44 {
45   GtkWindow *win = GTK_WINDOW (ud);
46   gboolean state = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget));
47 
48   if (state == TRUE)
49     gtk_window_present (win);
50 
51   /* Prevent the state from actually changing */
52   g_signal_handlers_block_by_func (widget, reset_check_state, ud);
53   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (widget), !state);
54   g_signal_handlers_unblock_by_func (widget, reset_check_state, ud);
55 }
56 
57 static void
add_menuitem(gpointer key,gpointer value,gpointer user_data)58 add_menuitem (gpointer key, gpointer value, gpointer user_data)
59 {
60   GtkMenu *menu = GTK_MENU (user_data);
61   PsppireWindow *pw = PSPPIRE_WINDOW (value);
62 
63   GtkWidget *mi = gtk_check_menu_item_new_with_label (key);
64 
65   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi),
66 				  pw == g_object_get_data (G_OBJECT (menu), "toplevel"));
67 
68   g_signal_connect (mi, "toggled", G_CALLBACK (reset_check_state), pw);
69 
70   gtk_container_add (GTK_CONTAINER(menu), mi);
71 }
72 
73 static void
toggle_split_window(PsppireDataWindow * de,GtkCheckMenuItem * ta)74 toggle_split_window (PsppireDataWindow  *de, GtkCheckMenuItem *ta)
75 {
76   psppire_data_editor_split_window (de->data_editor,
77                                    gtk_check_menu_item_get_active (ta));
78 }
79 
80 
81 
82 static void
repopulate_windows_menu(GObject * inst,gchar * name,gpointer data)83 repopulate_windows_menu (GObject *inst, gchar *name, gpointer data)
84 {
85   PsppireWindowRegister *reg = psppire_window_register_new ();
86   GtkMenuItem *mi = GTK_MENU_ITEM (data);
87 
88   GtkWidget *menu = gtk_menu_new ();
89 
90   GtkWindow *toplevel = g_object_get_data (G_OBJECT (mi), "toplevel");
91 
92   GtkWidget *minimize = gtk_menu_item_new_with_mnemonic (_("_Minimize all Windows"));
93 
94   GtkWidget *sep = gtk_separator_menu_item_new ();
95 
96   gtk_menu_attach (GTK_MENU (menu), minimize, 0, 1, 0, 1);
97 
98   if (PSPPIRE_DATA_WINDOW_TYPE == G_OBJECT_TYPE (toplevel))
99     {
100       GtkWidget *split = gtk_check_menu_item_new_with_mnemonic (_("_Split"));
101       gtk_menu_attach (GTK_MENU (menu), split, 0, 1, 1, 2);
102       g_signal_connect_swapped (split, "toggled",
103 				G_CALLBACK (toggle_split_window), toplevel);
104     }
105 
106   gtk_container_add (GTK_CONTAINER (menu), sep);
107 
108   gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), menu);
109 
110   g_object_set_data (G_OBJECT (menu), "toplevel", toplevel);
111 
112   g_hash_table_foreach (reg->name_table, add_menuitem, menu);
113 
114   g_signal_connect (minimize, "activate", G_CALLBACK (min_all), NULL);
115 
116   gtk_widget_show_all (GTK_WIDGET (mi));
117 }
118 
119 static void
on_destroy(GtkWindow * w,gpointer data)120 on_destroy (GtkWindow *w, gpointer data)
121 {
122   PsppireWindowRegister *reg = psppire_window_register_new ();
123 
124   g_signal_handlers_disconnect_by_func (reg, repopulate_windows_menu, w);
125 }
126 
127 GtkWidget *
create_windows_menu(GtkWindow * toplevel)128 create_windows_menu (GtkWindow *toplevel)
129 {
130   PsppireWindowRegister *reg = psppire_window_register_new ();
131 
132   GtkWidget *menuitem = gtk_menu_item_new_with_mnemonic (_("_Windows"));
133 
134   g_object_set_data (G_OBJECT (menuitem), "toplevel", toplevel);
135 
136   g_signal_connect (reg, "removed", G_CALLBACK (repopulate_windows_menu), menuitem);
137   g_signal_connect (reg, "inserted", G_CALLBACK (repopulate_windows_menu), menuitem);
138 
139   g_signal_connect (menuitem, "destroy", G_CALLBACK (on_destroy), NULL);
140 
141   return menuitem;
142 }
143