Changeset 269
- Timestamp:
- May 31, 2006, 11:20:59 PM (17 years ago)
- Location:
- trunk/gtk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gtk/main.c
r261 r269 68 68 gboolean prefsopen; 69 69 GtkWidget *stupidpopuphack; 70 gboolean closing; 70 71 }; 71 72 … … 117 118 void 118 119 actionclick(GtkWidget *widget, gpointer gdata); 119 void120 popupaction(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,121 gpointer gdata);122 120 gint 123 121 intrevcmp(gconstpointer a, gconstpointer b); … … 302 300 data->prefsopen = FALSE; 303 301 data->stupidpopuphack = NULL; 302 data->closing = FALSE; 304 303 305 304 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_NEVER, … … 460 459 struct exitdata *edata; 461 460 unsigned int ii; 461 GtkTreeIter iter; 462 TrTorrent *tor; 463 464 data->closing = TRUE; 462 465 463 466 /* stop the update timer */ … … 466 469 data->timer = 0; 467 470 468 /* try to stop all the torrents */ 471 /* 472 Add a reference to all torrents in the list, which will be removed 473 when the politely-stopped signal is emitted. This is necessary 474 because actionclick() adds a reference when it removes a torrent 475 from the model and calls tr_torrent_stop_polite() on it. 476 */ 477 if(gtk_tree_model_get_iter_first(data->model, &iter)) { 478 do 479 gtk_tree_model_get(data->model, &iter, MC_TORRENT, &tor, -1); 480 while(gtk_tree_model_iter_next(data->model, &iter)); 481 } 482 483 /* try to politely stop all the torrents */ 469 484 tr_backend_stop_torrents(data->back); 470 485 … … 773 788 fixbuttons(NULL, data); 774 789 790 /* check for politely stopped torrents unless we're exiting */ 791 if(!data->closing) 792 tr_backend_torrents_stopped(data->back); 793 775 794 return TRUE; 776 795 } … … 857 876 } 858 877 859 struct actioninfo {860 GtkWindow *wind;861 enum listact act;862 unsigned int off;863 GtkTreeSelection *sel;864 TrBackend *back;865 gboolean changed;866 GList *dead;867 };868 869 878 void 870 879 actionclick(GtkWidget *widget, gpointer gdata) { 871 880 struct cbdata *data = gdata; 872 struct actioninfo info = { 873 data->wind, 874 GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), LIST_ACTION)), 875 0, 876 gtk_tree_view_get_selection(data->view), 877 data->back, 878 FALSE, 879 NULL, 880 }; 881 GtkTreeSelection *sel = gtk_tree_view_get_selection(data->view); 882 GList *ii; 881 enum listact act; 882 GtkTreeSelection *sel; 883 GList *rows, *ii; 884 GtkTreeRowReference *ref; 883 885 GtkTreePath *path; 884 886 GtkTreeIter iter; 885 886 switch(info.act) { 887 TrTorrent *tor; 888 unsigned int actoff, status; 889 gboolean changed; 890 891 act = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), LIST_ACTION)); 892 893 switch(act) { 887 894 case ACT_OPEN: 888 895 makeaddwind(data->wind, addtorrents, data); … … 899 906 } 900 907 901 for(info.off = 0; info.off < ALEN(actionitems); info.off++) 902 if(actionitems[info.off].act == info.act) 908 sel = gtk_tree_view_get_selection(data->view); 909 rows = gtk_tree_selection_get_selected_rows(sel, NULL); 910 911 for(ii = rows; NULL != ii; ii = ii->next) { 912 ref = gtk_tree_row_reference_new(data->model, ii->data); 913 gtk_tree_path_free(ii->data); 914 ii->data = ref; 915 } 916 917 for(actoff = 0; actoff < ALEN(actionitems); actoff++) 918 if(actionitems[actoff].act == act) 903 919 break; 904 g_assert(info.off < ALEN(actionitems)); 905 906 gtk_tree_selection_selected_foreach(sel, popupaction, &info); 907 908 for(ii = info.dead; NULL != ii; ii = ii->next) { 909 g_assert(gtk_tree_row_reference_valid(ii->data)); 910 path = gtk_tree_row_reference_get_path(ii->data); 911 gtk_tree_selection_unselect_path(info.sel, path); 912 if(gtk_tree_model_get_iter(data->model, &iter, path)) 913 gtk_list_store_remove(GTK_LIST_STORE(data->model), &iter); 914 else { 915 g_assert_not_reached(); 920 g_assert(actoff < ALEN(actionitems)); 921 922 changed = FALSE; 923 for(ii = rows; NULL != ii; ii = ii->next) { 924 if(NULL != (path = gtk_tree_row_reference_get_path(ii->data)) && 925 gtk_tree_model_get_iter(data->model, &iter, path)) { 926 gtk_tree_model_get(data->model, &iter, MC_TORRENT, &tor, 927 MC_STAT, &status, -1); 928 /* check if this action is valid for this torrent */ 929 if((!actionitems[actoff].avail || actionitems[actoff].avail & status) && 930 !actionitems[actoff].nomenu) { 931 switch(act) { 932 case ACT_START: 933 tr_torrentStart(tr_torrent_handle(tor)); 934 changed = TRUE; 935 break; 936 case ACT_STOP: 937 tr_torrentStop(tr_torrent_handle(tor)); 938 changed = TRUE; 939 break; 940 case ACT_DELETE: 941 /* tor will be unref'd in the politely_stopped signal handler */ 942 g_object_ref(tor); 943 tr_torrent_stop_politely(tor); 944 gtk_list_store_remove(GTK_LIST_STORE(data->model), &iter); 945 changed = TRUE; 946 break; 947 case ACT_INFO: 948 makeinfowind(data->wind, tor); 949 break; 950 case ACT_OPEN: 951 case ACT_PREF: 952 break; 953 } 954 } 955 g_object_unref(tor); 916 956 } 917 gtk_tree_path_free(path); 957 if(NULL != path) 958 gtk_tree_path_free(path); 918 959 gtk_tree_row_reference_free(ii->data); 919 960 } 920 g_list_free( info.dead);921 922 if( info.changed) {961 g_list_free(rows); 962 963 if(changed) { 923 964 savetorrents(data); 924 965 updatemodel(data); 925 966 } 926 }927 928 void929 popupaction(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,930 gpointer gdata) {931 struct actioninfo *in = gdata;932 TrTorrent *tor;933 int status;934 935 gtk_tree_model_get(model, iter, MC_TORRENT, &tor, MC_STAT, &status, -1);936 937 /* check if this action is valid for this torrent */938 if((!actionitems[in->off].avail || actionitems[in->off].avail & status) &&939 !actionitems[in->off].nomenu) {940 switch(in->act) {941 case ACT_START:942 tr_torrentStart(tr_torrent_handle(tor));943 in->changed = TRUE;944 break;945 case ACT_STOP:946 tr_torrentStop(tr_torrent_handle(tor));947 in->changed = TRUE;948 break;949 case ACT_DELETE:950 in->dead = g_list_append(in->dead,951 gtk_tree_row_reference_new(model, path));952 in->changed = TRUE;953 break;954 case ACT_INFO:955 makeinfowind(in->wind, tor);956 break;957 case ACT_OPEN:958 case ACT_PREF:959 break;960 }961 }962 963 g_object_unref(tor);964 967 } 965 968 … … 1035 1038 gtk_list_store_set(GTK_LIST_STORE(data->model), &iter, 1036 1039 MC_TORRENT, ii->data, -1); 1040 /* we will always ref a torrent before politely stopping it */ 1041 g_signal_connect(ii->data, "politely_stopped", 1042 G_CALLBACK(g_object_unref), data); 1037 1043 g_object_unref(ii->data); 1038 1044 } -
trunk/gtk/tr_backend.c
r261 r269 202 202 tr_backend_save_state(TrBackend *back, char **errstr) { 203 203 benc_val_t state; 204 int ii; 205 GList *jj; 204 GList *ii; 206 205 207 206 TR_IS_BACKEND(back); … … 209 208 bzero(&state, sizeof(state)); 210 209 state.type = TYPE_LIST; 211 state.val.l.alloc = state.val.l.count =g_list_length(back->torrents);210 state.val.l.alloc = g_list_length(back->torrents); 212 211 state.val.l.vals = g_new0(benc_val_t, state.val.l.alloc); 213 212 214 for(ii = 0, jj = back->torrents; NULL != jj; ii++, jj = jj->next) 215 tr_torrent_get_state(jj->data, state.val.l.vals + ii); 213 for(ii = back->torrents; NULL != ii; ii = ii->next) { 214 tr_torrent_get_state(ii->data, state.val.l.vals + state.val.l.count); 215 if(0 != state.val.l.vals[state.val.l.count].type) 216 state.val.l.count++; 217 } 216 218 217 219 cf_savestate(&state, errstr); … … 269 271 270 272 for(ii = back->torrents; NULL != ii; ii = ii->next) 271 if(TR_STATUS_ACTIVE & tr_torrent_stat(ii->data)->status) 272 tr_torrentStop(tr_torrent_handle(ii->data)); 273 tr_torrent_stop_politely(ii->data); 273 274 } 274 275 275 276 gboolean 276 277 tr_backend_torrents_stopped(TrBackend *back) { 277 GList *ii; 278 279 TR_IS_BACKEND(back); 280 281 for(ii = back->torrents; NULL != ii; ii = ii->next) 282 if(TR_STATUS_ACTIVE & tr_torrent_stat(ii->data)->status) 283 return FALSE; 284 285 return TRUE; 286 } 278 GList *ii, *list; 279 gboolean ret = TRUE; 280 281 TR_IS_BACKEND(back); 282 283 list = g_list_copy(back->torrents); 284 for(ii = list; NULL != ii; ii = ii->next) 285 if(!(TR_STATUS_PAUSE & tr_torrent_stat_polite(ii->data)->status)) 286 ret = FALSE; 287 g_list_free(list); 288 289 return ret; 290 } -
trunk/gtk/tr_torrent.c
r261 r269 91 91 tr_torrent_class_init(gpointer g_class, gpointer g_class_data SHUTUP) { 92 92 GObjectClass *gobject_class = G_OBJECT_CLASS(g_class); 93 //TrTorrentClass *klass = TR_TORRENT_CLASS(g_class);93 TrTorrentClass *klass = TR_TORRENT_CLASS(g_class); 94 94 GParamSpec *pspec; 95 95 … … 118 118 G_PARAM_READWRITE); 119 119 g_object_class_install_property(gobject_class, TR_TORRENT_PAUSED, pspec); 120 121 klass->paused_signal_id = g_signal_newv("politely-stopped", 122 G_TYPE_FROM_CLASS(g_class), 123 G_SIGNAL_RUN_LAST, NULL, NULL, NULL, 124 g_cclosure_marshal_VOID__VOID, 125 G_TYPE_NONE, 0, NULL); 120 126 } 121 127 … … 127 133 self->back = NULL; 128 134 self->dir = NULL; 135 self->closing = FALSE; 129 136 self->disposed = FALSE; 130 137 } … … 341 348 return; 342 349 350 if(tor->closing) 351 return; 352 343 353 state->type = TYPE_DICT; 344 354 state->val.l.vals = g_new0(benc_val_t, len); … … 379 389 return (TR_STATUS_INACTIVE & st->status ? TRUE : FALSE); 380 390 } 391 392 void 393 tr_torrent_stop_politely(TrTorrent *tor) { 394 tr_stat_t *st; 395 396 TR_IS_TORRENT(tor); 397 398 if(tor->disposed) 399 return; 400 401 if(!tor->closing) { 402 st = tr_torrent_stat(tor); 403 tor->closing = TRUE; 404 if(TR_STATUS_ACTIVE & st->status) 405 tr_torrentStop(tor->handle); 406 } 407 } 408 409 tr_stat_t * 410 tr_torrent_stat_polite(TrTorrent *tor) { 411 TrTorrentClass *klass; 412 tr_stat_t *st = tr_torrentStat(tor->handle); 413 414 if(tor->disposed) 415 return st; 416 417 if(tor->closing && TR_STATUS_PAUSE & st->status) { 418 tor->closing = FALSE; 419 klass = g_type_class_peek(TR_TORRENT_TYPE); 420 g_signal_emit(tor, klass->paused_signal_id, 0, NULL); 421 } 422 423 return st; 424 } -
trunk/gtk/tr_torrent.h
r261 r269 56 56 GObject *back; 57 57 char *dir; 58 gboolean closing; 58 59 gboolean disposed; 59 60 }; … … 61 62 struct _TrTorrentClass { 62 63 GObjectClass parent; 64 int paused_signal_id; 63 65 }; 64 66 … … 82 84 tr_torrent_new_with_state(GObject *backend, benc_val_t *state, char **err); 83 85 86 void 87 tr_torrent_stop_politely(TrTorrent *tor); 88 89 tr_stat_t * 90 tr_torrent_stat_polite(TrTorrent *tor); 91 84 92 #ifdef TR_WANT_TORRENT_PRIVATE 85 93 void
Note: See TracChangeset
for help on using the changeset viewer.