Changeset 269 for trunk/gtk/main.c


Ignore:
Timestamp:
May 31, 2006, 11:20:59 PM (16 years ago)
Author:
joshe
Message:

Wait and try to send a stopped event when removing a torrent.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/gtk/main.c

    r261 r269  
    6868  gboolean prefsopen;
    6969  GtkWidget *stupidpopuphack;
     70  gboolean closing;
    7071};
    7172
     
    117118void
    118119actionclick(GtkWidget *widget, gpointer gdata);
    119 void
    120 popupaction(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
    121             gpointer gdata);
    122120gint
    123121intrevcmp(gconstpointer a, gconstpointer b);
     
    302300  data->prefsopen = FALSE;
    303301  data->stupidpopuphack = NULL;
     302  data->closing = FALSE;
    304303
    305304  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_NEVER,
     
    460459  struct exitdata *edata;
    461460  unsigned int ii;
     461  GtkTreeIter iter;
     462  TrTorrent *tor;
     463
     464  data->closing = TRUE;
    462465
    463466  /* stop the update timer */
     
    466469  data->timer = 0;
    467470
    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 */
    469484  tr_backend_stop_torrents(data->back);
    470485
     
    773788  fixbuttons(NULL, data);
    774789
     790  /* check for politely stopped torrents unless we're exiting */
     791  if(!data->closing)
     792    tr_backend_torrents_stopped(data->back);
     793
    775794  return TRUE;
    776795}
     
    857876}
    858877
    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 
    869878void
    870879actionclick(GtkWidget *widget, gpointer gdata) {
    871880  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;
    883885  GtkTreePath *path;
    884886  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) {
    887894    case ACT_OPEN:
    888895      makeaddwind(data->wind, addtorrents, data);
     
    899906  }
    900907
    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)
    903919      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);
    916956    }
    917     gtk_tree_path_free(path);
     957    if(NULL != path)
     958      gtk_tree_path_free(path);
    918959    gtk_tree_row_reference_free(ii->data);
    919960  }
    920   g_list_free(info.dead);
    921 
    922   if(info.changed) {
     961  g_list_free(rows);
     962
     963  if(changed) {
    923964    savetorrents(data);
    924965    updatemodel(data);
    925966  }
    926 }
    927 
    928 void
    929 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);
    964967}
    965968
     
    10351038    gtk_list_store_set(GTK_LIST_STORE(data->model), &iter,
    10361039                       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);
    10371043    g_object_unref(ii->data);
    10381044  }
Note: See TracChangeset for help on using the changeset viewer.