source: trunk/gtk/actions.c @ 4304

Last change on this file since 4304 was 4304, checked in by charles, 15 years ago

(gtk+) first cut of a filter bar

  • Property svn:keywords set to Date Rev Author Id
File size: 10.8 KB
Line 
1/*
2 * This file Copyright (C) 2007 Charles Kerr <charles@rebelbase.com>
3 *
4 * This file is licensed by the GPL version 2.  Works owned by the
5 * Transmission project are granted a special exemption to clause 2(b)
6 * so that the bulk of its code can remain under the MIT license.
7 * This exemption does not extend to derived works not owned by
8 * the Transmission project.
9 *
10 * $Id: actions.c 4304 2007-12-24 00:14:39Z charles $
11 */
12
13#include <string.h>
14#include <glib/gi18n.h>
15#include <gtk/gtk.h>
16#include <libtransmission/transmission.h>
17#include "conf.h"
18#include "torrent-inspector.h"
19#include "tr_core.h"
20#include "tr_prefs.h"
21#include "lock.h"
22#include "logo.h"
23#include "status-bar-icons.h"
24
25#define UNUSED G_GNUC_UNUSED
26
27extern void doAction (const char * action_name, gpointer user_data );
28
29static TrCore * myCore = 0;
30
31static GtkActionGroup * myGroup = 0;
32
33static void
34action_cb ( GtkAction * a, gpointer user_data )
35{
36  doAction ( gtk_action_get_name(a), user_data );
37}
38
39#if !GTK_CHECK_VERSION(2,8,0)
40#define GTK_STOCK_INFO GTK_STOCK_PROPERTIES
41#endif
42
43#if !GTK_CHECK_VERSION(2,10,0)
44#define GTK_STOCK_SELECT_ALL NULL
45#endif
46
47static GtkRadioActionEntry priority_toggle_entries[] =
48{
49  { "priority-high", NULL, N_("_High"), NULL, NULL, TR_PRI_HIGH },
50  { "priority-normal", NULL, N_("_Normal"), NULL, NULL, TR_PRI_NORMAL },
51  { "priority-low", NULL, N_("_Low"), NULL, NULL, TR_PRI_LOW }
52};
53
54extern void set_selected_file_priority ( tr_priority_t ); 
55
56static void
57priority_changed_cb (GtkAction *action UNUSED, GtkRadioAction *current)
58{
59  const int priority = gtk_radio_action_get_current_value (current);
60  set_selected_file_priority ( priority );
61}
62
63static GtkRadioActionEntry sort_radio_entries[] =
64{
65  { "sort-by-activity",   NULL, N_("Sort by _Activity"),   NULL, NULL, 0 },
66  { "sort-by-date-added", NULL, N_("Sort by _Date Added"), NULL, NULL, 1 },
67  { "sort-by-name",       NULL, N_("Sort by _Name"),       NULL, NULL, 2 },
68  { "sort-by-progress",   NULL, N_("Sort by _Progress"),   NULL, NULL, 3 },
69  { "sort-by-state",      NULL, N_("Sort by _State"),      NULL, NULL, 4 },
70  { "sort-by-tracker",    NULL, N_("Sort by _Tracker"),    NULL, NULL, 5 }
71};
72
73static void
74sort_changed_cb( GtkAction            * action UNUSED,
75                 GtkRadioAction       * current,
76                 gpointer user_data     UNUSED )
77{
78    const char * key = PREF_KEY_SORT_MODE;
79    const int i = gtk_radio_action_get_current_value( current );
80    const char * val = sort_radio_entries[i].name;
81    tr_core_set_pref( myCore, key, val );
82}
83
84static GtkToggleActionEntry show_toggle_entries[] = 
85{
86  { "toggle-main-window", NULL, 
87    N_("Show _Main Window"), NULL, NULL, G_CALLBACK(action_cb), TRUE }, 
88  { "toggle-message-log", NULL,
89    N_("Show Message _Log"), NULL, NULL, G_CALLBACK(action_cb), FALSE }
90};
91
92static void
93toggle_pref_cb ( GtkToggleAction * action, gpointer user_data UNUSED )
94{
95    const char * key = gtk_action_get_name( GTK_ACTION( action ) );
96    const gboolean val = gtk_toggle_action_get_active( action );
97    tr_core_set_pref_bool( myCore, key, val );
98}
99
100static GtkToggleActionEntry pref_toggle_entries[] =
101{
102  { "minimal-view", NULL,
103    N_("_Minimal View"), "<alt>M", NULL, G_CALLBACK(toggle_pref_cb), FALSE },
104  { "sort-reversed", NULL,
105    N_("_Reverse Sort Order"), NULL, NULL, G_CALLBACK(toggle_pref_cb), FALSE },
106  { "show-filter-bar", NULL,
107    N_("Show _Filter Bar"), NULL, NULL, G_CALLBACK(toggle_pref_cb), FALSE },
108  { "show-status-bar", NULL,
109    N_("Show _Status Bar"), NULL, NULL, G_CALLBACK(toggle_pref_cb), FALSE },
110  { "show-toolbar", NULL,
111    N_("Show _Toolbar"), NULL, NULL, G_CALLBACK(toggle_pref_cb), FALSE }
112};
113
114static GtkActionEntry entries[] =
115{
116  { "torrent-menu", NULL, N_("_Torrent"), NULL, NULL, NULL },
117  { "view-menu", NULL, N_("_View"), NULL, NULL, NULL },
118  { "sort-menu", NULL, N_("_Sort Torrents By"), NULL, NULL, NULL },
119  { "edit-menu", NULL, N_("_Edit"), NULL, NULL, NULL },
120  { "help-menu", NULL, N_("_Help"), NULL, NULL, NULL },
121  { "priority-menu", NULL, N_("_Priority"), NULL, NULL, NULL },
122  { "add-torrent", GTK_STOCK_OPEN,
123    NULL, NULL, N_("Open Torrent"), G_CALLBACK(action_cb) },
124  { "start-torrent", GTK_STOCK_MEDIA_PLAY,
125    N_("_Start"), "<control>S", NULL, G_CALLBACK(action_cb) },
126  { "show-stats", NULL, N_("_Statistics"), NULL, NULL, G_CALLBACK(action_cb) },
127  { "verify-torrent", NULL,
128    N_("_Verify Local Data"), NULL, NULL, G_CALLBACK(action_cb) },
129  { "pause-torrent", GTK_STOCK_MEDIA_PAUSE,
130    N_("_Pause"), "<control>P", NULL, G_CALLBACK(action_cb) },
131  { "remove-torrent", GTK_STOCK_REMOVE,
132    N_("_Remove"), "<control>R", NULL, G_CALLBACK(action_cb) },
133  { "create-torrent", GTK_STOCK_NEW,
134    N_("Create _New Torrent"), NULL, NULL, G_CALLBACK(action_cb) },
135  { "close", GTK_STOCK_CLOSE,
136    N_("_Close"), "<control>W", NULL, G_CALLBACK(action_cb) },
137  { "quit", GTK_STOCK_QUIT,
138    N_("_Quit"), "<control>Q", NULL, G_CALLBACK(action_cb) },
139  { "select-all", GTK_STOCK_SELECT_ALL,
140    N_("Select _All"), "<control>A", NULL, G_CALLBACK(action_cb) },
141  { "unselect-all", NULL,
142    N_("Dese_lect All"), "<shift><control>A", NULL, G_CALLBACK(action_cb) },
143  { "edit-preferences", GTK_STOCK_PREFERENCES,
144    NULL, NULL, NULL, G_CALLBACK(action_cb) },
145  { "show-torrent-details", GTK_STOCK_INFO,
146    N_("_Details"), "<alt>Return", N_("Torrent Details"), G_CALLBACK(action_cb) },
147  { "show-about-dialog", GTK_STOCK_ABOUT,
148    N_("_About Transmission"), NULL, NULL, G_CALLBACK(action_cb) },
149  { "update-tracker", GTK_STOCK_NETWORK,
150    N_("Ask Tracker for _More Peers"), NULL, NULL, G_CALLBACK(action_cb) }
151};
152
153static void
154ensure_tooltip (GtkActionEntry * e)
155{
156    if( !e->tooltip && e->label )
157    {
158        const char * src;
159        char *tgt;
160        e->tooltip = g_malloc( strlen( e->label ) + 1 );
161        for( src=e->label, tgt=(char*)e->tooltip; *src; ++src )
162            if( *src != '_' )
163                *tgt++ = *src;
164        *tgt++ = '\0';
165    }
166}
167
168typedef struct
169{
170   const guint8* raw;
171   const char * name;
172}
173BuiltinIconInfo;
174
175const BuiltinIconInfo my_builtin_icons [] =
176{
177    { tr_icon_logo, "transmission-logo" },
178    { tr_icon_lock, "transmission-lock" },
179    { tr_arrow_down, "tr-arrow-down" },
180    { tr_arrow_up, "tr-arrow-up" },
181    { tr_yin_yang, "tr-yin-yang" },
182    { tr_search_pulldown, "tr-search-pulldown" }
183};
184
185static void
186register_my_icons ( void )
187{
188   int i;
189   const int n = G_N_ELEMENTS( my_builtin_icons );
190   GtkIconFactory * factory = gtk_icon_factory_new ();
191   gtk_icon_factory_add_default( factory );
192
193   for( i=0; i<n; ++i )
194   {
195       GdkPixbuf * p;
196       int width;
197       GtkIconSet * icon_set;
198
199       p = gdk_pixbuf_new_from_inline( -1, my_builtin_icons[i].raw, FALSE, 0 );
200       width = gdk_pixbuf_get_width( p );
201       gtk_icon_theme_add_builtin_icon (my_builtin_icons[i].name, width, p );
202
203       icon_set = gtk_icon_set_new_from_pixbuf( p );
204       gtk_icon_factory_add( factory, my_builtin_icons[i].name, icon_set );
205
206       g_object_unref( p );
207       gdk_pixbuf_unref( p );
208       gtk_icon_set_unref (icon_set);
209    }
210
211    g_object_unref (G_OBJECT (factory));
212}
213
214static GtkUIManager * myUIManager = NULL;
215
216void
217actions_set_core( TrCore * core )
218{
219    myCore = core;
220}
221
222void
223actions_init( GtkUIManager * ui_manager, gpointer callback_user_data )
224{
225  int i, n;
226  int active;
227  char * match;
228  const int n_entries = G_N_ELEMENTS( entries );
229  GtkActionGroup * action_group;
230
231  myUIManager = ui_manager;
232
233  register_my_icons ();
234
235  for( i=0; i<n_entries; ++i )
236    ensure_tooltip (&entries[i]);
237
238  action_group = myGroup = gtk_action_group_new( "Actions" );
239  gtk_action_group_set_translation_domain( action_group, NULL );
240
241  gtk_action_group_add_radio_actions( action_group,
242                                      priority_toggle_entries,
243                                      G_N_ELEMENTS(priority_toggle_entries),
244                                      TR_PRI_NORMAL,
245                                      G_CALLBACK(priority_changed_cb), NULL);
246
247
248  match = pref_string_get( PREF_KEY_SORT_MODE );
249  for( i=0, n=G_N_ELEMENTS(sort_radio_entries), active=-1; active==-1 && i<n; ++i )
250      if( !strcmp( sort_radio_entries[i].name, match ) )
251          active = i;
252
253  gtk_action_group_add_radio_actions( action_group,
254                                      sort_radio_entries,
255                                      G_N_ELEMENTS(sort_radio_entries),
256                                      active,
257                                      G_CALLBACK(sort_changed_cb),
258                                      NULL );
259
260  gtk_action_group_add_toggle_actions( action_group, 
261                                       show_toggle_entries, 
262                                       G_N_ELEMENTS(show_toggle_entries), 
263                                       callback_user_data );
264
265  for( i=0, n=G_N_ELEMENTS(pref_toggle_entries); i<n; ++i )
266    pref_toggle_entries[i].is_active =
267      pref_flag_get( pref_toggle_entries[i].name );
268
269  gtk_action_group_add_toggle_actions( action_group, 
270                                       pref_toggle_entries, 
271                                       G_N_ELEMENTS(pref_toggle_entries), 
272                                       callback_user_data );
273
274  gtk_action_group_add_actions( action_group,
275                                entries, n_entries,
276                                callback_user_data );
277
278  gtk_ui_manager_insert_action_group( ui_manager, action_group, 0 );
279  g_object_unref (G_OBJECT(action_group));
280  g_free( match );
281}
282
283/****
284*****
285****/
286
287static GHashTable * key_to_action = NULL;
288
289static void
290ensure_action_map_loaded (GtkUIManager * uim)
291{
292    GList * l;
293
294    if ( key_to_action != NULL )
295        return;
296
297    key_to_action =
298        g_hash_table_new_full( g_str_hash, g_str_equal, g_free, NULL);
299
300    for( l=gtk_ui_manager_get_action_groups(uim); l!=NULL; l=l->next )
301    {
302        GtkActionGroup * action_group = GTK_ACTION_GROUP( l->data );
303        GList *ait, *actions = gtk_action_group_list_actions( action_group );
304        for( ait=actions; ait!=NULL; ait=ait->next )
305        {
306            GtkAction * action = GTK_ACTION( ait->data );
307            const char * name = gtk_action_get_name( action );
308            g_hash_table_insert( key_to_action, g_strdup(name), action );
309        }
310        g_list_free( actions );
311    }
312}
313
314static GtkAction*
315get_action( const char* name )
316{
317    ensure_action_map_loaded( myUIManager );
318    return ( GtkAction* ) g_hash_table_lookup( key_to_action, name );
319}
320
321void
322action_activate ( const char * name )
323{
324    GtkAction * action = get_action( name );
325    g_assert( action != NULL );
326    gtk_action_activate( action );
327}
328
329void
330action_sensitize( const char * name, gboolean b )
331{
332    GtkAction * action = get_action( name );
333    g_assert( action != NULL );
334    g_object_set( action, "sensitive", b, NULL );
335}
336
337void
338action_toggle( const char * name, gboolean b )
339{
340    GtkAction * action = get_action( name );
341    gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action), b );
342}
343
344GtkWidget*
345action_get_widget( const char * path )
346{
347    return gtk_ui_manager_get_widget( myUIManager, path );
348}
Note: See TracBrowser for help on using the repository browser.