Changeset 5015
- Timestamp:
- Feb 13, 2008, 3:00:21 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gtk/Makefile.am
r5003 r5015 24 24 makemeta-ui.h \ 25 25 msgwin.h \ 26 open.h \ 26 27 stats.h \ 27 28 sexy-icon-entry.h \ … … 49 50 makemeta-ui.c \ 50 51 msgwin.c \ 52 open.c \ 51 53 sexy-icon-entry.c \ 52 54 stats.c \ -
trunk/gtk/dialogs.c
r4848 r5015 23 23 *****************************************************************************/ 24 24 25 #include <errno.h>26 #include <stdio.h>27 #include <stdlib.h>28 #include <string.h>29 30 25 #include <gtk/gtk.h> 31 26 #include <glib/gi18n.h> … … 37 32 #include "hig.h" 38 33 #include "tr_core.h" 39 #include "tr_icon.h"40 34 #include "tr_prefs.h" 41 #include "util.h" 42 43 #define UPDATE_INTERVAL 1000 44 #define PREFNAME "transmission-dialog-pref-name" 45 #define FILESWIND_EXTRA_INDENT 4 46 47 #define STRIPROOT( path ) \ 48 ( g_path_is_absolute( (path) ) ? g_path_skip_root( (path) ) : (path) ) 49 50 struct addcb 51 { 52 GtkWidget * widget; 53 TrCore * core; 54 gboolean autostart; 55 gboolean usingaltdir; 56 GtkFileChooser *altdir; 57 GtkButtonBox *altbox; 35 36 struct dirdata 37 { 38 GtkWidget * widget; 39 TrCore * core; 40 GList * files; 41 tr_ctor * ctor; 58 42 }; 59 43 60 struct dirdata 61 { 62 GtkWidget * widget; 63 TrCore * core; 64 GList * files; 65 uint8_t * data; 66 size_t size; 67 enum tr_torrent_action action; 68 gboolean paused; 69 }; 70 71 static void 72 addwindnocore( gpointer gdata, GObject * core ); 73 static void 74 autoclick(GtkWidget *widget, gpointer gdata); 75 static void 76 dirclick(GtkWidget *widget, gpointer gdata); 77 static void 78 addresp(GtkWidget *widget, gint resp, gpointer gdata); 79 static void 80 promptdirnocore( gpointer gdata, GObject * core ); 81 static void 82 promptresp( GtkWidget * widget, gint resp, gpointer data ); 83 84 void 85 makeaddwind( GtkWindow * parent, TrCore * core ) 86 { 87 GtkWidget *wind = gtk_file_chooser_dialog_new(_("Open Torrent"), parent, 88 GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, 89 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); 90 struct addcb *data = g_new(struct addcb, 1); 91 GtkWidget *vbox = gtk_vbox_new(FALSE, 3); 92 GtkWidget *bbox = gtk_hbutton_box_new(); 93 GtkWidget *autocheck = gtk_check_button_new_with_mnemonic( 94 _("Automatically _start torrent")); 95 GtkWidget *dircheck = gtk_check_button_new_with_mnemonic( 96 _("Use alternate _download directory")); 97 GtkFileFilter *filter = gtk_file_filter_new(); 98 GtkFileFilter *unfilter = gtk_file_filter_new(); 99 GtkWidget *getdir = gtk_file_chooser_button_new( 100 _("Choose a download directory"), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); 101 char * pref; 102 103 data->widget = wind; 104 data->core = core; 105 data->autostart = TRUE; 106 data->usingaltdir = FALSE; 107 data->altdir = GTK_FILE_CHOOSER(getdir); 108 data->altbox = GTK_BUTTON_BOX(bbox); 109 110 g_object_weak_ref( G_OBJECT( core ), addwindnocore, data ); 111 112 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_EDGE); 113 gtk_box_pack_start_defaults(GTK_BOX(bbox), dircheck); 114 gtk_box_pack_start_defaults(GTK_BOX(bbox), getdir); 115 116 gtk_box_pack_start_defaults(GTK_BOX(vbox), autocheck); 117 gtk_box_pack_start_defaults(GTK_BOX(vbox), bbox); 118 119 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(autocheck), TRUE); 120 pref = pref_string_get( PREF_KEY_DIR_DEFAULT ); 121 if( pref != NULL ) { 122 gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER( wind ), pref ); 123 g_free( pref ); 124 } 125 126 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dircheck), FALSE); 127 gtk_widget_set_sensitive(getdir, FALSE); 128 129 gtk_file_filter_set_name(filter, _("Torrent files")); 130 gtk_file_filter_add_pattern(filter, "*.torrent"); 131 gtk_file_filter_set_name(unfilter, _("All files")); 132 gtk_file_filter_add_pattern(unfilter, "*"); 133 134 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(wind), filter); 135 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(wind), unfilter); 136 gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(wind), TRUE); 137 gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(wind), vbox); 138 139 g_signal_connect(G_OBJECT(autocheck), "clicked", G_CALLBACK(autoclick),data); 140 g_signal_connect(G_OBJECT(dircheck), "clicked", G_CALLBACK(dirclick), data); 141 g_signal_connect(G_OBJECT(wind), "response", G_CALLBACK(addresp), data); 142 143 gtk_widget_show_all(wind); 144 } 145 146 void 147 addwindnocore( gpointer gdata, GObject * core UNUSED ) 148 { 149 struct addcb * data = gdata; 44 static void 45 promptdirnocore( gpointer gdata, GObject * core UNUSED ) 46 { 47 struct dirdata * stuff = gdata; 150 48 151 49 /* prevent the response callback from trying to remove the weak 152 50 reference which no longer exists */ 153 data->core = NULL; 154 155 gtk_dialog_response( GTK_DIALOG( data->widget ), GTK_RESPONSE_NONE ); 156 } 157 158 static void 159 autoclick(GtkWidget *widget, gpointer gdata) { 160 struct addcb *data = gdata; 161 162 data->autostart = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); 163 } 164 165 static void 166 dirclick(GtkWidget *widget, gpointer gdata) { 167 struct addcb *data = gdata; 168 169 data->usingaltdir = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); 170 gtk_widget_set_sensitive(GTK_WIDGET(data->altdir), data->usingaltdir); 171 } 172 173 static void 174 addresp(GtkWidget *widget, gint resp, gpointer gdata) { 175 struct addcb *data = gdata; 176 GSList *files, *ii; 177 GList *stupidgtk; 178 char *dir; 179 enum tr_torrent_action action; 180 181 if(GTK_RESPONSE_ACCEPT == resp) { 182 dir = NULL; 183 if(data->usingaltdir) 184 dir = gtk_file_chooser_get_filename(data->altdir); 185 files = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(widget)); 186 action = tr_prefs_get_action( PREF_KEY_ADDSTD ); 187 188 if( NULL == dir ) 51 stuff->core = NULL; 52 53 gtk_dialog_response( GTK_DIALOG( stuff->widget ), GTK_RESPONSE_NONE ); 54 } 55 56 static void 57 promptresp( GtkWidget * widget, gint resp, gpointer data ) 58 { 59 struct dirdata * stuff; 60 61 stuff = data; 62 63 if( GTK_RESPONSE_ACCEPT == resp ) 189 64 { 190 stupidgtk = NULL; 191 for( ii = files; NULL != ii; ii = ii->next ) 192 { 193 stupidgtk = g_list_append( stupidgtk, ii->data ); 194 } 195 tr_core_add_list( data->core, stupidgtk, action, !data->autostart ); 196 freestrlist(stupidgtk); 197 } 198 else 199 { 200 for( ii = files; NULL != ii; ii = ii->next ) 201 { 202 tr_core_add_dir( data->core, ii->data, dir, 203 action, !data->autostart ); 204 g_free( ii->data ); 205 } 65 char * dir; 66 GList * l; 67 68 /* update the destination */ 69 dir = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER( widget ) ); 70 tr_ctorSetDestination( stuff->ctor, TR_FORCE, dir ); 206 71 g_free( dir ); 207 } 208 tr_core_torrents_added( data->core ); 209 g_slist_free(files); 210 } 211 212 if( NULL != data->core ) 213 { 214 g_object_weak_unref( G_OBJECT( data->core ), addwindnocore, data ); 215 } 216 217 g_free( data ); 218 gtk_widget_destroy(widget); 72 73 /* if there's metainfo in the ctor already, use it */ 74 if( !tr_ctorGetMetainfo( stuff->ctor, NULL ) ) 75 tr_core_add_ctor( stuff->core, stuff->ctor ); 76 77 /* if there's a list of files, use them too */ 78 for( l=stuff->files; l!=NULL; l=l->next ) 79 if( !tr_ctorSetMetainfoFromFile( stuff->ctor, l->data ) ) 80 tr_core_add_ctor( stuff->core, stuff->ctor ); 81 } 82 83 if( stuff->core ) 84 g_object_weak_unref( G_OBJECT( stuff->core ), promptdirnocore, stuff ); 85 86 gtk_widget_destroy( widget ); 87 freestrlist( stuff->files ); 88 tr_ctorFree( stuff->ctor ); 89 g_free( stuff ); 219 90 } 220 91 … … 235 106 } 236 107 108 static void 109 deleteToggled( GtkToggleButton * tb, gpointer ctor ) 110 { 111 tr_ctorSetDeleteSource( ctor, gtk_toggle_button_get_active( tb ) ); 112 } 113 114 static void 115 startToggled( GtkToggleButton * tb, gpointer ctor ) 116 { 117 tr_ctorSetPaused( ctor, TR_FORCE, !gtk_toggle_button_get_active( tb ) ); 118 } 119 237 120 void 238 promptfordir( GtkWindow * parent, TrCore * core, GList * files, uint8_t * data,239 size_t size, enum tr_torrent_action act, gboolean paused ) 240 { 241 c har * path;121 promptfordir( GtkWindow * parent, TrCore * core, GList * files, tr_ctor * ctor ) 122 { 123 uint8_t flag = 0; 124 const char * str; 242 125 struct dirdata * stuff; 243 126 GtkWidget * wind; 127 GtkWidget * v; 128 GtkWidget * w; 244 129 245 130 stuff = g_new0( struct dirdata, 1 ); 246 stuff->core = core; 247 if( NULL != files ) 248 { 249 stuff->files = dupstrlist( files ); 250 } 251 if( NULL != data ) 252 { 253 stuff->data = g_new( uint8_t, size ); 254 memcpy( stuff->data, data, size ); 255 stuff->size = size; 256 } 257 stuff->action = act; 258 stuff->paused = paused; 131 stuff->core = core; 132 stuff->ctor = ctor; 133 stuff->files = dupstrlist( files ); 259 134 260 135 g_object_weak_ref( G_OBJECT( core ), promptdirnocore, stuff ); … … 267 142 gtk_file_chooser_set_local_only( GTK_FILE_CHOOSER( wind ), TRUE ); 268 143 gtk_file_chooser_set_select_multiple( GTK_FILE_CHOOSER( wind ), FALSE ); 269 path = getdownloaddir( ); 270 gtk_file_chooser_set_filename( GTK_FILE_CHOOSER( wind ), path ); 271 g_free( path ); 144 tr_ctorGetDestination( ctor, TR_FORCE, &str ); 145 gtk_file_chooser_set_uri( GTK_FILE_CHOOSER( wind ), str ); 146 147 v = gtk_vbox_new( FALSE, GUI_PAD ); 148 149 w = gtk_check_button_new_with_mnemonic( _( "_Delete original torrent file" ) ); 150 g_signal_connect( w, "toggled", G_CALLBACK( deleteToggled ), ctor ); 151 tr_ctorGetDeleteSource( ctor, &flag ); 152 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( w ), flag ); 153 gtk_box_pack_start( GTK_BOX( v ), w, FALSE, FALSE, 0 ); 154 155 w = gtk_check_button_new_with_mnemonic( _( "_Start when added" ) ); 156 g_signal_connect( w, "toggled", G_CALLBACK( startToggled ), ctor ); 157 tr_ctorGetPaused( ctor, TR_FORCE, &flag ); 158 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( w ), !flag ); 159 gtk_box_pack_start( GTK_BOX( v ), w, FALSE, FALSE, 0 ); 160 161 gtk_file_chooser_set_extra_widget( GTK_FILE_CHOOSER( wind ), v ); 272 162 273 163 stuff->widget = wind; … … 277 167 278 168 gtk_widget_show_all(wind); 279 }280 281 void282 promptdirnocore( gpointer gdata, GObject * core UNUSED )283 {284 struct dirdata * stuff = gdata;285 286 /* prevent the response callback from trying to remove the weak287 reference which no longer exists */288 stuff->core = NULL;289 290 gtk_dialog_response( GTK_DIALOG( stuff->widget ), GTK_RESPONSE_NONE );291 }292 293 static void294 promptresp( GtkWidget * widget, gint resp, gpointer data )295 {296 struct dirdata * stuff;297 char * dir;298 GList * ii;299 300 stuff = data;301 302 if( GTK_RESPONSE_ACCEPT == resp )303 {304 dir = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER( widget ) );305 /* it seems that we will always get a directory */306 g_assert( NULL != dir );307 for( ii = g_list_first( stuff->files ); NULL != ii; ii = ii->next )308 {309 tr_core_add_dir( stuff->core, ii->data, dir,310 stuff->action, stuff->paused );311 }312 if( NULL != stuff->data )313 {314 tr_core_add_data_dir( stuff->core, stuff->data, stuff->size, dir,315 stuff->paused );316 }317 tr_core_torrents_added( stuff->core );318 g_free( dir );319 }320 321 if( NULL != stuff->core )322 {323 g_object_weak_unref( G_OBJECT( stuff->core ), promptdirnocore, stuff );324 }325 326 freestrlist( stuff->files );327 g_free( stuff->data );328 g_free( stuff );329 gtk_widget_destroy( widget );330 169 } 331 170 … … 346 185 { 347 186 struct quitdata * stuff = data; 348 349 pref_flag_set( PREF_KEY_ASKQUIT, 350 !gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(stuff->dontask) ) ); 187 GtkToggleButton * tb = GTK_TOGGLE_BUTTON( stuff->dontask ); 188 189 tr_core_set_pref_bool( stuff->core, 190 PREF_KEY_ASKQUIT, 191 !gtk_toggle_button_get_active( tb ) ); 351 192 352 193 if( response == GTK_RESPONSE_ACCEPT ) -
trunk/gtk/dialogs.h
r4404 r5015 30 30 #include "util.h" 31 31 32 /* show the "add a torrent" dialog */33 void34 makeaddwind( GtkWindow * parent, TrCore * core );35 36 32 /* prompt for a download directory for torrents, then add them */ 37 void 38 promptfordir( GtkWindow * parent, TrCore * core, GList * files, uint8_t * data, 39 size_t size, enum tr_torrent_action act, gboolean paused ); 33 void promptfordir( GtkWindow* parent, TrCore*, GList* filenames, tr_ctor* ); 40 34 41 35 /* prompt if the user wants to quit, calls func with cbdata if they do */ 42 void 43 askquit( TrCore*, GtkWindow* parent, callbackfunc_t func, void * cbdata ); 36 void askquit( TrCore*, GtkWindow* parent, callbackfunc_t func, void* cbdata ); 44 37 45 38 #endif /* TG_PREFS_H */ -
trunk/gtk/file-list.c
r5009 r5015 375 375 { 376 376 FileData * data = gdata; 377 378 g_object_weak_unref( G_OBJECT( data->gtor ), torrentDestroyed, data ); 379 377 380 file_list_set_torrent( data->top, NULL ); 378 381 } -
trunk/gtk/ipc.c
r4876 r5015 580 580 struct constate * con = arg; 581 581 struct constate_serv * srv = &con->u.serv; 582 enum tr_torrent_action action;583 582 benc_val_t * path; 584 583 int ii; 584 tr_ctor * ctor; 585 GList * list = NULL; 585 586 586 587 if( NULL == val || TYPE_LIST != val->type ) … … 590 591 } 591 592 592 action = tr_prefs_get_action( PREF_KEY_ADDIPC ); 593 ctor = tr_ctorNew( srv->core ); 594 593 595 for( ii = 0; ii < val->val.l.count; ii++ ) 594 596 { … … 598 600 g_utf8_validate( path->val.s.s, path->val.s.i, NULL ) ) 599 601 { 600 tr_core_add( TR_CORE( srv->core ), path->val.s.s, action, FALSE ); 601 } 602 } 603 tr_core_torrents_added( TR_CORE( srv->core ) ); 602 list = g_list_append( list, g_strndup( path->val.s.s, path->val.s.i ) ); 603 } 604 } 605 606 if( list ) { 607 tr_core_add_list( srv->core, list, ctor ); 608 tr_core_torrents_added( TR_CORE( srv->core ) ); 609 } 604 610 605 611 /* XXX should send info response back with torrent ids */ … … 613 619 struct constate * con = arg; 614 620 struct constate_serv * srv = &con->u.serv; 615 enum tr_torrent_action action;616 621 benc_val_t * file, * data, * dir, * start; 617 gboolean paused;622 tr_ctor * ctor; 618 623 619 624 if( NULL == val || TYPE_DICT != val->type ) … … 637 642 } 638 643 639 action = tr_prefs_get_action( PREF_KEY_ADDIPC ); 640 paused = ( NULL == start || start->val.i ? FALSE : TRUE ); 641 if( NULL != file ) 642 { 643 if( NULL == dir ) 644 { 645 tr_core_add( srv->core, file->val.s.s, action, paused ); 646 } 647 else 648 { 649 tr_core_add_dir( srv->core, file->val.s.s, dir->val.s.s, 650 action, paused ); 651 } 652 } 653 else 654 { 655 if( NULL == dir ) 656 { 657 tr_core_add_data( srv->core, (uint8_t *) data->val.s.s, 658 data->val.s.i, paused ); 659 } 660 else 661 { 662 tr_core_add_data_dir( srv->core, (uint8_t *) data->val.s.s, 663 data->val.s.i, dir->val.s.s, paused ); 664 } 665 } 644 ctor = tr_ctorNew( tr_core_handle( srv->core ) ); 645 if( dir ) 646 tr_ctorSetDestination( ctor, TR_FORCE, dir->val.s.s ); 647 if( file ) 648 tr_ctorSetMetainfoFromFile( ctor, file->val.s.s ); 649 if( data ) 650 tr_ctorSetMetainfo( ctor, (uint8_t*)data->val.s.s, data->val.s.i ); 651 if( start ) 652 tr_ctorSetPaused( ctor, TR_FORCE, !start->val.i ); 653 654 tr_core_add_ctor( TR_CORE( srv->core ), ctor ); 655 666 656 tr_core_torrents_added( TR_CORE( srv->core ) ); 667 657 … … 999 989 case IPC_MSG_GETDIR: 1000 990 /* XXX sending back "" when we're prompting is kind of bogus */ 1001 pref = pref_flag_get( PREF_KEY_ DIR_ASK) ? "" : getdownloaddir();991 pref = pref_flag_get( PREF_KEY_OPTIONS_PROMPT ) ? "" : getdownloaddir(); 1002 992 buf = ipc_mkstr( con->ipc, &size, IPC_MSG_DIR, tag, pref ); 1003 993 break; -
trunk/gtk/main.c
r4982 r5015 48 48 #include "makemeta-ui.h" 49 49 #include "msgwin.h" 50 #include "open.h" 50 51 #include "stats.h" 51 52 #include "torrent-inspector.h" … … 147 148 gpointer gdata ); 148 149 static void 149 coreprompt( TrCore *, GList *, enum tr_torrent_action, gboolean, gpointer ); 150 static void 151 corepromptdata( TrCore *, uint8_t *, size_t, gboolean, gpointer ); 150 coreprompt( TrCore *, GList *, gpointer, gpointer ); 152 151 static void 153 152 initializeFromPrefs( struct cbdata * cbdata ); … … 330 329 appsetup( TrWindow * wind, GList * args, 331 330 struct cbdata * cbdata, 332 gboolean paused, gboolean minimized ) 333 { 334 enum tr_torrent_action action; 335 331 gboolean forcepause, gboolean minimized ) 332 { 336 333 /* fill out cbdata */ 337 334 cbdata->wind = NULL; … … 350 347 g_signal_connect( cbdata->core, "directory-prompt", 351 348 G_CALLBACK( coreprompt ), cbdata ); 352 g_signal_connect( cbdata->core, "directory-prompt-data",353 G_CALLBACK( corepromptdata ), cbdata );354 349 g_signal_connect_swapped( cbdata->core, "quit", 355 350 G_CALLBACK( wannaquit ), cbdata ); … … 364 359 365 360 /* add torrents from command-line and saved state */ 366 tr_core_load( cbdata->core, paused);361 tr_core_load( cbdata->core, forcepause ); 367 362 368 363 if( NULL != args ) 369 364 { 370 action = tr_prefs_get_action( PREF_KEY_ADDIPC ); 371 tr_core_add_list( cbdata->core, args, action, paused ); 365 tr_ctor * ctor = tr_ctorNew( tr_core_handle( cbdata->core ) ); 366 if( forcepause ) 367 tr_ctorSetPaused( ctor, TR_FORCE, TRUE ); 368 tr_core_add_list( cbdata->core, args, ctor ); 372 369 } 373 370 tr_core_torrents_added( cbdata->core ); … … 626 623 GList * freeme = NULL; 627 624 628 #ifdef DND_DEBUG 625 #if 0 626 int i; 629 627 char *sele = gdk_atom_name(sel->selection); 630 628 char *targ = gdk_atom_name(sel->target); … … 684 682 if( paths != NULL ) 685 683 { 686 enum tr_torrent_action action = tr_prefs_get_action( PREF_KEY_ADDSTD);684 tr_ctor * ctor = tr_ctorNew( tr_core_handle( data->core ) ); 687 685 paths = g_list_reverse( paths ); 688 tr_core_add_list( data->core, paths, action, FALSE);686 tr_core_add_list( data->core, paths, ctor ); 689 687 tr_core_torrents_added( data->core ); 690 688 g_list_free( paths ); … … 749 747 } 750 748 751 void 752 coreprompt( TrCore * core, GList * paths, enum tr_torrent_action act, 753 gboolean paused, gpointer gdata ) 749 static void 750 coreprompt( TrCore * core, 751 GList * paths, 752 gpointer ctor, 753 gpointer gdata ) 754 754 { 755 755 struct cbdata * cbdata = gdata; 756 756 757 promptfordir( cbdata->wind, core, paths, NULL, 0, act, paused ); 758 } 759 760 void 761 corepromptdata( TrCore * core, uint8_t * data, size_t size, 762 gboolean paused, gpointer gdata ) 763 { 764 struct cbdata * cbdata = gdata; 765 766 promptfordir( cbdata->wind, core, NULL, data, size, TR_TOR_LEAVE, paused ); 757 if( g_list_length( paths ) != 1 ) 758 promptfordir( cbdata->wind, core, paths, ctor ); 759 else { 760 tr_ctorSetMetainfoFromFile( ctor, paths->data ); 761 makeaddwind( cbdata->wind, core, ctor ); 762 } 767 763 } 768 764 … … 1014 1010 if ( !strcmp (action_name, "open-torrent-menu") || !strcmp( action_name, "open-torrent-toolbar" )) 1015 1011 { 1016 makeaddwind( data->wind, data->core );1012 makeaddwind( data->wind, data->core, tr_ctorNew( tr_core_handle( data->core ) ) ); 1017 1013 } 1018 1014 else if (!strcmp (action_name, "show-stats")) -
trunk/gtk/my-valgrind.sh
r3160 r5015 3 3 export G_DEBUG=gc-friendly 4 4 export GLIBCXX_FORCE_NEW=1 5 valgrind --tool=memcheck --leak-check=full --leak-resolution=high --num-callers=64 --log-file=x-valgrind --show-reachable=yes ./transmission 5 valgrind --tool=memcheck --leak-check=full --leak-resolution=high --num-callers=64 --log-file=x-valgrind --show-reachable=yes ./transmission ~/Desktop/*torrent -
trunk/gtk/tr_core.c
r5005 r5015 78 78 gpointer marshal ) 79 79 { 80 typedef void (*TRMarshalPrompt) 81 ( gpointer, GList *, enum tr_torrent_action, gboolean, gpointer ); 80 typedef void (*TRMarshalPrompt)( gpointer, GList *, gpointer, gpointer ); 82 81 TRMarshalPrompt callback; 83 82 GCClosure * cclosure = (GCClosure*) closure; 84 83 GList * paths; 85 enum tr_torrent_action action; 86 gboolean paused; 84 gpointer ctor; 87 85 gpointer inst, gdata; 88 86 89 g_return_if_fail( 4 == count ); 90 91 inst = g_value_peek_pointer( vals ); 92 paths = g_value_get_pointer( vals + 1 ); 93 action = g_value_get_int( vals + 2 ); 94 paused = g_value_get_boolean( vals + 3 ); 95 gdata = closure->data; 87 g_return_if_fail( 3 == count ); 88 89 inst = g_value_peek_pointer( vals ); 90 paths = g_value_get_pointer( vals + 1 ); 91 ctor = g_value_get_pointer( vals + 2 ); 92 gdata = closure->data; 96 93 97 94 callback = (TRMarshalPrompt) ( NULL == marshal ? 98 95 cclosure->callback : marshal ); 99 callback( inst, paths, action, paused, gdata ); 100 } 101 102 static void 103 tr_core_marshal_data( GClosure * closure, GValue * ret UNUSED, guint count, 104 const GValue * vals, gpointer hint UNUSED, 105 gpointer marshal ) 106 { 107 typedef void (*TRMarshalPrompt) 108 ( gpointer, uint8_t *, size_t, gboolean, gpointer ); 109 TRMarshalPrompt callback; 110 GCClosure * cclosure = (GCClosure*) closure; 111 uint8_t * data; 112 size_t size; 113 gboolean paused; 114 gpointer inst, gdata; 115 116 g_return_if_fail( 4 == count ); 117 118 inst = g_value_peek_pointer( vals ); 119 data = (uint8_t *) g_value_get_string( vals + 1 ); 120 size = g_value_get_uint( vals + 2 ); 121 paused = g_value_get_boolean( vals + 3 ); 122 gdata = closure->data; 123 124 callback = (TRMarshalPrompt) ( NULL == marshal ? 125 cclosure->callback : marshal ); 126 callback( inst, data, size, paused, gdata ); 96 callback( inst, paths, ctor, gdata ); 127 97 } 128 98 … … 172 142 G_SIGNAL_RUN_LAST, 0, NULL, NULL, 173 143 tr_core_marshal_prompt, G_TYPE_NONE, 174 3, G_TYPE_POINTER, G_TYPE_INT, 175 G_TYPE_BOOLEAN ); 176 core_class->promptdatasig = g_signal_new( "directory-prompt-data", 177 G_TYPE_FROM_CLASS( g_class ), 178 G_SIGNAL_RUN_LAST, 0, NULL, NULL, 179 tr_core_marshal_data, 180 G_TYPE_NONE, 3, G_TYPE_STRING, 181 G_TYPE_UINT, G_TYPE_BOOLEAN ); 144 2, G_TYPE_POINTER, G_TYPE_POINTER ); 182 145 core_class->quitsig = g_signal_new( "quit", G_TYPE_FROM_CLASS( g_class ), 183 146 G_SIGNAL_RUN_LAST, 0, NULL, NULL, … … 487 450 } 488 451 489 staticvoid490 tr_core_ insert( TrCore * self, TrTorrent * tor )452 void 453 tr_core_add_torrent( TrCore * self, TrTorrent * tor ) 491 454 { 492 455 const tr_info * inf = tr_torrent_info( tor ); … … 495 458 GtkListStore * store = GTK_LIST_STORE( tr_core_model( self ) ); 496 459 GtkTreeIter unused; 460 497 461 gtk_list_store_insert_with_values( store, &unused, 0, 498 462 MC_NAME, inf->name, … … 504 468 MC_ID, self->priv->nextid, 505 469 -1); 506 self->priv->nextid++; 507 g_object_unref( tor ); 470 ++self->priv->nextid; 471 472 /* cleanup */ 473 g_object_unref( G_OBJECT( tor ) ); 508 474 g_free( collated ); 509 475 } … … 530 496 torrents = tr_loadTorrents ( tr_core_handle( self ), ctor, &count ); 531 497 for( i=0; i<count; ++i ) 532 tr_core_ insert( self, tr_torrent_new_preexisting( torrents[i] ) );498 tr_core_add_torrent( self, tr_torrent_new_preexisting( torrents[i] ) ); 533 499 534 500 tr_free( torrents ); … … 539 505 } 540 506 541 gboolean542 tr_core_add( TrCore * self, const char * path, enum tr_torrent_action act,543 gboolean paused )544 {545 GList * list;546 int ret;547 548 TR_IS_CORE( self );549 550 list = g_list_append( NULL, (void *) path );551 ret = tr_core_add_list( self, list, act, paused );552 g_list_free( list );553 554 return 1 == ret;555 }556 557 507 static void 558 508 tr_core_errsig( TrCore * self, enum tr_core_err type, const char * msg ) … … 564 514 } 565 515 566 gboolean 567 tr_core_add_dir( TrCore * self, const char * path, const char * dir, 568 enum tr_torrent_action act, gboolean paused ) 516 static void 517 tr_core_apply_defaults( tr_ctor * ctor ) 518 { 519 if( tr_ctorGetPaused( ctor, TR_FORCE, NULL ) ) 520 tr_ctorSetPaused( ctor, TR_FORCE, !pref_flag_get( PREF_KEY_START ) ); 521 522 if( tr_ctorGetDeleteSource( ctor, NULL ) ) 523 tr_ctorSetDeleteSource( ctor, pref_flag_get( PREF_KEY_DELETE_ORIGINAL ) ); 524 525 if( tr_ctorGetMaxConnectedPeers( ctor, TR_FORCE, NULL ) ) 526 tr_ctorSetMaxConnectedPeers( ctor, TR_FORCE, pref_int_get( PREF_KEY_MAX_PEERS_PER_TORRENT ) ); 527 528 if( tr_ctorGetDestination( ctor, TR_FORCE, NULL ) ) { 529 char * path = pref_string_get( PREF_KEY_DIR_DEFAULT ); 530 tr_ctorSetDestination( ctor, TR_FORCE, path ); 531 g_free( path ); 532 } 533 } 534 535 void 536 tr_core_add_ctor( TrCore * self, tr_ctor * ctor ) 569 537 { 570 538 TrTorrent * tor; 571 539 char * errstr; 572 540 573 TR_IS_CORE( self );574 575 541 errstr = NULL; 576 tor = tr_torrent_new( tr_core_handle( self ), path, dir, act, paused, &errstr ); 577 if( NULL == tor ) 542 543 tr_core_apply_defaults( ctor ); 544 tor = tr_torrent_new_ctor( tr_core_handle( self ), ctor, &errstr ); 545 if( !tor ) 578 546 { 579 547 tr_core_errsig( self, TR_CORE_ERR_ADD_TORRENT, errstr ); 580 548 g_free( errstr ); 581 return FALSE; 582 } 583 g_assert( NULL == errstr ); 584 585 tr_core_insert( self, tor ); 586 587 return TRUE; 588 } 589 590 int 591 tr_core_add_list( TrCore * self, GList * paths, enum tr_torrent_action act, 592 gboolean paused ) 593 { 594 char * dir; 595 int count; 596 597 TR_IS_CORE( self ); 598 599 if( pref_flag_get( PREF_KEY_DIR_ASK ) ) 549 errstr = NULL; 550 } 551 else 552 { 553 g_assert( !errstr ); 554 tr_core_add_torrent( self, tor ); 555 } 556 } 557 558 void 559 tr_core_add_list( TrCore * self, 560 GList * paths, 561 tr_ctor * ctor ) 562 { 563 tr_core_apply_defaults( ctor ); 564 565 if( pref_flag_get( PREF_KEY_OPTIONS_PROMPT ) ) 600 566 { 601 567 TrCoreClass * class = g_type_class_peek( TR_CORE_TYPE ); 602 g_signal_emit( self, class->promptsig, 0, paths, act, paused ); 603 return 0; 604 } 605 606 dir = getdownloaddir(); 607 count = 0; 608 for( ; paths; paths=paths->next ) 609 if( tr_core_add_dir( self, paths->data, dir, act, paused ) ) 610 count++; 611 612 g_free( dir ); 613 return count; 614 } 615 616 gboolean 617 tr_core_add_data( TrCore * self, uint8_t * data, size_t size, gboolean paused ) 618 { 619 gboolean ret; 620 char * path; 621 TR_IS_CORE( self ); 622 623 if( pref_flag_get( PREF_KEY_DIR_ASK ) ) 624 { 625 TrCoreClass * class = g_type_class_peek( TR_CORE_TYPE ); 626 g_signal_emit( self, class->promptdatasig, 0, data, size, paused ); 627 return FALSE; 628 } 629 630 path = getdownloaddir( ); 631 ret = tr_core_add_data_dir( self, data, size, path, paused ); 632 g_free( path ); 633 return ret; 634 } 635 636 gboolean 637 tr_core_add_data_dir( TrCore * self, uint8_t * data, size_t size, 638 const char * dir, gboolean paused ) 639 { 640 TrTorrent * tor; 641 char * errstr = NULL; 642 643 TR_IS_CORE( self ); 644 645 tor = tr_torrent_new_with_data( tr_core_handle( self ), data, size, dir, 646 paused, &errstr ); 647 if( NULL == tor ) 648 { 649 tr_core_errsig( self, TR_CORE_ERR_ADD_TORRENT, errstr ); 650 g_free( errstr ); 651 return FALSE; 652 } 653 g_assert( NULL == errstr ); 654 655 tr_core_insert( self, tor ); 656 657 return TRUE; 568 g_signal_emit( self, class->promptsig, 0, paths, ctor ); 569 } 570 else 571 { 572 for( ; paths; paths=paths->next ) 573 if( !tr_ctorSetMetainfoFromFile( ctor, paths->data ) ) 574 tr_core_add_ctor( self, ctor ); 575 tr_ctorFree( ctor ); 576 } 658 577 } 659 578 … … 661 580 tr_core_torrents_added( TrCore * self ) 662 581 { 663 TR_IS_CORE( self );664 665 582 tr_core_update( self ); 666 583 tr_core_errsig( self, TR_CORE_ERR_NO_MORE_TORRENTS, NULL ); … … 672 589 TrTorrent * tor; 673 590 GtkTreeModel * model = tr_core_model( self ); 674 675 TR_IS_CORE( self );676 591 677 592 gtk_tree_model_get( model, iter, MC_TORRENT, &tor, -1 ); … … 747 662 tr_core_quit( TrCore * self ) 748 663 { 749 TrCoreClass * class; 750 751 TR_IS_CORE( self ); 752 753 class = g_type_class_peek( TR_CORE_TYPE ); 664 TrCoreClass * class = g_type_class_peek( TR_CORE_TYPE ); 754 665 g_signal_emit( self, class->quitsig, 0 ); 755 666 } -
trunk/gtk/tr_core.h
r4998 r5015 31 31 #include <gtk/gtk.h> 32 32 33 #include <libtransmission/bencode.h>34 33 #include <libtransmission/transmission.h> 35 34 35 #include "tr_torrent.h" 36 36 #include "util.h" 37 37 38 #define TR_CORE_TYPE ( tr_core_get_type() ) 39 40 #define TR_CORE( obj ) \ 41 ( G_TYPE_CHECK_INSTANCE_CAST( (obj), TR_CORE_TYPE, TrCore ) ) 42 43 #define TR_CORE_CLASS( class ) \ 44 ( G_TYPE_CHECK_CLASS_CAST( (class), TR_CORE_TYPE, TrCoreClass ) ) 45 46 #define TR_IS_CORE( obj ) \ 47 ( G_TYPE_CHECK_INSTANCE_TYPE( (obj), TR_CORE_TYPE ) ) 48 49 #define TR_IS_CORE_CLASS( class ) \ 50 ( G_TYPE_CHECK_CLASS_TYPE( (class), TR_CORE_TYPE ) ) 51 52 #define TR_CORE_GET_CLASS( obj ) \ 53 ( G_TYPE_INSTANCE_GET_CLASS( (obj), TR_CORE_TYPE, TrCoreClass ) ) 54 38 #define TR_CORE_TYPE (tr_core_get_type()) 39 #define TR_CORE(o) G_TYPE_CHECK_INSTANCE_CAST((o),TR_CORE_TYPE,TrCore) 40 #define TR_IS_CORE(o) G_TYPE_CHECK_INSTANCE_TYPE((o),TR_CORE_TYPE) 41 #define TR_CORE_CLASS(k) G_TYPE_CHECK_CLASS_CAST((k),TR_CORE_TYPE,TrCoreClass) 42 #define TR_IS_CORE_CLASS(k) G_TYPE_CHECK_CLASS_TYPE((k),TR_CORE_TYPE) 43 #define TR_CORE_GET_CLASS(o) G_TYPE_INSTANCE_GET_CLASS((o),TR_CORE_TYPE,TrCoreClass) 55 44 56 45 struct core_stats … … 62 51 }; 63 52 64 /* treat the contents of this structure as private */65 53 typedef struct TrCore 66 54 { … … 79 67 80 68 /* "directory-prompt" signal: 81 void handler( TrCore *, GList *, enum tr_torrent_action, gboolean, gpointer) */69 void handler( TrCore *, GList *, gpointer ctor, gpointer userData ) */ 82 70 int promptsig; 83 84 /* "directory-prompt-data" signal:85 void handler( TrCore *, uint8_t *, size_t, gboolean, gpointer ) */86 int promptdatasig;87 71 88 72 /* "quit" signal: … … 121 105 tr_core_get_stats( const TrCore * self ); 122 106 123 /* Load saved state, return number of torrents added. May trigger one 124 or more "error" signals with TR_CORE_ERR_ADD_TORRENT */ 125 int 126 tr_core_load( TrCore * self, gboolean forcepaused ); 107 /****** 108 ******* 109 ******/ 127 110 128 /* Any the tr_core_add functions below may trigger an "error" signal 129 with TR_CORE_ERR_ADD_TORRENT */ 111 /** 112 * Load saved state and return number of torrents added. 113 * May trigger one or more "error" signals with TR_CORE_ERR_ADD_TORRENT 114 */ 115 int tr_core_load( TrCore * self, gboolean forcepaused ); 130 116 131 /* Add the torrent at the given path */ 132 gboolean 133 tr_core_add( TrCore * self, const char * path, enum tr_torrent_action act, 134 gboolean paused ); 117 /** 118 * Add a torrent. 119 * May trigger an "error" signal with TR_CORE_ERR_ADD_TORRENT 120 * Caller must free the ctor. 121 */ 122 void tr_core_add_ctor( TrCore * self, tr_ctor * ctor ); 135 123 136 /* Add the torrent at the given path with the given download directory */ 137 gboolean 138 tr_core_add_dir( TrCore * self, const char * path, const char * dir, 139 enum tr_torrent_action act, gboolean paused ); 124 /** 125 * Add a list of torrents. 126 * May trigger one or more "error" signals with TR_CORE_ERR_ADD_TORRENT 127 */ 128 void tr_core_add_list( TrCore * self, 129 GList * torrentFiles, 130 tr_ctor * ctor ); 140 131 141 /* Add a list of torrents with the given paths */142 int 143 tr_core_add_list( TrCore * self, GList * paths, enum tr_torrent_action act, 144 gboolean paused);132 /** 133 * Add a torrent. 134 */ 135 void tr_core_add_torrent( TrCore*, TrTorrent* ); 145 136 146 /* Add the torrent data in the given buffer */ 147 gboolean 148 tr_core_add_data( TrCore * self, uint8_t * data, size_t size, gboolean paused ); 137 /** 138 * Notifies listeners that torrents have been added. 139 * This should be called after one or more tr_core_add*() calls. 140 */ 141 void tr_core_torrents_added( TrCore * self ); 149 142 150 /* Add the torrent data in the given buffer with the given download directory */ 151 gboolean 152 tr_core_add_data_dir( TrCore * self, uint8_t * data, size_t size, 153 const char * dir, gboolean paused ); 154 155 /* Save state, update model, and signal the end of a torrent cluster */ 156 void 157 tr_core_torrents_added( TrCore * self ); 143 /****** 144 ******* 145 ******/ 158 146 159 147 /* remove a torrent, waiting for it to pause if necessary */ -
trunk/gtk/tr_prefs.c
r5007 r5015 43 43 pref_int_set_default ( PREF_KEY_UL_LIMIT, 50 ); 44 44 45 pref_flag_set_default ( PREF_KEY_ DIR_ASK, FALSE );45 pref_flag_set_default ( PREF_KEY_OPTIONS_PROMPT, TRUE ); 46 46 pref_string_set_default ( PREF_KEY_DIR_DEFAULT, g_get_home_dir() ); 47 47 … … 54 54 pref_flag_set_default ( PREF_KEY_ENCRYPTED_ONLY, FALSE ); 55 55 56 pref_string_set_default ( PREF_KEY_ADDSTD, toractionname(TR_TOR_COPY) );57 pref_string_set_default ( PREF_KEY_ADDIPC, toractionname(TR_TOR_COPY) );58 59 56 pref_int_set_default ( PREF_KEY_MSGLEVEL, TR_MSG_INF ); 60 57 … … 63 60 pref_flag_set_default ( PREF_KEY_MINIMAL_VIEW, FALSE ); 64 61 62 pref_flag_set_default ( PREF_KEY_START, TRUE ); 63 pref_flag_set_default ( PREF_KEY_DELETE_ORIGINAL, FALSE ); 64 65 65 pref_save( NULL ); 66 }67 68 /**69 ***70 **/71 72 int73 tr_prefs_get_action( const char * key )74 {75 char * val = pref_string_get( key );76 const int ret = toraddaction( val );77 g_free( val );78 return ret;79 }80 81 void82 tr_prefs_set_action( const char * key, int action )83 {84 pref_string_set( key, toractionname(action) );85 66 } 86 67 … … 156 137 157 138 static void 158 action_cb( GtkComboBox * w, gpointer core )159 {160 const char * key = g_object_get_data( G_OBJECT(w), PREFS_KEY );161 GtkTreeIter iter;162 if( gtk_combo_box_get_active_iter( GTK_COMBO_BOX(w), &iter ) )163 {164 int action;165 GtkTreeModel * model = gtk_combo_box_get_model( GTK_COMBO_BOX(w) );166 gtk_tree_model_get( model, &iter, 1, &action, -1 );167 tr_core_set_pref( core, key, toractionname(action) );168 }169 }170 171 static GtkWidget*172 new_action_combo( const char * key, gpointer core )173 {174 const char * s;175 GtkTreeIter iter;176 GtkCellRenderer * rend;177 GtkListStore * model;178 GtkWidget * w;179 180 model = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_INT );181 182 s = _("Use the torrent file where it is");183 gtk_list_store_append( model, &iter );184 gtk_list_store_set( model, &iter, 1, TR_TOR_LEAVE, 0, s, -1 );185 186 s = _("Keep a copy of the torrent file");187 gtk_list_store_append( model, &iter );188 gtk_list_store_set( model, &iter, 1, TR_TOR_COPY, 0, s, -1 );189 190 s = _("Keep a copy and remove the original");191 gtk_list_store_append( model, &iter );192 gtk_list_store_set( model, &iter, 1, TR_TOR_MOVE, 0, s, -1 );193 194 w = gtk_combo_box_new_with_model( GTK_TREE_MODEL(model) );195 gtk_combo_box_set_active( GTK_COMBO_BOX(w), tr_prefs_get_action(key) );196 g_object_set_data_full( G_OBJECT(w), PREFS_KEY, g_strdup(key), g_free );197 rend = gtk_cell_renderer_text_new( );198 gtk_cell_layout_pack_start( GTK_CELL_LAYOUT(w), rend, TRUE );199 gtk_cell_layout_add_attribute( GTK_CELL_LAYOUT(w), rend, "text", 0 );200 g_signal_connect( w, "changed", G_CALLBACK(action_cb), core );201 202 return w;203 }204 205 static void206 139 target_cb( GtkWidget * widget, gpointer target ) 207 140 { 208 141 gtk_widget_set_sensitive( GTK_WIDGET(target), gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget) ) ); 209 }210 211 static void212 target_invert_cb( GtkWidget * widget, gpointer target )213 {214 gtk_widget_set_sensitive( GTK_WIDGET(target), !gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget) ) );215 142 } 216 143 … … 268 195 } 269 196 270 GtkWidget * 271 tr_prefs_dialog_new( GObject * core, GtkWindow * parent ) 197 static GtkWidget* 198 generalPage( GObject * core ) 199 { 200 int row = 0; 201 const char * s; 202 GtkWidget * t; 203 GtkWidget * w; 204 205 t = hig_workarea_create (); 206 207 hig_workarea_add_section_title (t, &row, _("Windows")); 208 209 s = _("Show an icon in the system _tray"); 210 w = new_check_button( s, PREF_KEY_SYSTRAY, core ); 211 hig_workarea_add_wide_control( t, &row, w ); 212 213 s = _("Confirm _quit"); 214 w = new_check_button( s, PREF_KEY_ASKQUIT, core ); 215 hig_workarea_add_wide_control( t, &row, w ); 216 217 hig_workarea_finish (t, &row); 218 return t; 219 } 220 221 static GtkWidget* 222 torrentPage( GObject * core ) 223 { 224 int row = 0; 225 const char * s; 226 GtkWidget * t; 227 GtkWidget * w; 228 229 t = hig_workarea_create (); 230 231 hig_workarea_add_section_title( t, &row, _( "Location" ) ); 232 233 w = new_path_chooser_button( PREF_KEY_DIR_DEFAULT, core ); 234 hig_workarea_add_row( t, &row, _( "Default download location:" ), w, NULL ); 235 236 hig_workarea_add_section_divider( t, &row ); 237 hig_workarea_add_section_title( t, &row, _( "Adding Torrents" ) ); 238 239 s = _( "Show _options window" ); 240 w = new_check_button( s, PREF_KEY_OPTIONS_PROMPT, core ); 241 hig_workarea_add_wide_control( t, &row, w ); 242 243 s = _( "_Start transfers when added" ); 244 w = new_check_button( s, PREF_KEY_START, core ); 245 hig_workarea_add_wide_control( t, &row, w ); 246 247 s = _( "_Delete original torrent file" ); 248 w = new_check_button( s, PREF_KEY_DELETE_ORIGINAL, core ); 249 hig_workarea_add_wide_control( t, &row, w ); 250 251 hig_workarea_finish (t, &row); 252 return t; 253 } 254 255 static GtkWidget* 256 peerPage( GObject * core ) 257 { 258 int row = 0; 259 const char * s; 260 GtkWidget * t; 261 GtkWidget * w; 262 263 t = hig_workarea_create (); 264 hig_workarea_add_section_title (t, &row, _("Options")); 265 266 s = _("Use peer _exchange if possible"); 267 w = new_check_button( s, PREF_KEY_PEX, core ); 268 hig_workarea_add_wide_control( t, &row, w ); 269 270 s = _("_Ignore unencrypted peers"); 271 w = new_check_button( s, PREF_KEY_ENCRYPTED_ONLY, core ); 272 hig_workarea_add_wide_control( t, &row, w ); 273 274 hig_workarea_add_section_divider( t, &row ); 275 hig_workarea_add_section_title( t, &row, _( "Limits" ) ); 276 277 w = new_spin_button( PREF_KEY_MAX_PEERS_GLOBAL, core, 1, 3000, 5 ); 278 hig_workarea_add_row( t, &row, _( "Total max peers:" ), w, NULL ); 279 w = new_spin_button( PREF_KEY_MAX_PEERS_PER_TORRENT, core, 1, 300, 5 ); 280 hig_workarea_add_row( t, &row, _( "Per-torrent max peers:" ), w, NULL ); 281 282 hig_workarea_finish (t, &row); 283 return t; 284 } 285 286 static GtkWidget* 287 bandwidthPage( GObject * core ) 288 { 289 int row = 0; 290 const char * s; 291 GtkWidget * t; 292 GtkWidget * w, * w2; 293 294 t = hig_workarea_create (); 295 296 hig_workarea_add_section_title (t, &row, _("Speed Limits")); 297 298 s = _("_Limit upload speed (KiB/s)"); 299 w = new_check_button( s, PREF_KEY_UL_LIMIT_ENABLED, core ); 300 w2 = new_spin_button( PREF_KEY_UL_LIMIT, core, 0, INT_MAX, 5 ); 301 gtk_widget_set_sensitive( GTK_WIDGET(w2), pref_flag_get( PREF_KEY_UL_LIMIT_ENABLED ) ); 302 g_signal_connect( w, "toggled", G_CALLBACK(target_cb), w2 ); 303 hig_workarea_add_row_w( t, &row, w, w2, NULL ); 304 305 s = _("Li_mit download speed (KiB/s)"); 306 w = new_check_button( s, PREF_KEY_DL_LIMIT_ENABLED, core ); 307 w2 = new_spin_button( PREF_KEY_DL_LIMIT, core, 0, INT_MAX, 5 ); 308 gtk_widget_set_sensitive( GTK_WIDGET(w2), pref_flag_get( PREF_KEY_DL_LIMIT_ENABLED ) ); 309 g_signal_connect( w, "toggled", G_CALLBACK(target_cb), w2 ); 310 hig_workarea_add_row_w( t, &row, w, w2, NULL ); 311 312 hig_workarea_finish (t, &row); 313 return t; 314 } 315 316 static GtkWidget* 317 networkPage( GObject * core, gpointer alive ) 272 318 { 273 319 int row = 0; … … 277 323 GtkWidget * l; 278 324 GtkWidget * h; 325 GtkTooltips * tips; 326 327 tips = gtk_tooltips_new( ); 328 329 t = hig_workarea_create (); 330 hig_workarea_add_section_title (t, &row, _("Network")); 331 332 s = _("_Automatically map port" ); 333 w = new_check_button( s, PREF_KEY_NAT, core ); 334 hig_workarea_add_wide_control( t, &row, w ); 335 gtk_tooltips_set_tip( GTK_TOOLTIPS( tips ), w, _( "NAT traversal uses either NAT-PMP or UPnP" ), NULL ); 336 337 h = gtk_hbox_new( FALSE, GUI_PAD ); 338 w2 = new_spin_button( PREF_KEY_PORT, core, 1, INT_MAX, 1 ); 339 gtk_box_pack_start( GTK_BOX(h), w2, FALSE, FALSE, 0 ); 340 l = gtk_label_new( NULL ); 341 gtk_misc_set_alignment( GTK_MISC(l), 0.0f, 0.5f ); 342 gtk_box_pack_start( GTK_BOX(h), l, FALSE, FALSE, 0 ); 343 hig_workarea_add_row( t, &row, _("Incoming TCP _Port"), h, w ); 344 345 g_object_set_data( G_OBJECT(l), "tr-port-spin", w2 ); 346 g_object_set_data( G_OBJECT(l), "alive", alive ); 347 testing_port_cb( NULL, l ); 348 349 g_signal_connect( w, "toggled", G_CALLBACK(toggled_cb), l ); 350 g_signal_connect( w2, "value-changed", G_CALLBACK(testing_port_cb), l ); 351 352 hig_workarea_finish (t, &row); 353 return t; 354 } 355 356 GtkWidget * 357 tr_prefs_dialog_new( GObject * core, GtkWindow * parent ) 358 { 279 359 GtkWidget * d; 280 GtkTooltips * tips; 360 GtkWidget * n; 361 GtkWidget * w; 281 362 gboolean * alive; 282 363 283 364 alive = g_new( gboolean, 1 ); 284 365 *alive = TRUE; 285 286 tips = gtk_tooltips_new( );287 366 288 367 d = gtk_dialog_new_with_buttons( _("Preferences"), parent, … … 295 374 g_object_weak_ref( G_OBJECT( d ), dialogDestroyed, alive ); 296 375 376 n = gtk_notebook_new( ); 377 378 w = torrentPage( core ); 379 gtk_notebook_append_page( GTK_NOTEBOOK( n ), w, gtk_label_new (_("Torrents")) ); 380 w = peerPage( core ); 381 gtk_notebook_append_page( GTK_NOTEBOOK( n ), w, gtk_label_new (_("Peers")) ); 382 w = bandwidthPage( core ); 383 gtk_notebook_append_page( GTK_NOTEBOOK( n ), w, gtk_label_new (_("Bandwidth")) ); 384 w = networkPage( core, alive ); 385 gtk_notebook_append_page( GTK_NOTEBOOK( n ), w, gtk_label_new (_("Network")) ); 386 w = generalPage( core ); 387 gtk_notebook_append_page( GTK_NOTEBOOK( n ), w, gtk_label_new (_("General")) ); 388 389 297 390 g_signal_connect( d, "response", G_CALLBACK(response_cb), core ); 298 299 t = hig_workarea_create (); 300 301 hig_workarea_add_section_title (t, &row, _("Speed Limits")); 302 303 s = _("_Limit upload speed (KiB/s)"); 304 w = new_check_button( s, PREF_KEY_UL_LIMIT_ENABLED, core ); 305 w2 = new_spin_button( PREF_KEY_UL_LIMIT, core, 0, INT_MAX, 5 ); 306 gtk_widget_set_sensitive( GTK_WIDGET(w2), pref_flag_get( PREF_KEY_UL_LIMIT_ENABLED ) ); 307 g_signal_connect( w, "toggled", G_CALLBACK(target_cb), w2 ); 308 hig_workarea_add_row_w( t, &row, w, w2, NULL ); 309 310 s = _("Li_mit download speed (KiB/s)"); 311 w = new_check_button( s, PREF_KEY_DL_LIMIT_ENABLED, core ); 312 w2 = new_spin_button( PREF_KEY_DL_LIMIT, core, 0, INT_MAX, 5 ); 313 gtk_widget_set_sensitive( GTK_WIDGET(w2), pref_flag_get( PREF_KEY_DL_LIMIT_ENABLED ) ); 314 g_signal_connect( w, "toggled", G_CALLBACK(target_cb), w2 ); 315 hig_workarea_add_row_w( t, &row, w, w2, NULL ); 316 317 hig_workarea_add_section_divider( t, &row ); 318 hig_workarea_add_section_title (t, &row, _("Downloads")); 319 320 s = _("P_rompt for download directory"); 321 w = new_check_button( s, PREF_KEY_DIR_ASK, core ); 322 w2 = new_path_chooser_button( PREF_KEY_DIR_DEFAULT, core ); 323 gtk_widget_set_sensitive( GTK_WIDGET(w2), !pref_flag_get( PREF_KEY_DIR_ASK ) ); 324 g_signal_connect( w, "toggled", G_CALLBACK(target_invert_cb), w2 ); 325 hig_workarea_add_row_w( t, &row, w, w2, NULL ); 326 327 w = new_action_combo( PREF_KEY_ADDSTD, core ); 328 s = _("For torrents added _normally:"); 329 l = hig_workarea_add_row( t, &row, s, w, NULL ); 330 331 w = new_action_combo( PREF_KEY_ADDIPC, core ); 332 s = _("For torrents added from _command-line:"); 333 l = hig_workarea_add_row( t, &row, s, w, NULL ); 334 335 hig_workarea_add_section_divider( t, &row ); 336 hig_workarea_add_section_title( t, &row, _( "Peer Connections" ) ); 337 338 w = new_spin_button( PREF_KEY_MAX_PEERS_GLOBAL, core, 1, 3000, 5 ); 339 hig_workarea_add_row( t, &row, _( "Global maximum connected peers:" ), w, NULL ); 340 w = new_spin_button( PREF_KEY_MAX_PEERS_PER_TORRENT, core, 1, 300, 5 ); 341 hig_workarea_add_row( t, &row, _( "Maximum connected peers for new torrents:" ), w, NULL ); 342 343 hig_workarea_add_section_divider( t, &row ); 344 hig_workarea_add_section_title (t, &row, _("Network")); 345 346 s = _("_Automatically map port" ); 347 w = new_check_button( s, PREF_KEY_NAT, core ); 348 hig_workarea_add_wide_control( t, &row, w ); 349 gtk_tooltips_set_tip( GTK_TOOLTIPS( tips ), w, _( "NAT traversal uses either NAT-PMP or UPnP" ), NULL ); 350 351 h = gtk_hbox_new( FALSE, GUI_PAD ); 352 w2 = new_spin_button( PREF_KEY_PORT, core, 1, INT_MAX, 1 ); 353 gtk_box_pack_start( GTK_BOX(h), w2, FALSE, FALSE, 0 ); 354 l = gtk_label_new( NULL ); 355 gtk_misc_set_alignment( GTK_MISC(l), 0.0f, 0.5f ); 356 gtk_box_pack_start( GTK_BOX(h), l, FALSE, FALSE, 0 ); 357 hig_workarea_add_row( t, &row, _("Incoming TCP _Port"), h, w ); 358 359 g_object_set_data( G_OBJECT(l), "tr-port-spin", w2 ); 360 g_object_set_data( G_OBJECT(l), "alive", alive ); 361 testing_port_cb( NULL, l ); 362 363 g_signal_connect( w, "toggled", G_CALLBACK(toggled_cb), l ); 364 g_signal_connect( w2, "value-changed", G_CALLBACK(testing_port_cb), l ); 365 366 hig_workarea_add_section_divider( t, &row ); 367 hig_workarea_add_section_title (t, &row, _("Options")); 368 369 s = _("Use peer _exchange if possible"); 370 w = new_check_button( s, PREF_KEY_PEX, core ); 371 hig_workarea_add_wide_control( t, &row, w ); 372 373 s = _("_Ignore unencrypted peers"); 374 w = new_check_button( s, PREF_KEY_ENCRYPTED_ONLY, core ); 375 hig_workarea_add_wide_control( t, &row, w ); 376 377 s = _("Show an icon in the system _tray"); 378 w = new_check_button( s, PREF_KEY_SYSTRAY, core ); 379 hig_workarea_add_wide_control( t, &row, w ); 380 381 s = _("Confirm _quit"); 382 w = new_check_button( s, PREF_KEY_ASKQUIT, core ); 383 hig_workarea_add_wide_control( t, &row, w ); 384 385 hig_workarea_finish (t, &row); 386 gtk_box_pack_start_defaults( GTK_BOX(GTK_DIALOG(d)->vbox), t ); 391 gtk_box_pack_start_defaults( GTK_BOX(GTK_DIALOG(d)->vbox), n ); 387 392 gtk_widget_show_all( GTK_DIALOG(d)->vbox ); 388 393 return d; -
trunk/gtk/tr_prefs.h
r4404 r5015 25 25 #define PREF_KEY_UL_LIMIT_ENABLED "upload-limit-enabled" 26 26 #define PREF_KEY_UL_LIMIT "upload-limit" 27 #define PREF_KEY_ DIR_ASK "prompt-for-download-directory"27 #define PREF_KEY_OPTIONS_PROMPT "show-options-window" 28 28 #define PREF_KEY_DIR_DEFAULT "default-download-directory" 29 #define PREF_KEY_ ADDSTD "add-behavior-standard"30 #define PREF_KEY_ ADDIPC "add-behavior-ipc"29 #define PREF_KEY_START "start-added-torrents" 30 #define PREF_KEY_DELETE_ORIGINAL "delete-original-torrent-files" 31 31 #define PREF_KEY_PORT "listening-port" 32 32 #define PREF_KEY_NAT "nat-traversal-enabled" … … 49 49 void tr_prefs_init_global( void ); 50 50 51 int tr_prefs_get_action( const char * key );52 void tr_prefs_set_action( const char * key, int action );53 54 51 #endif -
trunk/gtk/tr_torrent.c
r5005 r5015 39 39 { 40 40 tr_torrent * handle; 41 char * delfile;42 41 gboolean seeding_cap_enabled; 43 42 gdouble seeding_cap; /* ratio to stop seeding at */ … … 55 54 struct TrTorrentPrivate ); 56 55 p->handle = NULL; 57 p->delfile = NULL;58 56 p->seeding_cap = 2.0; 59 57 … … 72 70 tr_torrent_dispose( GObject * o ) 73 71 { 74 GObjectClass * parent = g_type_class_peek(g_type_parent(TR_TORRENT_TYPE));72 GObjectClass * parent; 75 73 TrTorrent * self = TR_TORRENT( o ); 76 74 … … 79 77 if( self->priv->handle ) 80 78 tr_torrentClose( self->priv->handle ); 81 g_free( self->priv->delfile );82 79 self->priv = NULL; 83 80 } 84 81 85 /* chain up to the parent class */82 parent = g_type_class_peek(g_type_parent(TR_TORRENT_TYPE)); 86 83 parent->dispose( o ); 87 84 } 88 85 89 86 static void 90 tr_torrent_class_init( gpointer g_class, gpointer g_class_data UNUSED )87 tr_torrent_class_init( gpointer g_class, gpointer g_class_data UNUSED ) 91 88 { 92 89 GObjectClass *gobject_class = G_OBJECT_CLASS(g_class); 93 90 gobject_class->dispose = tr_torrent_dispose; 94 g_type_class_add_private( g_class, sizeof( struct TrTorrentPrivate) );91 g_type_class_add_private( g_class, sizeof( struct TrTorrentPrivate ) ); 95 92 } 96 93 97 94 GType 98 tr_torrent_get_type( void)95 tr_torrent_get_type( void ) 99 96 { 100 97 static GType type = 0; 101 98 102 if(0 == type) { 99 if( !type ) 100 { 103 101 static const GTypeInfo info = { 104 102 sizeof (TrTorrentClass), … … 171 169 172 170 TrTorrent * 173 tr_torrent_new( tr_handle * handle, 174 const char * metainfo_filename, 175 const char * destination, 176 enum tr_torrent_action act, 177 gboolean paused, 178 char ** err ) 179 { 180 TrTorrent * ret; 181 tr_torrent * tor; 182 tr_ctor * ctor; 183 int errcode = -1; 184 185 g_assert( destination ); 186 187 *err = NULL; 188 189 ctor = tr_ctorNew( handle ); 190 tr_ctorSetMetainfoFromFile( ctor, metainfo_filename ); 191 tr_ctorSetDestination( ctor, TR_FORCE, destination ); 192 tr_ctorSetPaused( ctor, TR_FORCE, paused ); 193 tr_ctorSetMaxConnectedPeers( ctor, TR_FORCE, pref_int_get( PREF_KEY_MAX_PEERS_PER_TORRENT ) ); 194 tor = tr_torrentNew( handle, ctor, &errcode ); 195 tr_ctorFree( ctor ); 171 tr_torrent_new_ctor( tr_handle * handle, 172 tr_ctor * ctor, 173 char ** err ) 174 { 175 tr_torrent * tor; 176 int errcode; 177 178 errcode = -1; 179 *err = NULL; 180 181 tor = tr_torrentNew( handle, ctor, &errcode ); 196 182 197 if( tor == NULL ) { 198 switch( errcode ) { 199 case TR_EINVALID: 200 *err = g_strdup_printf(_("%s: not a valid torrent file"), metainfo_filename ); 201 break; 202 case TR_EDUPLICATE: 203 *err = g_strdup_printf(_("%s: torrent is already open"), metainfo_filename ); 204 break; 205 default: 206 *err = g_strdup( metainfo_filename ); 207 break; 183 if( !tor ) 184 { 185 const char * filename = tr_ctorGetSourceFile( ctor ); 186 if( !filename ) 187 filename = "(null)"; 188 189 switch( errcode ) 190 { 191 case TR_EINVALID: 192 *err = g_strdup_printf( _("%s: not a valid torrent file"), filename ); 193 break; 194 case TR_EDUPLICATE: 195 *err = g_strdup_printf( _("%s: torrent is already open"), filename ); 196 break; 197 default: 198 *err = g_strdup( filename ); 199 break; 200 } 201 202 return NULL; 208 203 } 209 return NULL; 210 } 211 212 ret = maketorrent( tor ); 213 if( TR_TOR_MOVE == act ) 214 ret->priv->delfile = g_strdup( metainfo_filename ); 215 return ret; 216 } 217 218 TrTorrent * 219 tr_torrent_new_with_data( tr_handle * handle, 220 uint8_t * metainfo, 221 size_t size, 222 const char * destination, 223 gboolean paused, 224 char ** err ) 225 { 226 tr_torrent * tor; 227 tr_ctor * ctor; 228 int errcode = -1; 229 230 g_assert( destination ); 231 232 *err = NULL; 233 234 ctor = tr_ctorNew( handle ); 235 tr_ctorSetMetainfo( ctor, metainfo, size ); 236 tr_ctorSetDestination( ctor, TR_FORCE, destination ); 237 tr_ctorSetPaused( ctor, TR_FORCE, paused ); 238 tr_ctorSetMaxConnectedPeers( ctor, TR_FORCE, pref_int_get( PREF_KEY_MAX_PEERS_PER_TORRENT ) ); 239 tor = tr_torrentNew( handle, ctor, &errcode ); 240 241 if( tor == NULL ) { 242 switch( errcode ) { 243 case TR_EINVALID: 244 *err = g_strdup( _("not a valid torrent file") ); 245 break; 246 case TR_EDUPLICATE: 247 *err = g_strdup( _("torrent is already open") ); 248 break; 249 default: 250 *err = g_strdup( "" ); 251 break; 252 } 253 return NULL; 254 } 255 256 return maketorrent( tor ); 204 205 return maketorrent( tor ); 257 206 } 258 207 -
trunk/gtk/tr_torrent.h
r5005 r5015 88 88 89 89 TrTorrent * 90 tr_torrent_new( tr_handle * handle, const char * path, const char * dir, 91 enum tr_torrent_action act, gboolean paused, char ** err); 92 93 TrTorrent * 94 tr_torrent_new_with_data( tr_handle * handle, uint8_t * data, size_t size, 95 const char * dir, gboolean paused, char ** err ); 90 tr_torrent_new_ctor( tr_handle * handle, tr_ctor * ctor, char ** err ); 96 91 97 92 #endif -
trunk/gtk/util.c
r4759 r5015 223 223 } 224 224 225 enum tr_torrent_action226 toraddaction( const char * action )227 {228 if( !action || !strcmp( "copy", action ) )229 return TR_TOR_COPY;230 231 if( !strcmp( "move", action ) )232 return TR_TOR_MOVE;233 234 return TR_TOR_LEAVE;235 }236 237 const char *238 toractionname( enum tr_torrent_action action )239 {240 switch( action )241 {242 case TR_TOR_COPY:243 return "copy";244 245 case TR_TOR_MOVE:246 return "move";247 248 default:249 return "leave";250 }251 }252 253 225 char * 254 226 getdownloaddir( void ) -
trunk/gtk/util.h
r4759 r5015 34 34 /* NULL-safe version of strcmp */ 35 35 int tr_strcmp( const char*, const char * ); 36 37 /* XXX this shouldn't be here */38 enum tr_torrent_action { TR_TOR_LEAVE, TR_TOR_COPY, TR_TOR_MOVE };39 36 40 37 /* return number of items in array */ … … 82 79 GList * 83 80 checkfilenames( int argc, char ** argv ); 84 85 /* returns the flag for an action string */86 enum tr_torrent_action87 toraddaction( const char * action );88 89 /* returns the action string for a flag */90 const char *91 toractionname( enum tr_torrent_action action );92 81 93 82 /* retrieve the global download directory */ -
trunk/po/POTFILES.in
r4344 r5015 4 4 gtk/conf.c 5 5 gtk/dialogs.c 6 gtk/file-list.c 6 7 gtk/hig.c 7 8 gtk/io.c … … 10 11 gtk/makemeta-ui.c 11 12 gtk/msgwin.c 13 gtk/open.c 12 14 gtk/stats.c 13 15 gtk/torrent-cell-renderer.c
Note: See TracChangeset
for help on using the changeset viewer.