1 /*
2 * Copyright © 2005 Richard Hoelscher
3 * Copyright © 2006 Andreas Røsdal
4 * Copyright © 2007 Christian Persch
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 *
20 * Authors:
21 * Richard Hoelscher <rah@rahga.com>
22 */
23
24 #include <config.h>
25
26 #include <string.h>
27 #include <gtk/gtk.h>
28 #include <glib/gi18n.h>
29
30 #include "ar-runtime.h"
31
32 #include "ar-stock.h"
33
34 static void
menu_item_select_cb(GtkWidget * widget,GtkStatusbar * statusbar)35 menu_item_select_cb (GtkWidget * widget, GtkStatusbar * statusbar)
36 {
37 GtkAction *action;
38 gchar *tooltip;
39 guint context_id;
40
41 context_id = gtk_statusbar_get_context_id (statusbar, "games-tooltip");
42
43 action = gtk_activatable_get_related_action (GTK_ACTIVATABLE (widget));
44 g_return_if_fail (action != NULL);
45
46 g_object_get (action, "tooltip", &tooltip, NULL);
47
48 if (tooltip) {
49 gtk_statusbar_push (statusbar, context_id, tooltip);
50 g_free (tooltip);
51 }
52 }
53
54 static void
menu_item_deselect_cb(GtkWidget * widget,GtkStatusbar * statusbar)55 menu_item_deselect_cb (GtkWidget * widget, GtkStatusbar * statusbar)
56 {
57 guint context_id;
58
59 context_id = gtk_statusbar_get_context_id (statusbar, "games-tooltip");
60 gtk_statusbar_pop (statusbar, context_id);
61 }
62
63 static void
connect_proxy_cb(GtkUIManager * ui_manager,GtkAction * action,GtkWidget * proxy,GtkWidget * statusbar)64 connect_proxy_cb (GtkUIManager * ui_manager,
65 GtkAction * action,
66 GtkWidget * proxy, GtkWidget * statusbar)
67 {
68 if (!GTK_IS_MENU_ITEM (proxy))
69 return;
70
71 g_signal_connect (proxy, "select",
72 G_CALLBACK (menu_item_select_cb), statusbar);
73 g_signal_connect (proxy, "deselect",
74 G_CALLBACK (menu_item_deselect_cb), statusbar);
75 }
76
77 static void
disconnect_proxy_cb(GtkUIManager * ui_manager,GtkAction * action,GtkWidget * proxy,GtkWidget * statusbar)78 disconnect_proxy_cb (GtkUIManager * ui_manager,
79 GtkAction * action,
80 GtkWidget * proxy, GtkWidget * statusbar)
81 {
82 if (!GTK_IS_MENU_ITEM (proxy))
83 return;
84
85 g_signal_handlers_disconnect_by_func
86 (proxy, G_CALLBACK (menu_item_select_cb), statusbar);
87 g_signal_handlers_disconnect_by_func
88 (proxy, G_CALLBACK (menu_item_deselect_cb), statusbar);
89 }
90
91 /**
92 * Call this once, after creating the UI Manager but before
93 * you start adding actions. Then, whenever an action is added,
94 * connect_proxy() will set tooltips to be displayed in the statusbar.
95 */
96 void
ar_stock_prepare_for_statusbar_tooltips(GtkUIManager * ui_manager,GtkWidget * statusbar)97 ar_stock_prepare_for_statusbar_tooltips (GtkUIManager * ui_manager,
98 GtkWidget * statusbar)
99 {
100 g_signal_connect (ui_manager, "connect-proxy",
101 G_CALLBACK (connect_proxy_cb), statusbar);
102 g_signal_connect (ui_manager, "disconnect-proxy",
103 G_CALLBACK (disconnect_proxy_cb), statusbar);
104 }
105
106 /* This will become GTK_CHECK_VERSION (2, 15, x) once the patch from gtk+ bug 511332 is committed */
107 #undef HAVE_GTK_ICON_FACTORY_ADD_ALIAS
108
109 #ifndef HAVE_GTK_ICON_FACTORY_ADD_ALIAS
110
111 static void
register_stock_icon(GtkIconFactory * icon_factory,const char * stock_id,const char * icon_name)112 register_stock_icon (GtkIconFactory * icon_factory,
113 const char * stock_id,
114 const char * icon_name)
115 {
116 GtkIconSource *source;
117 GtkIconSet *set;
118
119 set = gtk_icon_set_new ();
120
121 source = gtk_icon_source_new ();
122 gtk_icon_source_set_icon_name (source, icon_name);
123 gtk_icon_set_add_source (set, source);
124 gtk_icon_source_free (source);
125
126 gtk_icon_factory_add (icon_factory, stock_id, set);
127 gtk_icon_set_unref (set);
128 }
129
130 static void
register_stock_icon_bidi(GtkIconFactory * icon_factory,const char * stock_id,const char * icon_name_ltr,const char * icon_name_rtl)131 register_stock_icon_bidi (GtkIconFactory * icon_factory,
132 const char * stock_id,
133 const char * icon_name_ltr,
134 const char * icon_name_rtl)
135 {
136 GtkIconSource *source;
137 GtkIconSet *set;
138
139 set = gtk_icon_set_new ();
140
141 source = gtk_icon_source_new ();
142 gtk_icon_source_set_icon_name (source, icon_name_ltr);
143 gtk_icon_source_set_direction (source, GTK_TEXT_DIR_LTR);
144 gtk_icon_source_set_direction_wildcarded (source, FALSE);
145 gtk_icon_set_add_source (set, source);
146 gtk_icon_source_free (source);
147
148 source = gtk_icon_source_new ();
149 gtk_icon_source_set_icon_name (source, icon_name_rtl);
150 gtk_icon_source_set_direction (source, GTK_TEXT_DIR_RTL);
151 gtk_icon_source_set_direction_wildcarded (source, FALSE);
152 gtk_icon_set_add_source (set, source);
153 gtk_icon_source_free (source);
154
155 gtk_icon_factory_add (icon_factory, stock_id, set);
156 gtk_icon_set_unref (set);
157 }
158
159 #endif /* HAVE_GTK_ICON_FACTORY_ADD_ALIAS */
160
161 void
ar_stock_init(void)162 ar_stock_init (void)
163 {
164 /* These stocks have a gtk stock icon */
165 const char *stock_icon_aliases[][2] = {
166 { AR_STOCK_CONTENTS, "help-contents" },
167 { AR_STOCK_HINT, "dialog-information" },
168 { AR_STOCK_NEW_GAME, "document-new" },
169 { AR_STOCK_START_NEW_GAME, "document-new" },
170 { AR_STOCK_RESET, "edit-clear" },
171 { AR_STOCK_RESTART_GAME, "view-refresh" },
172 { AR_STOCK_FULLSCREEN, "view-fullscreen" },
173 { AR_STOCK_LEAVE_FULLSCREEN, "view-restore" },
174 { AR_STOCK_PAUSE_GAME, "media-playback-pause" },
175 };
176
177 #ifndef HAVE_GTK_ICON_FACTORY_ADD_ALIAS
178 const char *stock_icon_aliases_bidi[][3] = {
179 { AR_STOCK_REDO_MOVE, "edit-redo", "edit-undo" },
180 { AR_STOCK_UNDO_MOVE, "edit-undo", "edit-redo" },
181 };
182 #endif
183
184 /* Private icon names */
185 const char *private_icon_names[][2] = {
186 { AR_STOCK_DEAL_CARDS, "cards-deal" }
187 };
188
189 static const GtkStockItem ar_stock_items[] = {
190 { AR_STOCK_CONTENTS, N_("_Contents"), 0, GDK_KEY_F1, NULL },
191 { AR_STOCK_FULLSCREEN, N_("_Fullscreen"), 0, GDK_KEY_F11, NULL },
192 { AR_STOCK_HINT, N_("_Hint"), GDK_CONTROL_MASK, 'h', NULL },
193 /* Translators: This "_New" is for the menu item 'Game->New', implies "New Game" */
194 { AR_STOCK_NEW_GAME, N_("_New"), GDK_CONTROL_MASK, 'n', NULL },
195 /* Translators: This "_New Game" is for the game-over dialogue */
196 { AR_STOCK_START_NEW_GAME, N_("_New Game"), 0, 0, NULL },
197 { AR_STOCK_REDO_MOVE, N_("_Redo Move"), GDK_CONTROL_MASK | GDK_SHIFT_MASK, 'z', NULL },
198 /* Translators: this is the "Reset" scores button in a scores dialogue */
199 { AR_STOCK_RESET, N_("_Reset"), 0, 0, NULL },
200 /* Translators: "_Restart" is the menu item 'Game->Restart', implies "Restart Game" */
201 { AR_STOCK_RESTART_GAME, N_("_Restart"), 0, 0, NULL },
202 { AR_STOCK_UNDO_MOVE, N_("_Undo Move"), GDK_CONTROL_MASK, 'z', NULL },
203 { AR_STOCK_DEAL_CARDS, N_("_Deal"), GDK_CONTROL_MASK, 'd', NULL },
204 { AR_STOCK_LEAVE_FULLSCREEN, N_("_Leave Fullscreen"), 0, GDK_KEY_F11, NULL },
205 { AR_STOCK_PAUSE_GAME, N_("_Pause"), 0, GDK_KEY_Pause, NULL },
206 };
207
208 guint i;
209 GtkIconFactory *icon_factory;
210
211 icon_factory = gtk_icon_factory_new ();
212
213 #ifdef HAVE_GTK_ICON_FACTORY_ADD_ALIAS
214 for (i = 0; i < G_N_ELEMENTS (stock_icon_aliases); ++i) {
215 gtk_icon_factory_add_alias (stock_icon_aliases[i][0],
216 stock_icon_aliases[i][1]);
217 }
218
219 #else
220 for (i = 0; i < G_N_ELEMENTS (stock_icon_aliases); ++i) {
221 register_stock_icon (icon_factory,
222 stock_icon_aliases[i][0],
223 stock_icon_aliases[i][1]);
224 }
225
226 for (i = 0; i < G_N_ELEMENTS (stock_icon_aliases_bidi); ++i) {
227 register_stock_icon_bidi (icon_factory,
228 stock_icon_aliases_bidi[i][0],
229 stock_icon_aliases_bidi[i][1],
230 stock_icon_aliases_bidi[i][2]);
231 }
232 #endif /* HAVE_GTK_ICON_FACTORY_ADD_ALIAS */
233
234 /* Register our private themeable icons */
235 for (i = 0; i < G_N_ELEMENTS (private_icon_names); i++) {
236 register_stock_icon (icon_factory,
237 private_icon_names[i][0],
238 private_icon_names[i][1]);
239 }
240
241 gtk_icon_factory_add_default (icon_factory);
242 g_object_unref (icon_factory);
243
244 /* GtkIconTheme will then look in our custom hicolor dir
245 * for icons as well as the standard search paths.
246 */
247 /* FIXME: multi-head! */
248 gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (),
249 ar_runtime_get_directory (AR_RUNTIME_ICON_THEME_DIRECTORY));
250
251 gtk_stock_add_static (ar_stock_items, G_N_ELEMENTS (ar_stock_items));
252 }
253
254 /**
255 * ar_get_licence:
256 *
257 * Returns: (transfer full): a newly allocated string with a GPL licence notice
258 */
259 char *
ar_get_licence(const gchar * game_name)260 ar_get_licence (const gchar *game_name)
261 {
262 const int version = 3;
263 char *license_trans, *license_str;
264
265 static const char license0[] =
266 /* %s is replaced with the name of the game in gnome-games. */
267 N_("%s is free software; you can redistribute it and/or modify "
268 "it under the terms of the GNU General Public License as published by "
269 "the Free Software Foundation; either version %d of the License, or "
270 "(at your option) any later version.");
271 static const char license1[] =
272 N_("%s is distributed in the hope that it will be useful, "
273 "but WITHOUT ANY WARRANTY; without even the implied warranty of "
274 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the "
275 "GNU General Public License for more details.");
276 static const char license3[] =
277 N_("You should have received a copy of the GNU General Public License "
278 "along with this program. If not, see <http://www.gnu.org/licenses/>.");
279
280 license_trans = g_strjoin ("\n\n", _(license0), _(license1), _(license3), NULL);
281
282 #pragma GCC diagnostic push
283 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
284 license_str =
285 g_strdup_printf (license_trans, game_name, version, game_name, game_name);
286 #pragma GCC diagnostic pop
287
288 g_free (license_trans);
289
290 return license_str;
291 }
292