source: trunk/gtk/actions.c @ 6490

Last change on this file since 6490 was 6490, checked in by charles, 13 years ago

lots of C correctness tweaks suggested by sparse/cgcc

  • Property svn:keywords set to Date Rev Author Id
File size: 9.9 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 6490 2008-08-11 19:05:02Z charles $
11 */
12
13#include <string.h>
14#include <glib/gi18n.h>
15#include <gtk/gtk.h>
16#include <libtransmission/transmission.h>
17#include "actions.h"
18#include "conf.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
26static TrCore * myCore = NULL;
27
28static GtkActionGroup * myGroup = NULL;
29
30static void
31action_cb ( GtkAction * a, gpointer user_data )
32{
33  doAction ( gtk_action_get_name(a), user_data );
34}
35
36#if !GTK_CHECK_VERSION(2,8,0)
37#define GTK_STOCK_INFO GTK_STOCK_PROPERTIES
38#endif
39
40#if !GTK_CHECK_VERSION(2,10,0)
41#define GTK_STOCK_SELECT_ALL NULL
42#endif
43
44static GtkRadioActionEntry sort_radio_entries[] =
45{
46  { "sort-by-activity",   NULL, N_("Sort by _Activity"),   NULL, NULL, 0 },
47  { "sort-by-name",       NULL, N_("Sort by _Name"),       NULL, NULL, 1 },
48  { "sort-by-progress",   NULL, N_("Sort by _Progress"),   NULL, NULL, 2 },
49  { "sort-by-ratio",      NULL, N_("Sort by _Ratio"),      NULL, NULL, 3 },
50  { "sort-by-state",      NULL, N_("Sort by _State"),      NULL, NULL, 4 },
51  { "sort-by-tracker",    NULL, N_("Sort by _Tracker"),    NULL, NULL, 5 },
52  { "sort-by-age",        NULL, N_("Sort by A_ge"),        NULL, NULL, 6 }
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  { PREF_KEY_SHOW_TRAY_ICON, NULL,
95    N_("Tray _Icon" ), NULL, NULL, G_CALLBACK(toggle_pref_cb), FALSE }
96};
97
98static GtkActionEntry entries[] =
99{
100  { "torrent-menu", NULL, N_("_Torrent"), NULL, NULL, NULL },
101  { "view-menu", NULL, N_("_View"), NULL, NULL, NULL },
102  { "sort-menu", NULL, N_("_Sort Torrents By"), NULL, NULL, NULL },
103  { "edit-menu", NULL, N_("_Edit"), NULL, NULL, NULL },
104  { "help-menu", NULL, N_("_Help"), NULL, NULL, NULL },
105  { "add-torrent-toolbar", GTK_STOCK_ADD, NULL, NULL, N_("Add a torrent"), G_CALLBACK(action_cb) },
106  { "add-torrent-menu", GTK_STOCK_ADD, N_("_Add..."), "<control>D", N_("Add a torrent"), G_CALLBACK(action_cb) },
107  { "start-torrent", GTK_STOCK_MEDIA_PLAY,
108    N_("_Start"), "<control>S", N_("Start torrent"), G_CALLBACK(action_cb) },
109  { "show-stats", NULL, N_("_Statistics"), NULL, NULL, G_CALLBACK(action_cb) },
110  { "verify-torrent", NULL,
111    N_("_Verify Local Data"), NULL, NULL, G_CALLBACK(action_cb) },
112  { "pause-torrent", GTK_STOCK_MEDIA_PAUSE,
113    N_("_Pause"), "<control>P", N_("Pause torrent"), G_CALLBACK(action_cb) },
114  { "remove-torrent", GTK_STOCK_REMOVE, NULL, "Delete", N_("Remove torrent"), G_CALLBACK(action_cb) },
115  { "delete-torrent", GTK_STOCK_DELETE, N_("_Delete Files and Remove"), "<shift>Delete", NULL, G_CALLBACK(action_cb) },
116  { "new-torrent", GTK_STOCK_NEW, N_("_New..."), NULL,
117    N_("Create a torrent"),
118    G_CALLBACK(action_cb) },
119  { "quit", GTK_STOCK_QUIT, N_("_Quit"), NULL, NULL, G_CALLBACK(action_cb) },
120  { "select-all", GTK_STOCK_SELECT_ALL,
121    N_( "Select _All" ), "<control>A", NULL, G_CALLBACK(action_cb) },
122  { "deselect-all", NULL,
123    N_("Dese_lect All"), "<shift><control>A", NULL, G_CALLBACK(action_cb) },
124  { "edit-preferences", GTK_STOCK_PREFERENCES, NULL, NULL, NULL, G_CALLBACK(action_cb) },
125  { "show-torrent-details", GTK_STOCK_INFO,
126    N_("_Details"), "<alt>Return", N_("Torrent details"), G_CALLBACK(action_cb) },
127  { "open-torrent-folder", GTK_STOCK_OPEN,
128    N_("_Open Folder"), NULL, NULL, G_CALLBACK(action_cb) },
129  { "show-about-dialog", GTK_STOCK_ABOUT, NULL, NULL, NULL, G_CALLBACK(action_cb) },
130  { "help", GTK_STOCK_HELP, N_("_Contents"), "F1", 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
135typedef struct
136{
137   const guint8* raw;
138   const char * name;
139}
140BuiltinIconInfo;
141
142static const BuiltinIconInfo my_fallback_icons [] =
143{
144    { tr_icon_logo, "transmission" },
145    { tr_icon_lock, "transmission-lock" }
146};
147
148static void
149register_my_icons ( void )
150{
151    int i;
152    const int n = G_N_ELEMENTS( my_fallback_icons );
153    GtkIconFactory * factory = gtk_icon_factory_new( );
154    GtkIconTheme * theme = gtk_icon_theme_get_default( );
155    gtk_icon_factory_add_default( factory );
156
157    for( i=0; i<n; ++i )
158    {
159        const char * name = my_fallback_icons[i].name;
160
161        if( !gtk_icon_theme_has_icon( theme, name ) )
162        {
163            int width;
164            GdkPixbuf * p;
165            GtkIconSet * icon_set;
166
167            p = gdk_pixbuf_new_from_inline( -1, my_fallback_icons[i].raw, FALSE, NULL );
168            width = gdk_pixbuf_get_width( p );
169            icon_set = gtk_icon_set_new_from_pixbuf( p );
170            gtk_icon_theme_add_builtin_icon( name, width, p );
171            gtk_icon_factory_add( factory, name, icon_set );
172
173            g_object_unref( p );
174            gtk_icon_set_unref( icon_set );
175        }
176    }
177
178    g_object_unref (G_OBJECT (factory));
179}
180
181static GtkUIManager * myUIManager = NULL;
182
183void
184actions_set_core( TrCore * core )
185{
186    myCore = core;
187}
188
189void
190actions_init( GtkUIManager * ui_manager, gpointer callback_user_data )
191{
192  int i, n;
193  int active;
194  const char * match;
195  const int n_entries = G_N_ELEMENTS( entries );
196  GtkActionGroup * action_group;
197
198  myUIManager = ui_manager;
199
200  register_my_icons( );
201
202  action_group = myGroup = gtk_action_group_new( "Actions" );
203  gtk_action_group_set_translation_domain( action_group, NULL );
204
205
206  match = pref_string_get( PREF_KEY_SORT_MODE );
207  for( i=0, n=G_N_ELEMENTS(sort_radio_entries), active=-1; active==-1 && i<n; ++i )
208      if( !strcmp( sort_radio_entries[i].name, match ) )
209          active = i;
210
211  gtk_action_group_add_radio_actions( action_group,
212                                      sort_radio_entries,
213                                      G_N_ELEMENTS(sort_radio_entries),
214                                      active,
215                                      G_CALLBACK(sort_changed_cb),
216                                      NULL );
217
218  gtk_action_group_add_toggle_actions( action_group, 
219                                       show_toggle_entries, 
220                                       G_N_ELEMENTS(show_toggle_entries), 
221                                       callback_user_data );
222
223  for( i=0, n=G_N_ELEMENTS(pref_toggle_entries); i<n; ++i )
224    pref_toggle_entries[i].is_active =
225      pref_flag_get( pref_toggle_entries[i].name );
226
227  gtk_action_group_add_toggle_actions( action_group, 
228                                       pref_toggle_entries, 
229                                       G_N_ELEMENTS(pref_toggle_entries), 
230                                       callback_user_data );
231
232  gtk_action_group_add_actions( action_group,
233                                entries, n_entries,
234                                callback_user_data );
235
236  gtk_ui_manager_insert_action_group( ui_manager, action_group, 0 );
237  g_object_unref (G_OBJECT(action_group));
238}
239
240/****
241*****
242****/
243
244static GHashTable * key_to_action = NULL;
245
246static void
247ensure_action_map_loaded (GtkUIManager * uim)
248{
249    GList * l;
250
251    if ( key_to_action != NULL )
252        return;
253
254    key_to_action =
255        g_hash_table_new_full( g_str_hash, g_str_equal, g_free, NULL);
256
257    for( l=gtk_ui_manager_get_action_groups(uim); l!=NULL; l=l->next )
258    {
259        GtkActionGroup * action_group = GTK_ACTION_GROUP( l->data );
260        GList *ait, *actions = gtk_action_group_list_actions( action_group );
261        for( ait=actions; ait!=NULL; ait=ait->next )
262        {
263            GtkAction * action = GTK_ACTION( ait->data );
264            const char * name = gtk_action_get_name( action );
265            g_hash_table_insert( key_to_action, g_strdup(name), action );
266        }
267        g_list_free( actions );
268    }
269}
270
271static GtkAction*
272get_action( const char* name )
273{
274    ensure_action_map_loaded( myUIManager );
275    return ( GtkAction* ) g_hash_table_lookup( key_to_action, name );
276}
277
278void
279action_activate ( const char * name )
280{
281    GtkAction * action = get_action( name );
282    g_assert( action != NULL );
283    gtk_action_activate( action );
284}
285
286void
287action_sensitize( const char * name, gboolean b )
288{
289    GtkAction * action = get_action( name );
290    g_assert( action != NULL );
291    g_object_set( action, "sensitive", b, NULL );
292}
293
294void
295action_toggle( const char * name, gboolean b )
296{
297    GtkAction * action = get_action( name );
298    gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action), b );
299}
300
301GtkWidget*
302action_get_widget( const char * path )
303{
304    return gtk_ui_manager_get_widget( myUIManager, path );
305}
Note: See TracBrowser for help on using the repository browser.