Changeset 5989
- Timestamp:
- Jun 1, 2008, 5:36:23 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/cli/transmissioncli.c
r5971 r5989 177 177 int err; 178 178 tr_metainfo_builder * builder = tr_metaInfoBuilderCreate( h, sourceFile ); 179 tr_makeMetaInfo( builder, torrentPath, announce, comment, isPrivate ); 179 tr_tracker_info ti; 180 ti.tier = 0; 181 ti.announce = announce; 182 tr_makeMetaInfo( builder, torrentPath, &ti, 1, comment, isPrivate ); 180 183 while( !builder->isDone ) { 181 184 tr_wait( 1000 ); -
trunk/gtk/Makefile.am
r5868 r5989 32 32 sexy-icon-entry.h \ 33 33 torrent-cell-renderer.h \ 34 tracker-list.h \ 34 35 tr-core.h \ 35 36 tr-core-dbus.h \ … … 59 60 stats.c \ 60 61 torrent-cell-renderer.c \ 62 tracker-list.c \ 61 63 tr-core.c \ 62 64 tr-icon.c \ -
trunk/gtk/details.c
r5987 r5989 25 25 #include "file-list.h" 26 26 #include "tr-torrent.h" 27 #include "tracker-list.h" 27 28 #include "hig.h" 28 29 #include "util.h" … … 1100 1101 }; 1101 1102 1102 enum1103 {1104 TR_COL_TIER,1105 TR_COL_ANNOUNCE,1106 TR_N_COLS1107 };1108 1109 static void1110 setTrackerChangeState( struct tracker_page * page, gboolean changed )1111 {1112 gtk_widget_set_sensitive( page->save_button, changed );1113 gtk_widget_set_sensitive( page->revert_button, changed );1114 }1115 1116 static GtkTreeModel*1117 tracker_model_new( tr_torrent * tor )1118 {1119 int i;1120 const tr_info * inf = tr_torrentInfo( tor );1121 GtkListStore * store = gtk_list_store_new( TR_N_COLS, G_TYPE_INT, G_TYPE_STRING );1122 1123 for( i=0; i<inf->trackerCount; ++i )1124 {1125 GtkTreeIter iter;1126 const tr_tracker_info * tinf = inf->trackers + i;1127 gtk_list_store_append( store, &iter );1128 gtk_list_store_set( store, &iter, TR_COL_TIER, tinf->tier + 1,1129 TR_COL_ANNOUNCE, tinf->announce,1130 -1 );1131 }1132 1133 gtk_tree_sortable_set_sort_column_id( GTK_TREE_SORTABLE( store ),1134 TR_COL_TIER,1135 GTK_SORT_ASCENDING );1136 1137 return GTK_TREE_MODEL( store );1138 }1139 1140 static void1141 onTrackerSelectionChanged( GtkTreeSelection * sel,1142 gpointer gpage )1143 {1144 struct tracker_page * page = gpage;1145 gboolean has_selection = gtk_tree_selection_get_selected( sel, NULL, NULL );1146 gtk_widget_set_sensitive( page->remove_button, has_selection );1147 }1148 1149 static void1150 onTrackerRemoveClicked( GtkButton * w UNUSED, gpointer gpage )1151 {1152 struct tracker_page * page = gpage;1153 GtkTreeIter iter;1154 if( gtk_tree_selection_get_selected( page->sel, NULL, &iter ) ) {1155 gtk_list_store_remove( page->store, &iter );1156 setTrackerChangeState( page, TRUE );1157 }1158 }1159 1160 static void1161 onTrackerAddClicked( GtkButton * w UNUSED, gpointer gpage )1162 {1163 GtkTreeIter iter;1164 struct tracker_page * page = gpage;1165 GtkTreePath * path;1166 gtk_list_store_append( page->store, &iter );1167 setTrackerChangeState( page, TRUE );1168 gtk_list_store_set( page->store, &iter, TR_COL_TIER, 1,1169 TR_COL_ANNOUNCE, _( "Announce URL" ),1170 -1 );1171 path = gtk_tree_model_get_path( GTK_TREE_MODEL( page->store ), &iter );1172 gtk_tree_view_set_cursor( page->view,1173 path,1174 gtk_tree_view_get_column( page->view, TR_COL_ANNOUNCE ),1175 TRUE );1176 gtk_tree_path_free( path );1177 }1178 1179 static void1180 onTrackerSaveClicked( GtkButton * w UNUSED, gpointer gpage )1181 {1182 struct tracker_page * page = gpage;1183 GtkTreeModel * model = GTK_TREE_MODEL( page->store );1184 const int n = gtk_tree_model_iter_n_children( model, NULL );1185 1186 if( n > 0 ) /* must have at least one tracker */1187 {1188 int i = 0;1189 GtkTreeIter iter;1190 tr_tracker_info * trackers;1191 1192 /* build the tracker list */1193 trackers = g_new0( tr_tracker_info, n );1194 if( gtk_tree_model_get_iter_first( model, &iter ) ) do {1195 gtk_tree_model_get( model, &iter, TR_COL_TIER, &trackers[i].tier,1196 TR_COL_ANNOUNCE, &trackers[i].announce,1197 -1 );1198 ++i;1199 } while( gtk_tree_model_iter_next( model, &iter ) );1200 g_assert( i == n );1201 1202 /* set the tracker list */1203 tr_torrentSetAnnounceList( tr_torrent_handle( page->gtor ),1204 trackers, n );1205 1206 1207 setTrackerChangeState( page, FALSE );1208 1209 /* cleanup */1210 for( i=0; i<n; ++i )1211 g_free( trackers[i].announce );1212 g_free( trackers );1213 }1214 }1215 1216 static void1217 onTrackerRevertClicked( GtkButton * w UNUSED, gpointer gpage )1218 {1219 struct tracker_page * page = gpage;1220 GtkTreeModel * model = tracker_model_new( tr_torrent_handle( page->gtor ) );1221 gtk_tree_view_set_model( page->view, model );1222 page->store = GTK_LIST_STORE( model );1223 g_object_unref( G_OBJECT( model ) );1224 setTrackerChangeState( page, FALSE );1225 }1226 1227 static void1228 onAnnounceEdited( GtkCellRendererText * renderer UNUSED,1229 gchar * path_string,1230 gchar * new_text,1231 gpointer gpage )1232 {1233 struct tracker_page * page = gpage;1234 GtkTreeModel * model = GTK_TREE_MODEL( page->store );1235 GtkTreeIter iter;1236 GtkTreePath * path = gtk_tree_path_new_from_string( path_string ) ;1237 if( gtk_tree_model_get_iter( model, &iter, path ) )1238 {1239 char * old_text;1240 gtk_tree_model_get( model, &iter, TR_COL_ANNOUNCE, &old_text, -1 );1241 if( tr_httpIsValidURL( new_text ) )1242 {1243 if( strcmp( old_text, new_text ) )1244 {1245 gtk_list_store_set( page->store, &iter, TR_COL_ANNOUNCE, new_text, -1 );1246 setTrackerChangeState( page, TRUE );1247 }1248 }1249 else if( !tr_httpIsValidURL( old_text ) )1250 {1251 /* both old and new are invalid...1252 they must've typed in an invalid URL1253 after hitting the "Add" button */1254 onTrackerRemoveClicked( NULL, page );1255 setTrackerChangeState( page, TRUE );1256 }1257 g_free( old_text );1258 }1259 gtk_tree_path_free( path );1260 }1261 1262 static void1263 onTierEdited( GtkCellRendererText * renderer UNUSED,1264 gchar * path_string,1265 gchar * new_text,1266 gpointer gpage )1267 {1268 struct tracker_page * page = gpage;1269 GtkTreeModel * model = GTK_TREE_MODEL( page->store );1270 GtkTreeIter iter;1271 GtkTreePath * path;1272 char * end;1273 int new_tier;1274 1275 errno = 0;1276 new_tier = strtol( new_text, &end, 10 );1277 if( new_tier<1 || *end || errno )1278 return;1279 1280 path = gtk_tree_path_new_from_string( path_string ) ;1281 if( gtk_tree_model_get_iter( model, &iter, path ) )1282 {1283 int old_tier;1284 gtk_tree_model_get( model, &iter, TR_COL_TIER, &old_tier, -1 );1285 if( old_tier != new_tier )1286 {1287 gtk_list_store_set( page->store, &iter, TR_COL_TIER, new_tier, -1 );1288 setTrackerChangeState( page, TRUE );1289 }1290 }1291 gtk_tree_path_free( path );1292 }1293 1294 1103 GtkWidget* 1295 1104 tracker_page_new( TrTorrent * gtor ) … … 1298 1107 GtkWidget * l; 1299 1108 GtkWidget * w; 1300 GtkWidget * h;1301 GtkWidget * v;1302 GtkWidget * fr;1303 1109 int row = 0; 1304 1110 const char * s; 1305 GtkTreeModel * m;1306 GtkCellRenderer * r;1307 GtkTreeViewColumn * c;1308 GtkTreeSelection * sel;1309 1111 struct tracker_page * page = g_new0( struct tracker_page, 1 ); 1310 1112 const tr_info * info = tr_torrent_info (gtor); … … 1315 1117 hig_workarea_add_section_title( t, &row, _( "Trackers" ) ); 1316 1118 1317 h = gtk_hbox_new( FALSE, GUI_PAD ); 1318 m = tracker_model_new( tr_torrent_handle( gtor ) ); 1319 page->store = GTK_LIST_STORE( m ); 1320 w = gtk_tree_view_new_with_model( m ); 1321 page->view = GTK_TREE_VIEW( w ); 1322 gtk_tree_view_set_enable_search( page->view, FALSE ); 1323 r = gtk_cell_renderer_text_new( ); 1324 g_object_set( G_OBJECT( r ), 1325 "editable", TRUE, 1326 NULL ); 1327 g_signal_connect( r, "edited", 1328 G_CALLBACK( onTierEdited ), page ); 1329 c = gtk_tree_view_column_new_with_attributes( _( "Tier" ), r, 1330 "text", TR_COL_TIER, 1331 NULL ); 1332 gtk_tree_view_column_set_sort_column_id( c, TR_COL_TIER ); 1333 gtk_tree_view_append_column( page->view, c ); 1334 r = gtk_cell_renderer_text_new( ); 1335 g_object_set( G_OBJECT( r ), 1336 "editable", TRUE, 1337 "ellipsize", PANGO_ELLIPSIZE_END, 1338 NULL ); 1339 g_signal_connect( r, "edited", 1340 G_CALLBACK( onAnnounceEdited ), page ); 1341 c = gtk_tree_view_column_new_with_attributes( _( "Announce URL" ), r, 1342 "text", TR_COL_ANNOUNCE, 1343 NULL ); 1344 gtk_tree_view_column_set_sort_column_id( c, TR_COL_ANNOUNCE ); 1345 gtk_tree_view_append_column( page->view, c ); 1346 w = gtk_scrolled_window_new( NULL, NULL ); 1347 gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( w ), 1348 GTK_POLICY_NEVER, 1349 GTK_POLICY_AUTOMATIC ); 1350 sel = gtk_tree_view_get_selection( page->view ); 1351 page->sel = sel; 1352 g_signal_connect( sel, "changed", 1353 G_CALLBACK( onTrackerSelectionChanged ), page ); 1354 gtk_container_add( GTK_CONTAINER( w ), GTK_WIDGET( page->view ) ); 1355 gtk_widget_set_size_request( w, -1, 133 ); 1356 fr = gtk_frame_new( NULL ); 1357 gtk_frame_set_shadow_type( GTK_FRAME( fr ), GTK_SHADOW_IN ); 1358 gtk_container_add( GTK_CONTAINER( fr ), w ); 1359 gtk_box_pack_start_defaults( GTK_BOX( h ), fr ); 1360 g_object_unref( G_OBJECT( m ) ); 1361 1362 v = gtk_vbox_new( TRUE, GUI_PAD_SMALL ); 1363 w = gtk_button_new_from_stock( GTK_STOCK_ADD ); 1364 g_signal_connect( w, "clicked", G_CALLBACK( onTrackerAddClicked ), page ); 1365 gtk_box_pack_start( GTK_BOX( v ), w, FALSE, FALSE, 0 ); 1366 page->add_button = w; 1367 w = gtk_button_new_from_stock( GTK_STOCK_REMOVE ); 1368 g_signal_connect( w, "clicked", G_CALLBACK( onTrackerRemoveClicked ), page ); 1369 gtk_box_pack_start( GTK_BOX( v ), w, FALSE, FALSE, 0 ); 1370 page->remove_button = w; 1371 w = gtk_button_new_from_stock( GTK_STOCK_SAVE ); 1372 g_signal_connect( w, "clicked", G_CALLBACK( onTrackerSaveClicked ), page ); 1373 gtk_widget_set_sensitive( w, FALSE ); 1374 gtk_box_pack_start( GTK_BOX( v ), w, FALSE, FALSE, 0 ); 1375 page->save_button = w; 1376 w = gtk_button_new_from_stock( GTK_STOCK_REVERT_TO_SAVED ); 1377 g_signal_connect( w, "clicked", G_CALLBACK( onTrackerRevertClicked ), page ); 1378 gtk_widget_set_sensitive( w, FALSE ); 1379 gtk_box_pack_start( GTK_BOX( v ), w, FALSE, FALSE, 0 ); 1380 page->revert_button = w; 1381 gtk_box_pack_start( GTK_BOX( h ), v, FALSE, FALSE, 0 ); 1382 1383 hig_workarea_add_wide_control( t, &row, h ); 1384 onTrackerSelectionChanged( sel, page ); 1119 w = tracker_list_new( gtor, GTK_POS_RIGHT ); 1120 hig_workarea_add_wide_control( t, &row, w ); 1385 1121 1386 1122 hig_workarea_add_section_divider( t, &row ); -
trunk/gtk/makemeta-ui.c
r5765 r5989 21 21 #include "hig.h" 22 22 #include "makemeta-ui.h" 23 #include "tracker-list.h" 23 24 #include "util.h" 24 25 … … 32 33 GtkWidget * size_lb; 33 34 GtkWidget * pieces_lb; 34 GtkWidget * announce_ entry;35 GtkWidget * announce_list; 35 36 GtkWidget * comment_entry; 36 37 GtkWidget * progressbar; … … 146 147 char buf[1024]; 147 148 guint tag; 149 tr_tracker_info * trackers = NULL; 150 int i; 151 int trackerCount = 0; 148 152 149 153 if( response != GTK_RESPONSE_ACCEPT ) … … 178 182 g_free( tmp ); 179 183 184 trackers = tracker_list_get_trackers( ui->announce_list, &trackerCount ); 185 180 186 tr_makeMetaInfo( ui->builder, 181 187 NULL, 182 gtk_entry_get_text( GTK_ENTRY( ui->announce_entry ) ),188 trackers, trackerCount, 183 189 gtk_entry_get_text( GTK_ENTRY( ui->comment_entry ) ), 184 190 gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( ui->private_check ) ) ); … … 186 192 tag = g_timeout_add (UPDATE_INTERVAL_MSEC, refresh_cb, ui); 187 193 g_object_set_data_full (G_OBJECT(d), "tag", GUINT_TO_POINTER(tag), remove_tag); 194 195 /* cleanup */ 196 for( i=0; i<trackerCount; ++i ) 197 g_free( trackers[i].announce ); 198 g_free( trackers ); 188 199 } 189 200 … … 321 332 322 333 hig_workarea_add_section_divider( t, &row ); 323 hig_workarea_add_section_title (t, &row, _(" Details"));334 hig_workarea_add_section_title (t, &row, _("Tracker")); 324 335 325 336 w = ui->private_check = hig_workarea_add_wide_checkbutton( t, &row, _( "_Private to this tracker" ), FALSE ); 326 337 327 w = ui->announce_entry = gtk_entry_new( ); 328 gtk_entry_set_text(GTK_ENTRY(w), "http://"); 329 hig_workarea_add_row (t, &row, _( "Announce _URL:" ), w, NULL ); 338 w = tracker_list_new( NULL, GTK_POS_LEFT ); 339 ui->announce_list = w; 340 hig_workarea_add_wide_control (t, &row, w ); 341 342 hig_workarea_add_section_divider( t, &row ); 343 hig_workarea_add_section_title (t, &row, _("Optional Information")); 330 344 331 345 w = ui->comment_entry = gtk_entry_new( ); -
trunk/gtk/tr-torrent.c
r5947 r5989 61 61 62 62 static int 63 isDisposed( const TrTorrent * self)64 { 65 return ! self || !self->priv;63 isDisposed( const TrTorrent * tor ) 64 { 65 return !tor || !TR_IS_TORRENT( tor ) || !tor->priv; 66 66 } 67 67 … … 124 124 tr_torrent_handle(TrTorrent *tor) 125 125 { 126 g_assert( TR_IS_TORRENT(tor) );127 128 126 return isDisposed( tor ) ? NULL : tor->priv->handle; 129 127 } -
trunk/libtransmission/makemeta.c
r5953 r5989 169 169 if( builder ) 170 170 { 171 uint32_t i; 172 for( i=0; i<builder->fileCount; ++i ) 173 tr_free( builder->files[i].filename ); 171 tr_file_index_t t; 172 int i; 173 for( t=0; t<builder->fileCount; ++t ) 174 tr_free( builder->files[t].filename ); 174 175 tr_free( builder->files ); 175 176 tr_free( builder->top ); 176 177 tr_free( builder->comment ); 177 tr_free( builder->announce ); 178 for( i=0; i<builder->trackerCount; ++i ) 179 tr_free( builder->trackers[i].announce ); 180 tr_free( builder->trackers ); 178 181 tr_free( builder->outputFile ); 179 182 tr_free( builder ); … … 342 345 tr_realMakeMetaInfo ( tr_metainfo_builder * builder ) 343 346 { 344 int n = 5;347 int i; 345 348 tr_benc top; 346 const char * ann = builder->announce; 347 348 if ( builder->comment && *builder->comment ) ++n; 349 tr_bencInitDict( &top, n ); 350 351 tr_bencDictAddStr( &top, "announce", ann ); 352 353 /* if a URL was entered but it's invalid, don't allow it. #814, #971 */ 354 if( ann && *ann && !tr_httpIsValidURL( ann ) ) 355 builder->result = TR_MAKEMETA_URL; 349 350 /* allow an empty set, but if URLs *are* listed, verify them. #814, #971 */ 351 for( i=0; i<builder->trackerCount && !builder->result; ++i ) 352 if( !tr_httpIsValidURL( builder->trackers[i].announce ) ) 353 builder->result = TR_MAKEMETA_URL; 354 355 tr_bencInitDict( &top, 6 ); 356 357 if( !builder->result && builder->trackerCount ) 358 { 359 int prevTier = -1; 360 tr_benc * tier = NULL; 361 tr_benc * announceList; 362 363 announceList = tr_bencDictAddList( &top, "announce-list", 0 ); 364 for( i=0; i<builder->trackerCount; ++i ) { 365 if( prevTier != builder->trackers[i].tier ) { 366 prevTier = builder->trackers[i].tier; 367 tier = tr_bencListAddList( announceList, 0 ); 368 } 369 tr_bencListAddStr( tier, builder->trackers[i].announce ); 370 } 371 372 tr_bencDictAddStr( &top, "announce", builder->trackers[0].announce ); 373 } 356 374 357 375 if( !builder->result && !builder->abortFlag ) … … 375 393 376 394 /* cleanup */ 377 tr_bencFree( & 395 tr_bencFree( &top ); 378 396 if( builder->abortFlag ) 379 397 builder->result = TR_MAKEMETA_CANCELLED; … … 431 449 432 450 void 433 tr_makeMetaInfo( tr_metainfo_builder * builder, 434 const char * outputFile, 435 const char * announce, 436 const char * comment, 437 int isPrivate ) 438 { 451 tr_makeMetaInfo( tr_metainfo_builder * builder, 452 const char * outputFile, 453 const tr_tracker_info * trackers, 454 int trackerCount, 455 const char * comment, 456 int isPrivate ) 457 { 458 int i; 439 459 tr_lock * lock; 440 460 441 461 /* free any variables from a previous run */ 442 tr_free( builder->announce ); 462 for( i=0; i<builder->trackerCount; ++i ) 463 tr_free( builder->trackers[i].announce ); 464 tr_free( builder->trackers ); 443 465 tr_free( builder->comment ); 444 466 tr_free( builder->outputFile ); … … 447 469 builder->abortFlag = 0; 448 470 builder->isDone = 0; 449 builder->announce = tr_strdup( announce ); 471 builder->trackerCount = trackerCount; 472 builder->trackers = tr_new0( tr_tracker_info, builder->trackerCount ); 473 for( i=0; i<builder->trackerCount; ++i ) { 474 builder->trackers[i].tier = trackers[i].tier; 475 builder->trackers[i].announce = tr_strdup( trackers[i].announce ); 476 } 450 477 builder->comment = tr_strdup( comment ); 451 478 builder->isPrivate = isPrivate; -
trunk/libtransmission/makemeta.h
r5358 r5989 55 55 **/ 56 56 57 char * announce; 57 tr_tracker_info * trackers; 58 int trackerCount; 58 59 char * comment; 59 60 char * outputFile; … … 96 97 97 98 /** 98 * 'outputFile' if NULL, builder->top + ".torrent" will be used.99 * @brief create a new .torrent file 99 100 * 100 101 * This is actually done in a worker thread, not the main thread! … … 104 105 * from time to time! When the worker thread sets that flag, 105 106 * the caller must pass the builder to tr_metaInfoBuilderFree(). 107 * 108 * @param outputFile if NULL, builder->top + ".torrent" will be used. 109 110 * @param trackers An array of trackers, sorted by tier from first to last. 111 * NOTE: only the `tier' and `announce' fields are used. 112 * 113 * @param trackerCount size of the `trackers' array 106 114 */ 107 115 void 108 tr_makeMetaInfo( tr_metainfo_builder * builder, 109 const char * outputFile, 110 const char * announce, 111 const char * comment, 112 int isPrivate ); 116 tr_makeMetaInfo( tr_metainfo_builder * builder, 117 const char * outputFile, 118 const tr_tracker_info * trackers, 119 int trackerCount, 120 const char * comment, 121 int isPrivate ); 113 122 114 123
Note: See TracChangeset
for help on using the changeset viewer.