source: trunk/gtk/actions.c @ 5760

Last change on this file since 5760 was 5760, checked in by charles, 14 years ago

(gtk) link to the online manual from the Help menu

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