Changeset 7
- Timestamp:
- Jan 12, 2006, 6:40:47 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 5 added
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/AUTHORS
r6 r7 9 9 10 10 Josh Elsasser <josh@elsasser.org> 11 + GTK interface11 + GTK+ interface 12 12 13 13 Michael Demars <keul@m0k.org> -
trunk/Jamfile
r6 r7 7 7 if $(OS) = MACOSX 8 8 { 9 OSXLinks macosx/Frameworks/Growl.framework/Growl ;10 9 OSXInfoPlist macosx/Info.plist : macosx/Info.plist.in ; 11 10 OSXBundle Transmission.app : libtransmission.a … … 17 16 macosx/English.lproj/MainMenu.nib/info.nib 18 17 macosx/English.lproj/MainMenu.nib/keyedobjects.nib 19 macosx/Frameworks/Growl.framework/Growl20 18 macosx/Images/Info.png 21 19 macosx/Images/Open.png … … 38 36 macosx/TorrentTableView.h 39 37 macosx/TorrentTableView.m 38 macosx/Transmission.sdef 40 39 macosx/Transmission.xcodeproj/project.pbxproj 41 40 macosx/Transmission_Prefix.pch -
trunk/Jamrules
r6 r7 9 9 VERSION_MINOR = 4 ; 10 10 # VERSION_STRING = $(VERSION_MAJOR).$(VERSION_MINOR) ; 11 VERSION_STRING = 0.5-cvs;11 VERSION_STRING = CVS-20051124 ; 12 12 13 13 DEFINES += VERSION_MAJOR=$(VERSION_MAJOR) … … 39 39 { 40 40 libtool -static $(>) -o $(<) ; 41 }42 43 rule OSXLinks44 {45 }46 actions OSXLinks47 {48 ( cd macosx/Frameworks/Growl.framework/ && \49 ln -s Versions/Current/Growl && \50 ln -s Versions/Current/Headers && \51 ln -s Versions/Current/Resources && \52 ln -s A Versions/Current )53 41 } 54 42 -
trunk/gtk/Jamfile
r6 r7 1 1 SubDir TOP gtk ; 2 2 3 GTK_SRC = conf.c main.c util.c ;3 GTK_SRC = conf.c main.c prefs.c util.c ; 4 4 5 5 Main transmission-gtk : $(GTK_SRC) ; -
trunk/gtk/conf.c
r5 r7 40 40 #include "conf.h" 41 41 #include "transmission.h" 42 #include "util.h" 42 43 43 44 #define FILE_LOCK "gtk_lock" … … 160 161 goto done; 161 162 } 162 /*g_io_channel_set_encoding(io, NULL, NULL);*/163 163 g_io_channel_set_line_term(io, &term, 1); 164 164 … … 210 210 g_tree_insert(prefs, g_strdup(name), g_strdup(value)); 211 211 212 return writeprefs(errstr); 212 if(NULL != errstr) 213 return writeprefs(errstr); 214 else 215 return TRUE; 213 216 } 214 217 … … 237 240 } 238 241 242 #ifdef NDEBUG 243 ftruncate(fd, 0); 244 #else 245 assert(0 == ftruncate(fd, 0)); 246 #endif 247 239 248 info.err = NULL; 240 249 io = g_io_channel_unix_new(fd); 241 /*g_io_channel_set_encoding(io, NULL, NULL);*/242 250 g_io_channel_set_close_on_unref(io, TRUE); 243 251 … … 319 327 goto done; 320 328 } 321 /*g_io_channel_set_encoding(io, NULL, NULL);*/322 329 g_io_channel_set_line_term(io, &term, 1); 323 330 … … 368 375 char *start, *end; 369 376 377 /* skip any leading whitespace */ 370 378 while(isspace(*line)) 371 379 line++; 372 380 373 if(NULL == (start = strchr(line, '='))) 381 /* walk over the key, which may be alphanumerics as well as - or _ */ 382 for(start = line; isalnum(*start) || '_' == *start || '-' == *start; start++) 383 ; 384 385 /* they key must be immediately followed by an = */ 386 if('=' != *start) 374 387 return NULL; 375 376 while(isspace(*(++start))) 377 ; 378 379 if('"' != *start) 388 *(start++) = '\0'; 389 390 /* then the opening quote for the value */ 391 if('"' != *(start++)) 380 392 return NULL; 381 393 382 for(end = ++start; '\0' != *end && '"' != *end; end++) 394 /* walk over the value */ 395 for(end = start; '\0' != *end && '"' != *end; end++) 396 /* skip over escaped quotes */ 383 397 if('\\' == *end && '\0' != *(end + 1)) 384 398 end++; 385 399 400 /* make sure we didn't hit the end of the string */ 386 401 if('"' != *end) 387 402 return NULL; 388 389 if(0 == memcmp(line, "torrent", sizeof("torrent") - 1)) { 390 state->ts_torrent = g_new(char, end - start + 1); 391 memcpy(state->ts_torrent, start, end - start); 392 state->ts_torrent[end - start] = '\0'; 393 } 394 else if(0 == memcmp(line, "dir", sizeof("dir") - 1)) { 395 state->ts_directory = g_new(char, end - start + 1); 396 memcpy(state->ts_directory, start, end - start); 397 state->ts_directory[end - start] = '\0'; 398 } 399 else if(0 == memcmp(line, "paused", sizeof("paused") - 1)) { 400 state->ts_paused = (0 == memcmp("yes", start, end - start)); 401 } 402 403 *end = '\0'; 404 405 /* if it's a key we recognize then save the data */ 406 if(0 == strcmp(line, "torrent")) 407 state->ts_torrent = g_strcompress(start); 408 else if(0 == strcmp(line, "dir")) 409 state->ts_directory = g_strcompress(start); 410 else if(0 == strcmp(line, "paused")) 411 state->ts_paused = strbool(start); 412 413 /* return a pointer to just past the end of the value */ 403 414 return end + 1; 404 415 } 405 416 406 /* XXX need to save download directory, also maybe running/stopped state */407 417 gboolean 408 418 cf_savestate(int count, tr_stat_t *torrents, char **errstr) { … … 426 436 } 427 437 438 #ifdef NDEBUG 439 ftruncate(fd, 0); 440 #else 441 assert(0 == ftruncate(fd, 0)); 442 #endif 443 428 444 io = g_io_channel_unix_new(fd); 445 g_io_channel_set_close_on_unref(io, TRUE); 446 429 447 /* XXX what the hell should I be doing about unicode? */ 430 /*g_io_channel_set_encoding(io, NULL, NULL);*/431 g_io_channel_set_close_on_unref(io, TRUE);432 448 433 449 err = NULL; -
trunk/gtk/conf.h
r5 r7 44 44 const char * 45 45 cf_getpref(const char *name); 46 /* if errstr is NULL then prefs will not be saved */ 46 47 gboolean 47 48 cf_setpref(const char *name, const char *value, char **errstr); -
trunk/gtk/main.c
r5 r7 25 25 */ 26 26 27 #include <sys/param.h> 27 28 #include <assert.h> 29 #include <errno.h> 28 30 #include <string.h> 29 31 #include <stdio.h> 30 32 #include <stdlib.h> 31 #include <sys/param.h>32 33 #include <time.h> 33 34 #include <unistd.h> … … 36 37 37 38 #include "conf.h" 39 #include "prefs.h" 38 40 #include "transmission.h" 39 41 #include "util.h" … … 43 45 struct cbdata { 44 46 tr_handle_t *tr; 45 GtkWi dget*wind;47 GtkWindow *wind; 46 48 GtkListStore *model; 47 49 GtkTreeView *view; … … 60 62 61 63 void 62 readargs(int argc, char **argv, int *port, int *limit);63 void64 64 maketypes(void); 65 65 gpointer … … 93 93 makeaddwind(struct cbdata *data); 94 94 gboolean 95 addtorrent(tr_handle_t *tr, GtkWi dget*parentwind, const char *torrent,95 addtorrent(tr_handle_t *tr, GtkWindow *parentwind, const char *torrent, 96 96 const char *dir, gboolean paused); 97 97 void … … 102 102 makeinfowind(struct cbdata *data, int index); 103 103 gboolean 104 savetorrents(tr_handle_t *tr, GtkWi dget*wind, int count, tr_stat_t *stat);104 savetorrents(tr_handle_t *tr, GtkWindow *wind, int count, tr_stat_t *stat); 105 105 106 106 #define TR_TYPE_PIECES_NAME "tr-type-pieces" … … 110 110 111 111 #define LIST_ACTION "torrent-list-action" 112 enum listact { ACT_OPEN, ACT_START, ACT_STOP, ACT_DELETE, ACT_INFO };112 enum listact { ACT_OPEN, ACT_START, ACT_STOP, ACT_DELETE, ACT_INFO, ACT_PREF }; 113 113 #define LIST_ACTION_FROM "torrent-list-action-from" 114 114 enum listfrom { FROM_BUTTON, FROM_POPUP }; … … 129 129 {4, "Properties", GTK_STOCK_PROPERTIES, ACT_INFO, 130 130 "Get additional information for a torrent", "XXX"}, 131 {5, "Preferences", GTK_STOCK_PREFERENCES, ACT_PREF, 132 "Open preferences dialog", "XXX"}, 131 133 }; 132 134 … … 136 138 GtkWidget *mainwind, *preferr, *stateerr; 137 139 char *err; 138 int port, limit;139 140 tr_handle_t *tr; 140 141 GList *saved; 142 const char *pref; 143 long intval; 141 144 142 145 gtk_init(&argc, &argv); 143 readargs(argc, argv, &port, &limit);144 146 145 147 tr = tr_init(); … … 153 155 154 156 if(!cf_loadprefs(&err)) { 155 preferr = errmsg( mainwind, "%s", err);157 preferr = errmsg(GTK_WINDOW(mainwind), "%s", err); 156 158 g_free(err); 157 159 } 158 160 saved = cf_loadstate(&err); 159 161 if(NULL != err) { 160 stateerr = errmsg( mainwind, "%s", err);162 stateerr = errmsg(GTK_WINDOW(mainwind), "%s", err); 161 163 g_free(err); 162 164 } 163 165 164 /* XXX need to remove port and limit options and make them prefs */ 165 /* XXX need prefs gui */ 166 /* XXX need default save dir pref */ 167 168 if(0 != port) 169 tr_setBindPort(tr, port); 170 if(0 != limit) 171 tr_setUploadLimit(tr, limit); 166 /* set the upload limit */ 167 setlimit(tr); 168 169 /* set the listening port */ 170 if(NULL != (pref = cf_getpref(PREF_PORT)) && 171 0 < (intval = strtol(pref, NULL, 10)) && 0xffff >= intval) 172 tr_setBindPort(tr, intval); 172 173 173 174 maketypes(); … … 179 180 gtk_widget_show_all(stateerr); 180 181 } else { 181 errmsg_full(NULL, (errfunc_t)gtk_main_quit, NULL, "%s", err); 182 gtk_widget_show(errmsg_full(NULL, (errfunc_t)gtk_main_quit, 183 NULL, "%s", err)); 182 184 g_free(err); 183 185 } 184 186 } else { 185 errmsg_full(NULL, (errfunc_t)gtk_main_quit, NULL, "%s", err); 187 gtk_widget_show(errmsg_full(NULL, (errfunc_t)gtk_main_quit, 188 NULL, "%s", err)); 186 189 g_free(err); 187 190 } … … 190 193 191 194 return 0; 192 }193 194 void195 readargs(int argc, char **argv, int *port, int *limit) {196 char *name;197 int opt, num;198 199 *port = 0;200 *limit = 0;201 202 if(NULL == (name = strrchr(argv[0], '/')) || '\0' == *(++name))203 name = argv[0];204 205 for(num = 1; num < argc; num++)206 if(0 == strcmp(argv[num], "-help") || 0 == strcmp(argv[num], "--help"))207 goto usage;208 209 while(0 <= (opt = getopt(argc, argv, "hp:u:"))) {210 switch(opt) {211 case 'p':212 num = atoi(optarg);213 if(0 < num && 0xffff > num)214 *port = num;215 break;216 case 'u':217 num = atoi(optarg);218 if(0 != num)219 *limit = num;220 break;221 default:222 goto usage;223 }224 }225 226 return;227 228 usage:229 printf("usage: %s [-h] [-p port] [-u limit]\n", name);230 exit(1);231 195 } 232 196 … … 258 222 259 223 data->tr = tr; 260 data->wind = wind;224 data->wind = GTK_WINDOW(wind); 261 225 data->timer = -1; 262 226 /* filled in by makewind_list */ … … 278 242 for(ii = g_list_first(saved); NULL != ii; ii = ii->next) { 279 243 ts = ii->data; 280 addtorrent(tr, wind, ts->ts_torrent, ts->ts_directory, ts->ts_paused); 244 addtorrent(tr, GTK_WINDOW(wind), 245 ts->ts_torrent, ts->ts_directory, ts->ts_paused); 281 246 cf_freestate(ts); 282 247 } … … 323 288 fprintf(stderr, "quit: starting timeout at %i\n", edata->started); 324 289 325 //exitcheck(edata);326 327 290 /* returning FALSE means to destroy the window */ 328 291 return TRUE; … … 364 327 data->timer = -1; 365 328 366 gtk_widget_destroy( data->cbdata->wind);329 gtk_widget_destroy(GTK_WIDGET(data->cbdata->wind)); 367 330 tr_close(data->cbdata->tr); 368 331 g_free(data->cbdata); … … 382 345 gtk_toolbar_set_style(GTK_TOOLBAR(bar), GTK_TOOLBAR_BOTH); 383 346 384 for(ii = 0; ii < sizeof(actionitems) / sizeof(actionitems[0]); ii++) {347 for(ii = 0; ii < ALEN(actionitems); ii++) { 385 348 item = gtk_tool_button_new_from_stock(actionitems[ii].id); 386 349 gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), actionitems[ii].name); … … 420 383 GtkCellRenderer *rendprog; 421 384 422 assert(MC_ROW_COUNT == sizeof(types) / sizeof(types[0]));385 assert(MC_ROW_COUNT == ALEN(types)); 423 386 424 387 model = gtk_list_store_newv(MC_ROW_COUNT, types); … … 433 396 g_object_set(rendprog, "text", "", NULL); 434 397 435 /*436 col = gtk_tree_view_column_new_with_attributes(437 "Name", rend, "text", MC_NAME, NULL);438 gtk_tree_view_column_add_attribute(col, rend, "text", MC_SIZE);439 gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);440 441 col = gtk_tree_view_column_new_with_attributes(442 "Status", rend, "text", MC_STAT, NULL);443 gtk_tree_view_column_add_attribute(col, rend, "text", MC_ERR);444 gtk_tree_view_column_add_attribute(col, rend, "text", MC_DPEERS);445 gtk_tree_view_column_add_attribute(col, rend, "text", MC_UPEERS);446 gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);447 448 col = gtk_tree_view_column_new_with_attributes(449 "Progress", rendprog, "value", MC_PROG, NULL);450 gtk_tree_view_column_pack_start(col, rend, TRUE);451 gtk_tree_view_column_add_attribute(col, rend, "text", MC_ETA);452 gtk_tree_view_column_add_attribute(col, rend, "text", MC_DRATE);453 gtk_tree_view_column_add_attribute(col, rend, "text", MC_URATE);454 gtk_tree_view_column_add_attribute(col, rend, "text", MC_DOWN);455 gtk_tree_view_column_add_attribute(col, rend, "text", MC_UP);456 gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);457 */458 459 398 gtk_tree_view_append_column(GTK_TREE_VIEW(view), 460 399 gtk_tree_view_column_new_with_attributes("Name", rend, … … 490 429 gtk_tree_view_column_new_with_attributes("Leechers", rend, 491 430 "text", MC_DPEERS, NULL)); 492 /*gtk_tree_view_append_column(GTK_TREE_VIEW(view),493 gtk_tree_view_column_new_with_attributes("", rend,494 "text", MC_PIECES, NULL));*/495 431 gtk_tree_view_append_column(GTK_TREE_VIEW(view), 496 432 gtk_tree_view_column_new_with_attributes("Downloaded", rend, … … 533 469 MC_URATE, st[ii].rateUpload, MC_ETA, st[ii].eta, MC_PEERS, st[ii].peersTotal, 534 470 MC_UPEERS, st[ii].peersUploading, MC_DPEERS, st[ii].peersDownloading, 535 /*MC_PIECES, st[ii].pieces,*/MC_DOWN, st[ii].downloaded, MC_UP, st[ii].uploaded, -1);471 MC_DOWN, st[ii].downloaded, MC_UP, st[ii].uploaded, -1); 536 472 } 537 473 free(st); … … 579 515 /* XXX am I leaking references here? */ 580 516 /* XXX can I cache this in cbdata? */ 581 for(ii = 0; ii < sizeof(actionitems) / sizeof(actionitems[0]); ii++) {517 for(ii = 0; ii < ALEN(actionitems); ii++) { 582 518 item = gtk_menu_item_new_with_label(actionitems[ii].name); 583 519 g_object_set_data(G_OBJECT(item), LIST_ACTION, … … 611 547 tr_stat_t *sb; 612 548 613 if(ACT_OPEN == act) { 614 makeaddwind(data); 615 return; 549 switch(act) { 550 case ACT_OPEN: 551 makeaddwind(data); 552 return; 553 case ACT_PREF: 554 makeprefwindow(data->wind, data->tr); 555 return; 556 default: 557 break; 616 558 } 617 559 … … 674 616 g_signal_connect_swapped(GTK_FILE_SELECTION(wind)->cancel_button, "clicked", 675 617 G_CALLBACK(gtk_widget_destroy), wind); 676 gtk_window_set_transient_for(GTK_WINDOW(wind), GTK_WINDOW(data->wind));618 gtk_window_set_transient_for(GTK_WINDOW(wind), data->wind); 677 619 gtk_window_set_destroy_with_parent(GTK_WINDOW(wind), TRUE); 678 620 gtk_window_set_modal(GTK_WINDOW(wind), TRUE); … … 681 623 682 624 gboolean 683 addtorrent(tr_handle_t *tr, GtkWi dget*parentwind, const char *torrent,625 addtorrent(tr_handle_t *tr, GtkWindow *parentwind, const char *torrent, 684 626 const char *dir, gboolean paused) { 685 627 char *wd; 628 629 if(NULL == dir) { 630 dir = cf_getpref(PREF_DIR); 631 if(!mkdir_p(dir, 0777)) { 632 errmsg(parentwind, "Failed to create download directory %s:\n%s", 633 dir, strerror(errno)); 634 return FALSE; 635 } 636 } 686 637 687 638 if(0 != tr_torrentInit(tr, torrent)) { … … 694 645 tr_torrentSetFolder(tr, tr_torrentCount(tr) - 1, dir); 695 646 else { 696 /* XXX need pref for download directory */697 647 wd = g_new(char, MAXPATHLEN + 1); 698 648 if(NULL == getcwd(wd, MAXPATHLEN + 1)) … … 748 698 assert(!"XXX i'm tired"); 749 699 } 750 wind = gtk_dialog_new_with_buttons(sb[index].info.name, GTK_WINDOW(data->wind),700 wind = gtk_dialog_new_with_buttons(sb[index].info.name, data->wind, 751 701 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL); 752 702 … … 856 806 857 807 gboolean 858 savetorrents(tr_handle_t *tr, GtkWi dget*wind, int count, tr_stat_t *stat) {808 savetorrents(tr_handle_t *tr, GtkWindow *wind, int count, tr_stat_t *stat) { 859 809 char *errstr; 860 810 tr_stat_t *st; -
trunk/gtk/util.c
r5 r7 25 25 */ 26 26 27 #include <sys/types.h> 28 #include <sys/stat.h> 29 #include <errno.h> 27 30 #include <stdarg.h> 31 #include <string.h> 32 28 33 #include <gtk/gtk.h> 29 34 … … 31 36 32 37 static void 33 errcb(GtkWidget *wi dget, int resp, gpointer data);38 errcb(GtkWidget *wind, int resp, gpointer data); 34 39 35 40 gboolean … … 51 56 } 52 57 58 gboolean 59 mkdir_p(const char *name, mode_t mode) { 60 struct stat sb; 61 char *parent; 62 gboolean ret; 63 int oerrno; 64 65 if(0 != stat(name, &sb)) { 66 if(ENOENT != errno) 67 return FALSE; 68 parent = g_path_get_dirname(name); 69 ret = mkdir_p(parent, mode); 70 oerrno = errno; 71 g_free(parent); 72 errno = oerrno; 73 return (ret ? (0 == mkdir(name, mode)) : FALSE); 74 } 75 76 if(!S_ISDIR(sb.st_mode)) { 77 errno = ENOTDIR; 78 return FALSE; 79 } 80 81 return TRUE; 82 } 83 53 84 GtkWidget * 54 errmsg(GtkWi dget*wind, const char *format, ...) {85 errmsg(GtkWindow *wind, const char *format, ...) { 55 86 GtkWidget *dialog; 56 87 va_list ap; … … 64 95 65 96 GtkWidget * 66 errmsg_full(GtkWi dget*wind, errfunc_t func, void *data,97 errmsg_full(GtkWindow *wind, errfunc_t func, void *data, 67 98 const char *format, ...) { 68 99 GtkWidget *dialog; … … 77 108 78 109 GtkWidget * 79 verrmsg(GtkWi dget*wind, errfunc_t func, void *data,110 verrmsg(GtkWindow *wind, errfunc_t func, void *data, 80 111 const char *format, va_list ap) { 81 112 GtkWidget *dialog; … … 89 120 NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", msg); 90 121 else 91 dialog = gtk_message_dialog_new( 92 GTK_ WINDOW(wind), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,122 dialog = gtk_message_dialog_new(wind, 123 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, 93 124 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", msg); 94 125 … … 99 130 g_signal_connect(dialog, "response", G_CALLBACK(errcb), funcdata); 100 131 if(NULL != wind) 101 gtk_widget_show _all(dialog);132 gtk_widget_show(dialog); 102 133 g_free(msg); 103 134 -
trunk/gtk/util.h
r5 r7 28 28 #define TG_UTIL_H 29 29 30 #include <sys/types.h> 30 31 #include <stdarg.h> 31 32 … … 37 38 #endif 38 39 40 /* return number of items in array */ 41 #define ALEN(a) (sizeof(a) / sizeof((a)[0])) 42 39 43 gboolean 40 44 strbool(const char *str); 45 46 gboolean 47 mkdir_p(const char *name, mode_t mode); 41 48 42 49 typedef void (*errfunc_t)(void*); … … 45 52 46 53 GtkWidget * 47 errmsg(GtkWi dget*wind, const char *format, ...)54 errmsg(GtkWindow *wind, const char *format, ...) 48 55 #ifdef __GNUC__ 49 56 __attribute__ ((format (printf, 2, 3))) … … 52 59 53 60 GtkWidget * 54 errmsg_full(GtkWi dget*wind, errfunc_t func, void *data,61 errmsg_full(GtkWindow *wind, errfunc_t func, void *data, 55 62 const char *format, ...) 56 63 #ifdef __GNUC__ … … 60 67 61 68 GtkWidget * 62 verrmsg(GtkWi dget*wind, errfunc_t func, void *data,69 verrmsg(GtkWindow *wind, errfunc_t func, void *data, 63 70 const char *format, va_list ap); 64 71 -
trunk/libtransmission/transmission.c
r6 r7 66 66 h->fdlimit = tr_fdInit(); 67 67 68 h->bindPort = 9090;68 h->bindPort = TR_DEFAULT_PORT; 69 69 70 70 snprintf( h->prefsDirectory, sizeof( h->prefsDirectory ), -
trunk/libtransmission/transmission.h
r6 r7 30 30 #define TR_MAX_TORRENT_COUNT 50 31 31 32 #define TR_DEFAULT_PORT 9090 33 32 34 /*********************************************************************** 33 35 * tr_init -
trunk/libtransmission/upload.c
r1 r7 102 102 now = tr_date(); 103 103 104 /* Check the last fourtimes we sent something and decide if104 /* Check the last FOO times we sent something and decide if 105 105 we must wait */ 106 106 for( i = 0; i < FOO; i++ ) 107 107 { 108 108 size += u->sizes[i]; 109 if( (uint64_t) size < 1024ULL *110 u->limit * ( now - u->dates[i] ) / 1000)109 if( (uint64_t) size * 1000 < 110 ( now - u->dates[i] ) * u->limit * 1024 ) 111 111 { 112 112 ret = 1; -
trunk/libtransmission/utils.h
r3 r7 43 43 struct timeval tv; 44 44 gettimeofday( &tv, NULL ); 45 return ( (uint64_t) tv.tv_sec * 1000 + (uint64_t)tv.tv_usec / 1000 );45 return (uint64_t) tv.tv_sec * 1000 + ( tv.tv_usec / 1000 ); 46 46 } 47 47 -
trunk/macosx/Controller.h
r6 r7 27 27 #include <transmission.h> 28 28 #include "PrefsController.h" 29 #include <Growl/Growl.h>30 29 31 30 @class TorrentTableView; 32 31 33 @interface Controller : NSObject <GrowlApplicationBridgeDelegate>32 @interface Controller : NSObject 34 33 { 35 34 tr_handle_t * fHandle; … … 99 98 - (void) linkHomepage: (id) sender; 100 99 - (void) linkForums: (id) sender; 101 - (void) notifyGrowl: (NSString *) file folder: (NSString *) folder; 102 - (void) revealInFinder: (NSString *) path; 100 - (void) notifyGrowl: (NSString *) file; 101 - (void) finderReveal: (NSString *) path; 102 - (void) finderTrash: (NSString *) path; 103 - (void) growlRegister: (id) sender; 103 104 104 105 @end -
trunk/macosx/Controller.m
r6 r7 192 192 193 193 /* Register with the growl system */ 194 [ GrowlApplicationBridge setGrowlDelegate:self];194 [self growlRegister: self]; 195 195 196 196 /* Update the interface every 500 ms */ … … 468 468 deleteData: (BOOL) deleteData 469 469 { 470 BOOL torrentWarning = ![[NSUserDefaults standardUserDefaults] 471 boolForKey:@"SkipTorrentDeletionWarning"]; 472 BOOL dataWarning = ![[NSUserDefaults standardUserDefaults] 473 boolForKey:@"SkipDataDeletionWarning"]; 474 475 if ( ( torrentWarning && deleteTorrent ) || (dataWarning && deleteData ) ) 476 { 477 NSAlert *alert = [[[NSAlert alloc] init] autorelease]; 478 479 [alert addButtonWithTitle:@"Delete"]; 480 [alert addButtonWithTitle:@"Cancel"]; 481 [alert setAlertStyle:NSWarningAlertStyle]; 482 [alert setMessageText:@"Do you want to remove this torrent from Transmission?"]; 483 484 if ( (deleteTorrent && torrentWarning) && 485 !( dataWarning && deleteData ) ) 486 { 487 /* delete torrent warning YES, delete data warning NO */ 488 [alert setInformativeText:@"This will delete the .torrent file only. " 489 "This can not be undone!"]; 490 } 491 else if( (deleteData && dataWarning) && 492 !( torrentWarning && deleteTorrent ) ) 493 { 494 /* delete torrent warning NO, delete data warning YES */ 495 [alert setInformativeText:@"This will delete the downloaded data. " 496 "This can not be undone!"]; 497 } 498 else 499 { 500 /* delete torrent warning YES, delete data warning YES */ 501 [alert setInformativeText:@"This will delete the downloaded data and " 502 ".torrent file. This can not be undone!"]; 503 } 504 505 if ( [alert runModal] == NSAlertSecondButtonReturn ) 506 return; 507 } 508 509 if ( deleteData ) 510 { 511 tr_file_t * files = fStat[idx].info.files; 512 int i; 513 514 for ( i = 0; i < fStat[idx].info.fileCount; i++ ) 515 { 516 if ( -1 == remove([[NSString stringWithFormat:@"%s/%s", 517 fStat[idx].folder, 518 files[i].name] 519 cString]) ) 520 { 521 NSLog(@"remove(%s) failed, errno = %i", 522 files[i].name, 523 errno); 524 } 525 } 526 527 /* in some cases, we should remove fStat[idx].folder also. When? */ 528 } 529 530 if ( deleteTorrent ) 531 { 532 if ( -1 == remove( fStat[idx].info.torrent ) ) 533 { 534 NSLog(@"remove(%s) failed, errno = %i", 535 fStat[idx].info.torrent, 536 errno); 537 } 470 if( deleteData ) 471 { 472 [self finderTrash: [NSString stringWithFormat: @"%@/%@", 473 [NSString stringWithUTF8String: fStat[idx].folder], 474 [NSString stringWithUTF8String: fStat[idx].info.name]]]; 475 } 476 if( deleteTorrent ) 477 { 478 [self finderTrash: [NSString stringWithUTF8String: 479 fStat[idx].info.torrent]]; 538 480 } 539 481 … … 612 554 } 613 555 [self notifyGrowl: [NSString stringWithUTF8String: 614 fStat[i].info.name] folder: [NSString stringWithUTF8String: 615 fStat[i].folder]]; 556 fStat[i].info.name]]; 616 557 tr_setFinished( fHandle, i, 0 ); 617 558 } … … 910 851 } 911 852 912 - (void) notifyGrowl: (NSString * ) file folder: (NSString *) folder 913 { 914 [GrowlApplicationBridge 915 notifyWithTitle: @"Download complete." 916 description: [NSString stringWithFormat: @"Seeding: %@", file] 917 notificationName: @"Download complete." 918 iconData: nil 919 priority: 0 920 isSticky: FALSE 921 clickContext: [NSString stringWithFormat: @"%@/%@", folder, file]]; 922 } 923 924 - (NSDictionary *)registrationDictionaryForGrowl 853 - (void) notifyGrowl: (NSString * ) file 854 { 855 NSString * growlScript; 856 NSAppleScript * appleScript; 857 NSDictionary * error; 858 859 growlScript = [NSString stringWithFormat: 860 @"tell application \"System Events\"\n" 861 " if exists application process \"GrowlHelperApp\" then\n" 862 " tell application \"GrowlHelperApp\"\n " 863 " notify with name \"Download Complete\"" 864 " title \"Download Complete\"" 865 " description \"%@\"" 866 " application name \"Transmission\"\n" 867 " end tell\n" 868 " end if\n" 869 "end tell", file]; 870 appleScript = [[NSAppleScript alloc] initWithSource: growlScript]; 871 if( ![appleScript executeAndReturnError: &error] ) 872 { 873 printf( "Growl notify failed\n" ); 874 } 875 [appleScript release]; 876 } 877 878 - (void) growlRegister: (id) sender 925 879 { 926 NSString *title = [NSString stringWithUTF8String: "Download complete."]; 927 NSMutableArray *defNotesArray = [NSMutableArray array]; 928 NSMutableArray *allNotesArray = [NSMutableArray array]; 929 930 [allNotesArray addObject:title]; 931 [defNotesArray addObject:[NSNumber numberWithUnsignedInt:0]]; 932 933 NSDictionary *regDict = [NSDictionary dictionaryWithObjectsAndKeys: 934 @"Transmission", GROWL_APP_NAME, 935 allNotesArray, GROWL_NOTIFICATIONS_ALL, 936 defNotesArray, GROWL_NOTIFICATIONS_DEFAULT, 937 nil]; 938 939 return regDict; 940 } 941 942 - (NSString *) applicationNameForGrowl 943 { 944 return [NSString stringWithUTF8String: "Transmission"]; 945 } 946 947 - (void) growlNotificationWasClicked: (id) clickContext 948 { 949 [self revealInFinder: (NSString *) clickContext]; 950 } 880 NSString * growlScript; 881 NSAppleScript * appleScript; 882 NSDictionary * error; 883 884 growlScript = [NSString stringWithFormat: 885 @"tell application \"System Events\"\n" 886 " if exists application process \"GrowlHelperApp\" then\n" 887 " tell application \"GrowlHelperApp\"\n" 888 " register as application \"Transmission\" " 889 " all notifications {\"Download Complete\"}" 890 " default notifications {\"Download Complete\"}" 891 " icon of application \"Transmission\"\n" 892 " end tell\n" 893 " end if\n" 894 "end tell"]; 895 appleScript = [[NSAppleScript alloc] initWithSource: growlScript]; 896 if( ![appleScript executeAndReturnError: &error] ) 897 { 898 printf( "Growl registration failed\n" ); 899 } 900 [appleScript release]; 901 } 902 951 903 952 904 - (void) revealFromMenu: (id) sender 953 905 { 954 [fTableView revealInFinder: [fTableView selectedRow]]; 955 } 956 957 - (void) revealInFinder: (NSString *) path 906 int row; 907 908 row = [fTableView selectedRow]; 909 if( row < 0 ) 910 { 911 return; 912 } 913 [self finderReveal: [NSString stringWithFormat: @"%@/%@", 914 [NSString stringWithUTF8String: fStat[row].folder], 915 [NSString stringWithUTF8String: fStat[row].info.name]]]; 916 } 917 918 - (void) finderReveal: (NSString *) path 958 919 { 959 920 NSString * string; … … 961 922 NSDictionary * error; 962 923 963 string = [NSString stringWithFormat: @"tell application " 964 "\"Finder\"\nactivate\nreveal (POSIX file \"%@\")\nend tell", 965 path]; 924 string = [NSString stringWithFormat: 925 @"tell application \"Finder\"\n" 926 " activate\n" 927 " reveal (POSIX file \"%@\")\n" 928 "end tell", path]; 929 966 930 appleScript = [[NSAppleScript alloc] initWithSource: string]; 967 931 if( ![appleScript executeAndReturnError: &error] ) 968 932 { 969 printf( " Reveal in Finder: AppleScriptfailed\n" );933 printf( "finderReveal failed\n" ); 970 934 } 971 935 [appleScript release]; 972 936 } 973 937 938 - (void) finderTrash: (NSString *) path 939 { 940 NSString * string; 941 NSAppleScript * appleScript; 942 NSDictionary * error; 943 944 string = [NSString stringWithFormat: 945 @"tell application \"Finder\"\n" 946 " move (POSIX file \"%@\") to trash\n" 947 "end tell", path]; 948 949 appleScript = [[NSAppleScript alloc] initWithSource: string]; 950 if( ![appleScript executeAndReturnError: &error] ) 951 { 952 printf( "finderTrash failed\n" ); 953 } 954 [appleScript release]; 955 } 974 956 975 957 @end -
trunk/macosx/PrefsController.m
r1 r7 45 45 NSUserDefaults * defaults; 46 46 NSDictionary * appDefaults; 47 NSString * desktop, * port; 47 48 48 49 fHandle = handle; … … 51 52 - Simple bar 52 53 - Always download to Desktop 53 - Port 909054 - Port TR_DEFAULT_PORT 54 55 - 20 KB/s upload limit */ 55 NSString * desktopPath 56 = [NSString stringWithFormat: @"%@/Desktop", 57 NSHomeDirectory()]; 56 desktop = [NSHomeDirectory() stringByAppendingString: @"/Desktop"]; 57 port = [NSString stringWithFormat: @"%d", TR_DEFAULT_PORT]; 58 58 59 59 defaults = [NSUserDefaults standardUserDefaults]; … … 61 61 @"NO", @"UseAdvancedBar", 62 62 @"Constant", @"DownloadChoice", 63 desktop Path,@"DownloadFolder",64 @"9090",@"BindPort",63 desktop, @"DownloadFolder", 64 port, @"BindPort", 65 65 @"20", @"UploadLimit", 66 66 NULL]; -
trunk/macosx/ProgressCell.h
r6 r7 31 31 tr_stat_t * fStat; 32 32 33 NSString * fProgressString;34 33 NSString * fDlString; 35 34 NSString * fUlString; 36 35 37 NSBitmapImageRep * fB gBmp;38 NSBitmapImageRep * f Bmp;36 NSBitmapImageRep * fBackgroundBmp; 37 NSBitmapImageRep * fProgressBmp; 39 38 } 40 39 - (id) init; -
trunk/macosx/ProgressCell.m
r6 r7 23 23 #include "ProgressCell.h" 24 24 25 @implementation ProgressCell 26 27 /*********************************************************************** 28 * Static tables 29 *********************************************************************** 30 * We use these tables to optimize the drawing. They contain packed 31 * RGBA pixels for every color we might need. 32 **********************************************************************/ 25 33 #if 0 26 34 /* Coefficients for the "3D effect" */ … … 72 80 0x00ED00FF, 0x00F200FF, 0x00F400FF, 0x00B500FF }; 73 81 74 @implementation ProgressCell 75 82 /*********************************************************************** 83 * init 84 *********************************************************************** 85 * Prepares the NSBitmapImageReps we are going to need in order to 86 * draw. 87 **********************************************************************/ 76 88 - (id) init 77 89 { 78 NSImage * bgImg;79 NSSize size;80 81 90 self = [super init]; 82 91 83 /* Have a NSBitmapImageRep ready to draw the progression bar */ 84 bgImg = [NSImage imageNamed: @"Progress.png"]; 85 fBgBmp = [[bgImg representations] objectAtIndex: 0]; 86 size = [bgImg size]; 87 fBmp = [[NSBitmapImageRep alloc] 88 initWithBitmapDataPlanes: NULL pixelsWide: size.width 89 pixelsHigh: size.height bitsPerSample: 8 samplesPerPixel: 4 90 hasAlpha: YES isPlanar: NO 92 /* Load the background image for the progress bar and get it as a 93 32-bit bitmap */ 94 fBackgroundBmp = [[[NSImage imageNamed: @"Progress.png"] 95 representations] objectAtIndex: 0]; 96 97 /* Allocate another bitmap of the same size. We will draw the 98 progress bar in it */ 99 fProgressBmp = [[NSBitmapImageRep alloc] 100 initWithBitmapDataPlanes: NULL pixelsWide: 101 [fBackgroundBmp size].width pixelsHigh: 102 [fBackgroundBmp size].height bitsPerSample: 8 103 samplesPerPixel: 4 hasAlpha: YES isPlanar: NO 91 104 colorSpaceName: NSCalibratedRGBColorSpace 92 105 bytesPerRow: 0 bitsPerPixel: 0]; … … 95 108 } 96 109 110 /*********************************************************************** 111 * setStat 112 *********************************************************************** 113 * Readies ourselves to draw updated info. 114 **********************************************************************/ 97 115 - (void) setStat: (tr_stat_t *) stat 98 116 { 99 117 int i; 118 uint8_t * in, * out; 100 119 101 120 fStat = stat; 102 121 103 fProgressString = [NSString stringWithFormat: 104 @"%.2f %%", 100.0 * fStat->progress]; 122 /* Update the strings to be displayed */ 105 123 fDlString = [NSString stringWithFormat: 106 124 @"DL: %.2f KB/s", fStat->rateDownload]; … … 108 126 @"UL: %.2f KB/s", fStat->rateUpload]; 109 127 110 for( i = 0; i < [fBmp size].height; i++ ) 111 { 112 memcpy( [fBmp bitmapData] + i * [fBmp bytesPerRow], 113 [fBgBmp bitmapData] + i * [fBgBmp bytesPerRow], 114 [fBmp size].width * 4 ); 115 } 116 128 /* Reset our bitmap to the background image... */ 129 in = [fBackgroundBmp bitmapData]; 130 out = [fProgressBmp bitmapData]; 131 for( i = 0; i < [fProgressBmp size].height; i++ ) 132 { 133 memcpy( out, in, [fProgressBmp size].width * 4 ); 134 in += [fBackgroundBmp bytesPerRow]; 135 out += [fProgressBmp bytesPerRow]; 136 } 137 138 /* ...and redraw the progress bar on the top of it */ 117 139 if( [[NSUserDefaults standardUserDefaults] 118 140 boolForKey:@"UseAdvancedBar"]) … … 126 148 } 127 149 150 /*********************************************************************** 151 * buildSimpleBar 152 **********************************************************************/ 128 153 - (void) buildSimpleBar 129 154 { 130 int h, w ;155 int h, w, end, pixelsPerRow; 131 156 uint32_t * p; 157 uint32_t * colors; 158 159 pixelsPerRow = [fProgressBmp bytesPerRow] / 4; 160 161 /* The background image is 124*18 pixels, but the actual 162 progress bar is 120*14 : the first two columns, the last 163 two columns and the last four lines contain the shadow. */ 164 165 p = (uint32_t *) [fProgressBmp bitmapData]; 166 p += 2; 167 end = lrintf( floor( fStat->progress * 120 ) ); 168 colors = ( fStat->status & TR_STATUS_SEED ) ? kGreen : kBlue2; 132 169 133 170 for( h = 0; h < 14; h++ ) 134 171 { 135 p = (uint32_t *) ( [fBmp bitmapData] + 136 h * [fBmp bytesPerRow] ) + 2; 137 138 for( w = 0; w < 120; w++ ) 139 { 140 if( w >= (int) ( fStat->progress * 120 ) ) 141 { 142 break; 143 } 144 145 if( fStat->status & TR_STATUS_SEED ) 146 { 147 *p = kGreen[h]; 148 } 149 else 150 { 151 *p = kBlue2[h]; 152 } 153 p++; 154 } 155 } 156 } 157 172 for( w = 0; w < end; w++ ) 173 { 174 p[w] = colors[h]; 175 } 176 p += pixelsPerRow; 177 } 178 } 179 180 /*********************************************************************** 181 * buildAdvancedBar 182 **********************************************************************/ 158 183 - (void) buildAdvancedBar 159 184 { 160 int h, w ;185 int h, w, end, pixelsPerRow; 161 186 uint32_t * p; 162 163 for( h = 0; h < 14; h++ ) 164 { 165 p = (uint32_t *) ( [fBmp bitmapData] + 166 h * [fBmp bytesPerRow] ) + 2; 167 168 for( w = 0; w < 120; w++ ) 169 { 170 if( fStat->status & TR_STATUS_SEED ) 171 { 172 *p = kGreen[h]; 173 } 174 else 175 { 176 /* Download is not finished yet */ 177 if( h < 2 ) 178 { 179 /* First two lines: dark blue to show progression */ 180 if( w >= (int) ( fStat->progress * 120 ) ) 181 { 182 break; 183 } 184 *p = kBlue4[h]; 185 } 186 else 187 { 188 /* Lines 2 to X: blue or grey depending on whether 189 we have the piece or not */ 190 if( fStat->pieces[w] < 0 ) 191 { 192 *p = kGray[h]; 193 } 194 else if( fStat->pieces[w] < 1 ) 195 { 196 *p = kRed[h]; 197 } 198 else if( fStat->pieces[w] < 2 ) 199 { 200 *p = kBlue1[h]; 201 } 202 else if( fStat->pieces[w] < 3 ) 203 { 204 *p = kBlue2[h]; 205 } 206 else 207 { 208 *p = kBlue3[h]; 209 } 210 } 211 } 212 213 p++; 214 } 215 } 216 } 217 187 uint32_t * colors; 188 189 if( fStat->status & TR_STATUS_SEED ) 190 { 191 /* All green, same as the simple bar */ 192 [self buildSimpleBar]; 193 return; 194 } 195 196 pixelsPerRow = [fProgressBmp bytesPerRow] / 4; 197 198 /* First two lines: dark blue to show progression */ 199 p = (uint32_t *) [fProgressBmp bitmapData]; 200 p += 2; 201 end = lrintf( floor( fStat->progress * 120 ) ); 202 for( h = 0; h < 2; h++ ) 203 { 204 for( w = 0; w < end; w++ ) 205 { 206 p[w] = kBlue4[h]; 207 } 208 p += pixelsPerRow; 209 } 210 211 /* Lines 2 to 14: blue or grey depending on whether 212 we have the piece or not */ 213 for( w = 0; w < 120; w++ ) 214 { 215 /* Point to pixel ( 2 + w, 2 ). We will then draw 216 "vertically" */ 217 p = (uint32_t *) ( [fProgressBmp bitmapData] + 218 2 * [fProgressBmp bytesPerRow] ); 219 p += 2 + w; 220 221 if( fStat->pieces[w] < 0 ) 222 { 223 colors = kGray; 224 } 225 else if( fStat->pieces[w] < 1 ) 226 { 227 colors = kRed; 228 } 229 else if( fStat->pieces[w] < 2 ) 230 { 231 colors = kBlue1; 232 } 233 else if( fStat->pieces[w] < 3 ) 234 { 235 colors = kBlue2; 236 } 237 else 238 { 239 colors = kBlue3; 240 } 241 242 for( h = 2; h < 14; h++ ) 243 { 244 p[0] = colors[h]; 245 p += pixelsPerRow; 246 } 247 } 248 } 249 250 /*********************************************************************** 251 * drawWithFrame 252 *********************************************************************** 253 * We have the strings, we have the bitmap. Let's just draw them where 254 * they belong. 255 **********************************************************************/ 218 256 - (void) drawWithFrame: (NSRect) cellFrame inView: (NSView *) view 219 257 { 220 258 NSImage * img; 259 NSMutableDictionary * attributes; 260 NSPoint pen; 221 261 222 262 if( ![view lockFocusIfCanDraw] ) … … 225 265 } 226 266 227 NSMutableDictionary * attributes; 228 NSPoint pen = cellFrame.origin; 229 230 attributes = [NSMutableDictionary dictionaryWithCapacity: 1]; 231 [attributes setObject: [NSFont messageFontOfSize:12.0] 232 forKey: NSFontAttributeName]; 233 267 pen = cellFrame.origin; 268 269 /* Init an NSImage with our bitmap in order to draw it. We need to 270 do this every time, or for some reason it won't draw if the 271 display is set to thousands of colors when Transmission was 272 started */ 273 img = [[NSImage alloc] initWithSize: [fProgressBmp size]]; 274 [img addRepresentation: fProgressBmp]; 275 [img setFlipped: YES]; 276 277 /* Actually draw the bar */ 234 278 pen.x += 5; pen.y += 5; 235 236 img = [[NSImage alloc] initWithSize: [fBmp size]]; 237 [img addRepresentation: fBmp]; 238 [img setFlipped: YES]; 239 [img drawAtPoint: pen fromRect: 240 NSMakeRect( 0, 0, [fBmp size].width, [fBmp size].height ) 279 [img drawAtPoint: pen fromRect: NSMakeRect( 0, 0, 280 [fProgressBmp size].width, [fProgressBmp size].height ) 241 281 operation: NSCompositeSourceOver fraction: 1.0]; 282 242 283 [img release]; 243 284 244 [attributes setObject: [NSFont messageFontOfSize:10.0]245 forKey: NSFontAttributeName];246 285 /* Draw the strings with font 10 */ 286 attributes = [NSDictionary dictionaryWithObject: 287 [NSFont messageFontOfSize: 10.0] forKey: NSFontAttributeName]; 247 288 pen.x += 5; pen.y += 20; 248 289 [fDlString drawAtPoint: pen withAttributes: attributes]; 249 250 290 pen.x += 0; pen.y += 15; 251 291 [fUlString drawAtPoint: pen withAttributes: attributes]; -
trunk/macosx/TorrentTableView.m
r6 r7 8 8 fStat = stat; 9 9 [self reloadData]; 10 }11 12 - (void) revealInFinder: (int) row13 {14 NSString * string;15 NSAppleScript * appleScript;16 NSDictionary * error;17 18 string = [NSString stringWithFormat: @"tell application "19 "\"Finder\"\nactivate\nreveal (POSIX file \"%@/%@\")\nend tell",20 [NSString stringWithUTF8String: fStat[row].folder],21 [NSString stringWithUTF8String: fStat[row].info.name]];22 appleScript = [[NSAppleScript alloc] initWithSource: string];23 if( ![appleScript executeAndReturnError: &error] )24 {25 printf( "Reveal in Finder: AppleScript failed\n" );26 }27 [appleScript release];28 10 } 29 11 … … 107 89 else if( [self pointInRevealRect: point] ) 108 90 { 109 [fController revealInFinder: [NSString stringWithFormat:91 [fController finderReveal: [NSString stringWithFormat: 110 92 @"%@/%@", [NSString stringWithUTF8String: fStat[row].folder], 111 93 [NSString stringWithUTF8String: fStat[row].info.name]]]; -
trunk/macosx/Transmission.xcodeproj/project.pbxproj
r6 r7 19 19 4D752E930913C949008EAAD4 /* Preferences.png in Resources */ = {isa = PBXBuildFile; fileRef = 4D752E920913C949008EAAD4 /* Preferences.png */; }; 20 20 4D813EB508AA43AC00191DB4 /* Progress.png in Resources */ = {isa = PBXBuildFile; fileRef = 4D813EB408AA43AC00191DB4 /* Progress.png */; }; 21 4D81E2E4092EF0CB00F24127 /* Growl.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D81E2E3092EF0CB00F24127 /* Growl.framework */; };22 4D81E309092EF26F00F24127 /* Growl.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4D81E2E3092EF0CB00F24127 /* Growl.framework */; };23 21 4DA6FDBA0911233800450CB1 /* PauseOn.png in Resources */ = {isa = PBXBuildFile; fileRef = 4DA6FDB80911233800450CB1 /* PauseOn.png */; }; 24 22 4DA6FDBB0911233800450CB1 /* PauseOff.png in Resources */ = {isa = PBXBuildFile; fileRef = 4DA6FDB90911233800450CB1 /* PauseOff.png */; }; … … 62 60 }; 63 61 /* End PBXBuildStyle section */ 64 65 /* Begin PBXCopyFilesBuildPhase section */66 4D81E301092EF24500F24127 /* CopyFiles */ = {67 isa = PBXCopyFilesBuildPhase;68 buildActionMask = 2147483647;69 dstPath = "";70 dstSubfolderSpec = 10;71 files = (72 4D81E309092EF26F00F24127 /* Growl.framework in CopyFiles */,73 );74 runOnlyForDeploymentPostprocessing = 0;75 };76 /* End PBXCopyFilesBuildPhase section */77 62 78 63 /* Begin PBXFileReference section */ … … 100 85 4D752E920913C949008EAAD4 /* Preferences.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Preferences.png; path = Images/Preferences.png; sourceTree = "<group>"; }; 101 86 4D813EB408AA43AC00191DB4 /* Progress.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Progress.png; path = Images/Progress.png; sourceTree = "<group>"; }; 102 4D81E2E3092EF0CB00F24127 /* Growl.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Growl.framework; path = Frameworks/Growl.framework; sourceTree = "<group>"; };103 87 4DA6FDB80911233800450CB1 /* PauseOn.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = PauseOn.png; path = Images/PauseOn.png; sourceTree = "<group>"; }; 104 88 4DA6FDB90911233800450CB1 /* PauseOff.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = PauseOff.png; path = Images/PauseOff.png; sourceTree = "<group>"; }; … … 123 107 4DF0C5AE08991C1600DD8943 /* libtransmission.a in Frameworks */, 124 108 4D3EA0AA08AE13C600EA10C2 /* IOKit.framework in Frameworks */, 125 4D81E2E4092EF0CB00F24127 /* Growl.framework in Frameworks */,126 109 ); 127 110 runOnlyForDeploymentPostprocessing = 0; … … 151 134 children = ( 152 135 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, 153 4D81E2E3092EF0CB00F24127 /* Growl.framework */,154 136 ); 155 137 name = "Linked Frameworks"; … … 239 221 8D11072C0486CEB800E47090 /* Sources */, 240 222 8D11072E0486CEB800E47090 /* Frameworks */, 241 4D81E301092EF24500F24127 /* CopyFiles */,242 223 ); 243 224 buildRules = ( -
trunk/transmissioncli.c
r3 r7 40 40 " -s, --scrape Print counts of seeders/leechers and exit\n" \ 41 41 " -v, --verbose <int> Verbose level (0 to 2, default = 0)\n" \ 42 " -p, --port <int> Port we should listen on (default = 9090)\n" \42 " -p, --port <int> Port we should listen on (default = %d)\n" \ 43 43 " -u, --upload <int> Maximum upload rate (-1 = no limit, default = 20)\n" 44 44 … … 47 47 static int showScrape = 0; 48 48 static int verboseLevel = 0; 49 static int bindPort = 9090;49 static int bindPort = TR_DEFAULT_PORT; 50 50 static int uploadLimit = 20; 51 51 static char * torrentPath = NULL; … … 67 67 if( parseCommandLine( argc, argv ) ) 68 68 { 69 printf( USAGE, argv[0] );69 printf( USAGE, argv[0], TR_DEFAULT_PORT ); 70 70 return 1; 71 71 } … … 73 73 if( showHelp ) 74 74 { 75 printf( USAGE, argv[0] );75 printf( USAGE, argv[0], TR_DEFAULT_PORT ); 76 76 return 0; 77 77 }
Note: See TracChangeset
for help on using the changeset viewer.