source: trunk/gtk/actions.c @ 6559

Last change on this file since 6559 was 6559, checked in by muks, 13 years ago

Don't show an error when transmission is run twice

Instead, present the main window. This commit also auto-generates
the dbus bindings.

  • Property svn:keywords set to Date Rev Author Id
File size: 10.0 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 6559 2008-08-17 12:39:26Z muks $
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  { "present-main-window", NULL, NULL, NULL, NULL, G_CALLBACK(action_cb) },
134};
135
136typedef struct
137{
138   const guint8* raw;
139   const char * name;
140}
141BuiltinIconInfo;
142
143static const BuiltinIconInfo my_fallback_icons [] =
144{
145    { tr_icon_logo, "transmission" },
146    { tr_icon_lock, "transmission-lock" }
147};
148
149static void
150register_my_icons ( void )
151{
152    int i;
153    const int n = G_N_ELEMENTS( my_fallback_icons );
154    GtkIconFactory * factory = gtk_icon_factory_new( );
155    GtkIconTheme * theme = gtk_icon_theme_get_default( );
156    gtk_icon_factory_add_default( factory );
157
158    for( i=0; i<n; ++i )
159    {
160        const char * name = my_fallback_icons[i].name;
161
162        if( !gtk_icon_theme_has_icon( theme, name ) )
163        {
164            int width;
165            GdkPixbuf * p;
166            GtkIconSet * icon_set;
167
168            p = gdk_pixbuf_new_from_inline( -1, my_fallback_icons[i].raw, FALSE, NULL );
169            width = gdk_pixbuf_get_width( p );
170            icon_set = gtk_icon_set_new_from_pixbuf( p );
171            gtk_icon_theme_add_builtin_icon( name, width, p );
172            gtk_icon_factory_add( factory, name, icon_set );
173
174            g_object_unref( p );
175            gtk_icon_set_unref( icon_set );
176        }
177    }
178
179    g_object_unref (G_OBJECT (factory));
180}
181
182static GtkUIManager * myUIManager = NULL;
183
184void
185actions_set_core( TrCore * core )
186{
187    myCore = core;
188}
189
190void
191actions_init( GtkUIManager * ui_manager, gpointer callback_user_data )
192{
193  int i, n;
194  int active;
195  const char * match;
196  const int n_entries = G_N_ELEMENTS( entries );
197  GtkActionGroup * action_group;
198
199  myUIManager = ui_manager;
200
201  register_my_icons( );
202
203  action_group = myGroup = gtk_action_group_new( "Actions" );
204  gtk_action_group_set_translation_domain( action_group, NULL );
205
206
207  match = pref_string_get( PREF_KEY_SORT_MODE );
208  for( i=0, n=G_N_ELEMENTS(sort_radio_entries), active=-1; active==-1 && i<n; ++i )
209      if( !strcmp( sort_radio_entries[i].name, match ) )
210          active = i;
211
212  gtk_action_group_add_radio_actions( action_group,
213                                      sort_radio_entries,
214                                      G_N_ELEMENTS(sort_radio_entries),
215                                      active,
216                                      G_CALLBACK(sort_changed_cb),
217                                      NULL );
218
219  gtk_action_group_add_toggle_actions( action_group, 
220                                       show_toggle_entries, 
221                                       G_N_ELEMENTS(show_toggle_entries), 
222                                       callback_user_data );
223
224  for( i=0, n=G_N_ELEMENTS(pref_toggle_entries); i<n; ++i )
225    pref_toggle_entries[i].is_active =
226      pref_flag_get( pref_toggle_entries[i].name );
227
228  gtk_action_group_add_toggle_actions( action_group, 
229                                       pref_toggle_entries, 
230                                       G_N_ELEMENTS(pref_toggle_entries), 
231                                       callback_user_data );
232
233  gtk_action_group_add_actions( action_group,
234                                entries, n_entries,
235                                callback_user_data );
236
237  gtk_ui_manager_insert_action_group( ui_manager, action_group, 0 );
238  g_object_unref (G_OBJECT(action_group));
239}
240
241/****
242*****
243****/
244
245static GHashTable * key_to_action = NULL;
246
247static void
248ensure_action_map_loaded (GtkUIManager * uim)
249{
250    GList * l;
251
252    if ( key_to_action != NULL )
253        return;
254
255    key_to_action =
256        g_hash_table_new_full( g_str_hash, g_str_equal, g_free, NULL);
257
258    for( l=gtk_ui_manager_get_action_groups(uim); l!=NULL; l=l->next )
259    {
260        GtkActionGroup * action_group = GTK_ACTION_GROUP( l->data );
261        GList *ait, *actions = gtk_action_group_list_actions( action_group );
262        for( ait=actions; ait!=NULL; ait=ait->next )
263        {
264            GtkAction * action = GTK_ACTION( ait->data );
265            const char * name = gtk_action_get_name( action );
266            g_hash_table_insert( key_to_action, g_strdup(name), action );
267        }
268        g_list_free( actions );
269    }
270}
271
272static GtkAction*
273get_action( const char* name )
274{
275    ensure_action_map_loaded( myUIManager );
276    return ( GtkAction* ) g_hash_table_lookup( key_to_action, name );
277}
278
279void
280action_activate ( const char * name )
281{
282    GtkAction * action = get_action( name );
283    g_assert( action != NULL );
284    gtk_action_activate( action );
285}
286
287void
288action_sensitize( const char * name, gboolean b )
289{
290    GtkAction * action = get_action( name );
291    g_assert( action != NULL );
292    g_object_set( action, "sensitive", b, NULL );
293}
294
295void
296action_toggle( const char * name, gboolean b )
297{
298    GtkAction * action = get_action( name );
299    gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action), b );
300}
301
302GtkWidget*
303action_get_widget( const char * path )
304{
305    return gtk_ui_manager_get_widget( myUIManager, path );
306}
Note: See TracBrowser for help on using the repository browser.