]> granicus.if.org Git - transmission/blob - gtk/actions.c
Update to Uncrustify 0.68.1
[transmission] / gtk / actions.c
1 /*
2  * This file Copyright (C) 2007-2014 Mnemosyne LLC
3  *
4  * It may be used under the GNU GPL versions 2 or 3
5  * or any future license endorsed by Mnemosyne LLC.
6  *
7  */
8
9 #include <string.h>
10
11 #include <glib/gi18n.h>
12 #include <gtk/gtk.h>
13
14 #include <libtransmission/transmission.h>
15
16 #include "actions.h"
17 #include "conf.h"
18 #include "tr-core.h"
19 #include "tr-prefs.h"
20
21 static TrCore* myCore = NULL;
22 static GtkActionGroup* myGroup = NULL;
23
24 static void action_cb(GtkAction* a, gpointer user_data)
25 {
26     gtr_actions_handler(gtk_action_get_name(a), user_data);
27 }
28
29 static GtkRadioActionEntry sort_radio_entries[] =
30 {
31     { "sort-by-activity", NULL, N_("Sort by _Activity"), NULL, NULL, 0 },
32     { "sort-by-name", NULL, N_("Sort by _Name"), NULL, NULL, 1 },
33     { "sort-by-progress", NULL, N_("Sort by _Progress"), NULL, NULL, 2 },
34     { "sort-by-queue", NULL, N_("Sort by _Queue"), NULL, NULL, 3 },
35     { "sort-by-ratio", NULL, N_("Sort by Rati_o"), NULL, NULL, 4 },
36     { "sort-by-state", NULL, N_("Sort by Stat_e"), NULL, NULL, 5 },
37     { "sort-by-age", NULL, N_("Sort by A_ge"), NULL, NULL, 6 },
38     { "sort-by-time-left", NULL, N_("Sort by Time _Left"), NULL, NULL, 7 },
39     { "sort-by-size", NULL, N_("Sort by Si_ze"), NULL, NULL, 8 }
40 };
41
42 static void sort_changed_cb(GtkAction* action UNUSED, GtkRadioAction* current, gpointer user_data UNUSED)
43 {
44     tr_quark const key = TR_KEY_sort_mode;
45     int const i = gtk_radio_action_get_current_value(current);
46     char const* val = sort_radio_entries[i].name;
47
48     gtr_core_set_pref(myCore, key, val);
49 }
50
51 static GtkToggleActionEntry show_toggle_entries[] =
52 {
53     { "toggle-main-window", NULL, N_("_Show Transmission"), NULL, NULL, G_CALLBACK(action_cb), TRUE },
54     { "toggle-message-log", NULL, N_("Message _Log"), NULL, NULL, G_CALLBACK(action_cb), FALSE }
55 };
56
57 static void toggle_pref_cb(GtkToggleAction* action, gpointer user_data UNUSED)
58 {
59     char const* key = gtk_action_get_name(GTK_ACTION(action));
60     gboolean const val = gtk_toggle_action_get_active(action);
61
62     gtr_core_set_pref_bool(myCore, tr_quark_new(key, TR_BAD_SIZE), val);
63 }
64
65 static GtkToggleActionEntry pref_toggle_entries[] =
66 {
67     { "alt-speed-enabled", NULL, N_("Enable Alternative Speed _Limits"), NULL, NULL, G_CALLBACK(toggle_pref_cb), FALSE },
68     { "compact-view", NULL, N_("_Compact View"), "<alt>C", NULL, G_CALLBACK(toggle_pref_cb), FALSE },
69     { "sort-reversed", NULL, N_("Re_verse Sort Order"), NULL, NULL, G_CALLBACK(toggle_pref_cb), FALSE },
70     { "show-filterbar", NULL, N_("_Filterbar"), NULL, NULL, G_CALLBACK(toggle_pref_cb), FALSE },
71     { "show-statusbar", NULL, N_("_Statusbar"), NULL, NULL, G_CALLBACK(toggle_pref_cb), FALSE },
72     { "show-toolbar", NULL, N_("_Toolbar"), NULL, NULL, G_CALLBACK(toggle_pref_cb), FALSE }
73 };
74
75 static GtkActionEntry entries[] =
76 {
77     { "file-menu", NULL, N_("_File"), NULL, NULL, NULL },
78     { "torrent-menu", NULL, N_("_Torrent"), NULL, NULL, NULL },
79     { "view-menu", NULL, N_("_View"), NULL, NULL, NULL },
80     { "sort-menu", NULL, N_("_Sort Torrents By"), NULL, NULL, NULL },
81     { "queue-menu", NULL, N_("_Queue"), NULL, NULL, NULL },
82     { "edit-menu", NULL, N_("_Edit"), NULL, NULL, NULL },
83     { "help-menu", NULL, N_("_Help"), NULL, NULL, NULL },
84     { "copy-magnet-link-to-clipboard", GTK_STOCK_COPY, N_("Copy _Magnet Link to Clipboard"), "", NULL, G_CALLBACK(action_cb) },
85     { "open-torrent-from-url", GTK_STOCK_OPEN, N_("Open _URL…"), "<control>U", N_("Open URL…"), G_CALLBACK(action_cb) },
86     { "open-torrent-toolbar", GTK_STOCK_OPEN, NULL, NULL, N_("Open a torrent"), G_CALLBACK(action_cb) },
87     { "open-torrent-menu", GTK_STOCK_OPEN, NULL, NULL, N_("Open a torrent"), G_CALLBACK(action_cb) },
88     { "torrent-start", GTK_STOCK_MEDIA_PLAY, N_("_Start"), "<control>S", N_("Start torrent"), G_CALLBACK(action_cb) },
89     { "torrent-start-now", GTK_STOCK_MEDIA_PLAY, N_("Start _Now"), "<shift><control>S", N_("Start torrent now"),
90         G_CALLBACK(action_cb) },
91     { "show-stats", NULL, N_("_Statistics"), NULL, NULL, G_CALLBACK(action_cb) },
92     { "donate", NULL, N_("_Donate"), NULL, NULL, G_CALLBACK(action_cb) },
93     { "torrent-verify", NULL, N_("_Verify Local Data"), "<control>V", NULL, G_CALLBACK(action_cb) },
94     { "torrent-stop", GTK_STOCK_MEDIA_PAUSE, N_("_Pause"), "<control>P", N_("Pause torrent"), G_CALLBACK(action_cb) },
95     { "pause-all-torrents", GTK_STOCK_MEDIA_PAUSE, N_("_Pause All"), NULL, N_("Pause all torrents"), G_CALLBACK(action_cb) },
96     { "start-all-torrents", GTK_STOCK_MEDIA_PLAY, N_("_Start All"), NULL, N_("Start all torrents"), G_CALLBACK(action_cb) },
97     { "relocate-torrent", NULL, N_("Set _Location…"), NULL, NULL, G_CALLBACK(action_cb) },
98     { "remove-torrent", GTK_STOCK_REMOVE, NULL, "Delete", N_("Remove torrent"), G_CALLBACK(action_cb) },
99     { "delete-torrent", GTK_STOCK_DELETE, N_("_Delete Files and Remove"), "<shift>Delete", NULL, G_CALLBACK(action_cb) },
100     { "new-torrent", GTK_STOCK_NEW, N_("_New…"), NULL, N_("Create a torrent"), G_CALLBACK(action_cb) },
101     { "quit", GTK_STOCK_QUIT, N_("_Quit"), NULL, NULL, G_CALLBACK(action_cb) },
102     { "select-all", GTK_STOCK_SELECT_ALL, N_("Select _All"), "<control>A", NULL, G_CALLBACK(action_cb) },
103     { "deselect-all", NULL, N_("Dese_lect All"), "<shift><control>A", NULL, G_CALLBACK(action_cb) },
104     { "edit-preferences", GTK_STOCK_PREFERENCES, NULL, NULL, NULL, G_CALLBACK(action_cb) },
105     { "show-torrent-properties", GTK_STOCK_PROPERTIES, NULL, "<alt>Return", N_("Torrent properties"), G_CALLBACK(action_cb) },
106     { "open-torrent-folder", GTK_STOCK_OPEN, N_("Open Fold_er"), "<control>E", NULL, G_CALLBACK(action_cb) },
107     { "show-about-dialog", GTK_STOCK_ABOUT, NULL, NULL, NULL, G_CALLBACK(action_cb) },
108     { "help", GTK_STOCK_HELP, N_("_Contents"), "F1", NULL, G_CALLBACK(action_cb) },
109     { "torrent-reannounce", GTK_STOCK_NETWORK, N_("Ask Tracker for _More Peers"), NULL, NULL, G_CALLBACK(action_cb) },
110     { "queue-move-top", GTK_STOCK_GOTO_TOP, N_("Move to _Top"), NULL, NULL, G_CALLBACK(action_cb) },
111     { "queue-move-up", GTK_STOCK_GO_UP, N_("Move _Up"), "<control>Up", NULL, G_CALLBACK(action_cb) },
112     { "queue-move-down", GTK_STOCK_GO_DOWN, N_("Move _Down"), "<control>Down", NULL, G_CALLBACK(action_cb) },
113     { "queue-move-bottom", GTK_STOCK_GOTO_BOTTOM, N_("Move to _Bottom"), NULL, NULL, G_CALLBACK(action_cb) },
114     { "present-main-window", NULL, N_("Present Main Window"), NULL, NULL, G_CALLBACK(action_cb) }
115 };
116
117 typedef struct
118 {
119     char const* filename;
120     char const* name;
121 }
122 BuiltinIconInfo;
123
124 static BuiltinIconInfo const my_fallback_icons[] =
125 {
126     { "logo-48", WINDOW_ICON },
127     { "logo-24", TRAY_ICON },
128     { "logo-48", NOTIFICATION_ICON },
129     { "lock", "transmission-lock" },
130     { "utilities", "utilities" },
131     { "turtle-blue", "alt-speed-on" },
132     { "turtle-grey", "alt-speed-off" },
133     { "ratio", "ratio" }
134 };
135
136 static void register_my_icons(void)
137 {
138     GtkIconTheme* theme = gtk_icon_theme_get_default();
139     GtkIconFactory* factory = gtk_icon_factory_new();
140
141     gtk_icon_factory_add_default(factory);
142
143     for (size_t i = 0; i < G_N_ELEMENTS(my_fallback_icons); ++i)
144     {
145         char const* name = my_fallback_icons[i].name;
146
147         if (!gtk_icon_theme_has_icon(theme, name))
148         {
149             GdkPixbuf* p;
150             gchar* resource_path = g_strdup_printf(TR_RESOURCE_PATH "icons/%s.png", my_fallback_icons[i].filename);
151
152             p = gdk_pixbuf_new_from_resource(resource_path, NULL);
153
154             g_free(resource_path);
155
156             if (p != NULL)
157             {
158                 int width;
159                 GtkIconSet* icon_set;
160
161                 width = gdk_pixbuf_get_width(p);
162                 icon_set = gtk_icon_set_new_from_pixbuf(p);
163
164                 gtk_icon_theme_add_builtin_icon(name, width, p);
165                 gtk_icon_factory_add(factory, name, icon_set);
166
167                 g_object_unref(p);
168                 gtk_icon_set_unref(icon_set);
169             }
170         }
171     }
172
173     g_object_unref(G_OBJECT(factory));
174 }
175
176 static GtkUIManager* myUIManager = NULL;
177
178 void gtr_actions_set_core(TrCore* core)
179 {
180     myCore = core;
181 }
182
183 void gtr_actions_init(GtkUIManager* ui_manager, gpointer callback_user_data)
184 {
185     int active = -1;
186     char const* match;
187     int const n_entries = G_N_ELEMENTS(entries);
188     GtkActionGroup* action_group;
189
190     myUIManager = ui_manager;
191
192     register_my_icons();
193
194     action_group = myGroup = gtk_action_group_new("Actions");
195     gtk_action_group_set_translation_domain(action_group, NULL);
196
197     match = gtr_pref_string_get(TR_KEY_sort_mode);
198
199     for (size_t i = 0; active == -1 && i < G_N_ELEMENTS(sort_radio_entries); ++i)
200     {
201         if (g_strcmp0(sort_radio_entries[i].name, match) == 0)
202         {
203             active = i;
204         }
205     }
206
207     gtk_action_group_add_radio_actions(action_group, sort_radio_entries, G_N_ELEMENTS(sort_radio_entries), active,
208         G_CALLBACK(sort_changed_cb), NULL);
209
210     gtk_action_group_add_toggle_actions(action_group, show_toggle_entries, G_N_ELEMENTS(show_toggle_entries),
211         callback_user_data);
212
213     for (size_t i = 0; i < G_N_ELEMENTS(pref_toggle_entries); ++i)
214     {
215         pref_toggle_entries[i].is_active = gtr_pref_flag_get(tr_quark_new(pref_toggle_entries[i].name, TR_BAD_SIZE));
216     }
217
218     gtk_action_group_add_toggle_actions(action_group, pref_toggle_entries, G_N_ELEMENTS(pref_toggle_entries),
219         callback_user_data);
220
221     gtk_action_group_add_actions(action_group, entries, n_entries, callback_user_data);
222
223     gtk_ui_manager_insert_action_group(ui_manager, action_group, 0);
224     g_object_unref(G_OBJECT(action_group));
225 }
226
227 /****
228 *****
229 ****/
230
231 static GHashTable* key_to_action = NULL;
232
233 static void ensure_action_map_loaded(GtkUIManager* uim)
234 {
235     if (key_to_action != NULL)
236     {
237         return;
238     }
239
240     key_to_action = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
241
242     for (GList* l = gtk_ui_manager_get_action_groups(uim); l != NULL; l = l->next)
243     {
244         GtkActionGroup* action_group = GTK_ACTION_GROUP(l->data);
245         GList* actions = gtk_action_group_list_actions(action_group);
246
247         for (GList* ait = actions; ait != NULL; ait = ait->next)
248         {
249             GtkAction* action = GTK_ACTION(ait->data);
250             char const* name = gtk_action_get_name(action);
251             g_hash_table_insert(key_to_action, g_strdup(name), action);
252         }
253
254         g_list_free(actions);
255     }
256 }
257
258 static GtkAction* get_action(char const* name)
259 {
260     ensure_action_map_loaded(myUIManager);
261     return (GtkAction*)g_hash_table_lookup(key_to_action, name);
262 }
263
264 void gtr_action_activate(char const* name)
265 {
266     GtkAction* action = get_action(name);
267
268     g_assert(action != NULL);
269     gtk_action_activate(action);
270 }
271
272 void gtr_action_set_sensitive(char const* name, gboolean b)
273 {
274     GtkAction* action = get_action(name);
275
276     g_assert(action != NULL);
277     g_object_set(action, "sensitive", b, NULL);
278 }
279
280 void gtr_action_set_important(char const* name, gboolean b)
281 {
282     GtkAction* action = get_action(name);
283
284     g_assert(action != NULL);
285     g_object_set(action, "is-important", b, NULL);
286 }
287
288 void gtr_action_set_toggled(char const* name, gboolean b)
289 {
290     GtkAction* action = get_action(name);
291
292     gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), b);
293 }
294
295 GtkWidget* gtr_action_get_widget(char const* path)
296 {
297     return gtk_ui_manager_get_widget(myUIManager, path);
298 }