source: trunk/gtk/actions.c @ 4905

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

(gtk) #677: small HIG tweaks

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