1 /*
2
3 Copyright (c) 2002 Jamis Buck
4 Copyright (c) 2003-2007 Michael Terry
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 */
21
22 #include "../config.h"
23 #include <glib/gi18n.h>
24 #include <gtk/gtk.h>
25 #include "fio.h"
26 #include "xpad-app.h"
27 #include "xpad-pad.h"
28 #include "xpad-pad-group.h"
29 #include "xpad-preferences.h"
30 #include "xpad-tray.h"
31
32 static void xpad_tray_activate_cb (GtkStatusIcon *icon);
33 static void xpad_tray_popup_menu_cb (GtkStatusIcon *icon, guint button, guint time);
34
35 static GtkStatusIcon *docklet = NULL;
36
37 void
xpad_tray_open(void)38 xpad_tray_open (void)
39 {
40 GtkIconTheme *theme;
41
42 xpad_tray_close ();
43
44 theme = gtk_icon_theme_get_default ();
45 if (!gtk_icon_theme_has_icon (theme, PACKAGE))
46 return;
47
48 docklet = gtk_status_icon_new_from_icon_name (PACKAGE);
49
50 if (docklet)
51 {
52 g_signal_connect (docklet, "activate", G_CALLBACK (xpad_tray_activate_cb), NULL);
53 g_signal_connect (docklet, "popup-menu", G_CALLBACK (xpad_tray_popup_menu_cb), NULL);
54 }
55 }
56
57 void
xpad_tray_close(void)58 xpad_tray_close (void)
59 {
60 if (docklet) {
61 g_object_unref (docklet);
62 docklet = NULL;
63 }
64 }
65
66 gboolean
xpad_tray_is_open(void)67 xpad_tray_is_open (void)
68 {
69 if (docklet)
70 return gtk_status_icon_is_embedded (docklet);
71 else
72 return FALSE;
73 }
74
75 static gint
menu_title_compare(GtkWindow * a,GtkWindow * b)76 menu_title_compare (GtkWindow *a, GtkWindow *b)
77 {
78 gchar *title_a = g_utf8_casefold (gtk_window_get_title (a), -1);
79 gchar *title_b = g_utf8_casefold (gtk_window_get_title (b), -1);
80
81 gint rv = g_utf8_collate (title_a, title_b);
82
83 g_free (title_a);
84 g_free (title_b);
85
86 return rv;
87 }
88
89 static void
menu_show_all(XpadPadGroup * group)90 menu_show_all (XpadPadGroup *group)
91 {
92 GSList *pads = xpad_pad_group_get_pads (xpad_app_get_pad_group ());
93 g_slist_foreach (pads, (GFunc) gtk_window_present, NULL);
94 g_slist_free (pads);
95 }
96
97 static void
menu_spawn(XpadPadGroup * group)98 menu_spawn (XpadPadGroup *group)
99 {
100 GtkWidget *pad = xpad_pad_new (group);
101 gtk_widget_show (pad);
102 }
103
104 static void
xpad_tray_popup_menu_cb(GtkStatusIcon * icon,guint button,guint time)105 xpad_tray_popup_menu_cb (GtkStatusIcon *icon, guint button, guint time)
106 {
107 GtkWidget *menu, *item;
108 GSList *pads, *l;
109 gint n;
110
111 menu = gtk_menu_new ();
112 pads = xpad_pad_group_get_pads (xpad_app_get_pad_group ());
113
114 item = gtk_image_menu_item_new_from_stock (GTK_STOCK_NEW, NULL);
115 g_signal_connect_swapped (item, "activate", G_CALLBACK (menu_spawn), xpad_app_get_pad_group ());
116 gtk_container_add (GTK_CONTAINER (menu), item);
117 gtk_widget_show (item);
118
119 item = gtk_separator_menu_item_new ();
120 gtk_container_add (GTK_CONTAINER (menu), item);
121 gtk_widget_show (item);
122
123 item = gtk_menu_item_new_with_mnemonic (_("_Show All"));
124 g_signal_connect_swapped (item, "activate", G_CALLBACK (menu_show_all), xpad_app_get_pad_group ());
125 gtk_container_add (GTK_CONTAINER (menu), item);
126 gtk_widget_show (item);
127 if (!pads)
128 gtk_widget_set_sensitive (item, FALSE);
129
130 item = gtk_image_menu_item_new_with_mnemonic (_("_Close All"));
131 g_signal_connect_swapped (item, "activate", G_CALLBACK (xpad_pad_group_close_all), xpad_app_get_pad_group ());
132 gtk_container_add (GTK_CONTAINER (menu), item);
133 gtk_widget_show (item);
134 if (!pads)
135 gtk_widget_set_sensitive (item, FALSE);
136
137 item = gtk_separator_menu_item_new ();
138 gtk_container_add (GTK_CONTAINER (menu), item);
139 gtk_widget_show (item);
140
141 /**
142 * Order pads according to title.
143 */
144 pads = g_slist_sort (pads, (GCompareFunc) menu_title_compare);
145
146 /**
147 * Populate list of windows.
148 */
149 for (l = pads, n = 1; l; l = l->next, n++)
150 {
151 gchar *title;
152 gchar *tmp_title;
153
154 tmp_title = g_strdup (gtk_window_get_title (GTK_WINDOW (l->data)));
155 str_replace_tokens (&tmp_title, '_', "__");
156 if (n < 10)
157 title = g_strdup_printf ("_%i. %s", n, tmp_title);
158 else
159 title = g_strdup_printf ("%i. %s", n, tmp_title);
160 g_free (tmp_title);
161
162 item = gtk_menu_item_new_with_mnemonic (title);
163 g_signal_connect_swapped (item, "activate", G_CALLBACK (gtk_window_present), l->data);
164 gtk_container_add (GTK_CONTAINER (menu), item);
165 gtk_widget_show (item);
166
167 g_free (title);
168 }
169 g_slist_free (pads);
170
171 if (pads)
172 {
173 item = gtk_separator_menu_item_new ();
174 gtk_container_add (GTK_CONTAINER (menu), item);
175 gtk_widget_show (item);
176 }
177
178 item = gtk_image_menu_item_new_from_stock (GTK_STOCK_PREFERENCES, NULL);
179 g_signal_connect (item, "activate", G_CALLBACK (xpad_preferences_open), NULL);
180 gtk_container_add (GTK_CONTAINER (menu), item);
181 gtk_widget_show (item);
182
183 item = gtk_image_menu_item_new_from_stock (GTK_STOCK_QUIT, NULL);
184 g_signal_connect (item, "activate", G_CALLBACK (gtk_main_quit), NULL);
185 gtk_container_add (GTK_CONTAINER (menu), item);
186 gtk_widget_show (item);
187
188 gtk_menu_popup (GTK_MENU (menu), NULL, NULL, gtk_status_icon_position_menu, icon, button, time);
189 }
190
191 static void
xpad_tray_activate_cb(GtkStatusIcon * icon)192 xpad_tray_activate_cb (GtkStatusIcon *icon)
193 {
194 GSList *pads = xpad_pad_group_get_pads (xpad_app_get_pad_group ());
195 g_slist_foreach (pads, (GFunc) gtk_window_present, NULL);
196 g_slist_free (pads);
197 }
198
199