Changeset 22


Ignore:
Timestamp:
Jan 12, 2006, 7:00:58 PM (15 years ago)
Author:
root
Message:

Update 2005-12-27

Location:
trunk/gtk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/gtk/main.c

    r20 r22  
    9999listpopup(GtkWidget *widget, gpointer gdata);
    100100void
    101 dopopupmenu(GdkEventButton *event, struct cbdata *data, GtkTreeIter *iter);
     101dopopupmenu(GdkEventButton *event, struct cbdata *data,
     102            GList *ids, int status);
     103void
     104killmenu(GtkWidget *menu, gpointer *gdata SHUTUP);
    102105void
    103106actionclick(GtkWidget *widget, gpointer gdata);
     107void
     108doubleclick(GtkWidget *widget, GtkTreePath *path, GtkTreeViewColumn *col,
     109            gpointer gdata);
    104110
    105111gboolean
     
    108114void
    109115addedtorrents(void *vdata);
    110 const char *
    111 statusstr(int status);
    112 void
    113 makeinfowind(struct cbdata *data, int index);
    114116gboolean
    115117savetorrents(tr_handle_t *tr, GtkWindow *wind, int count, tr_stat_t *stat);
     118void
     119orstatus(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
     120         gpointer gdata);
     121void
     122makeidlist(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
     123           gpointer gdata);
    116124
    117125#define TR_TYPE_PIECES_NAME     "tr-type-pieces"
     
    125133enum listfrom { FROM_BUTTON, FROM_POPUP };
    126134
    127 #define LIST_INDEX            "torrent-list-index"
     135#define LIST_INDEX            "torrent-list-indexes"
     136#define LIST_MENU_WIDGET      "torrent-list-popup-menu-widget"
    128137
    129138struct { const gchar *name; const gchar *id; enum listact act; gboolean nomenu;
     
    446455  gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(view), TRUE);
    447456  sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
    448   gtk_tree_selection_set_mode(GTK_TREE_SELECTION(sel), GTK_SELECTION_SINGLE);
     457  gtk_tree_selection_set_mode(GTK_TREE_SELECTION(sel), GTK_SELECTION_MULTIPLE);
    449458  g_signal_connect(G_OBJECT(sel), "changed", G_CALLBACK(fixbuttons), data);
    450459  g_signal_connect(G_OBJECT(view), "button-press-event",
    451460                   G_CALLBACK(listclick), data);
    452461  g_signal_connect(G_OBJECT(view), "popup-menu", G_CALLBACK(listpopup), data);
     462  g_signal_connect(G_OBJECT(view), "row-activated",
     463                   G_CALLBACK(doubleclick), data);
    453464  gtk_widget_show_all(view);
    454465
     
    469480fixbuttons(GtkTreeSelection *sel, gpointer gdata) {
    470481  struct cbdata *data = gdata;
    471   GtkTreeModel *model;
    472   GtkTreeIter iter;
    473482  gboolean selected;
    474483  unsigned int ii;
     
    477486  if(NULL == sel)
    478487    sel = gtk_tree_view_get_selection(data->view);
    479   if((selected = gtk_tree_selection_get_selected(sel, &model, &iter)))
    480     gtk_tree_model_get(model, &iter, MC_STAT, &status, -1);
     488  status = 0;
     489  gtk_tree_selection_selected_foreach(sel, orstatus, &status);
     490  selected = (0 < gtk_tree_selection_count_selected_rows(sel));
    481491
    482492  for(ii = 0; ii < ALEN(actionitems); ii++)
     
    620630}
    621631
     632/* show a popup menu for a right-click on the list */
    622633gboolean
    623634listclick(GtkWidget *widget SHUTUP, GdkEventButton *event, gpointer gdata) {
    624635  struct cbdata *data = gdata;
     636  GtkTreeSelection *sel = gtk_tree_view_get_selection(data->view);
    625637  GtkTreePath *path;
    626638  GtkTreeIter iter;
     639  int index, status;
     640  GList *ids;
    627641
    628642  if(GDK_BUTTON_PRESS == event->type && 3 == event->button) {
     643    /* find what row, if any, the user clicked on */
    629644    if(!gtk_tree_view_get_path_at_pos(data->view, event->x, event->y, &path,
    630645                                      NULL, NULL, NULL))
    631       dopopupmenu(event, data, NULL);
     646      /* no row was clicked, do the popup with no torrent IDs or status */
     647      dopopupmenu(event, data, NULL, 0);
    632648    else {
    633       if(gtk_tree_model_get_iter(GTK_TREE_MODEL(data->model), &iter, path))
    634         dopopupmenu(event, data, &iter);
     649      if(gtk_tree_model_get_iter(GTK_TREE_MODEL(data->model), &iter, path)) {
     650        /* get ID and status for the right-clicked row */
     651        gtk_tree_model_get(GTK_TREE_MODEL(data->model), &iter,
     652                           MC_ROW_INDEX, &index, MC_STAT, &status, -1);
     653        /* get a list of selected IDs */
     654        ids = NULL;
     655        gtk_tree_selection_selected_foreach(sel, makeidlist, &ids);
     656        /* is the clicked row selected? */
     657        if(NULL == g_list_find(ids, GINT_TO_POINTER(index))) {
     658          /* no, do the popup for just the clicked row */
     659          g_list_free(ids);
     660          dopopupmenu(event, data, g_list_append(NULL, GINT_TO_POINTER(index)),
     661                      status);
     662        } else {
     663          /* yes, do the popup for all the selected rows */
     664          gtk_tree_selection_selected_foreach(sel, orstatus, &status);
     665          dopopupmenu(event, data, ids, status);
     666        }
     667      }
    635668      gtk_tree_path_free(path);
    636669    }
     
    646679  GtkTreeSelection *sel = gtk_tree_view_get_selection(data->view);
    647680  GtkTreeModel *model;
    648   GtkTreeIter iter;
    649 
    650   if(!gtk_tree_selection_get_selected(sel, &model, &iter))
    651     dopopupmenu(NULL, data, NULL);
     681  GList *ids;
     682  int status;
     683
     684  if(0 >= gtk_tree_selection_count_selected_rows(sel))
     685    dopopupmenu(NULL, data, NULL, 0);
    652686  else {
    653687    assert(model == GTK_TREE_MODEL(data->model));
    654     dopopupmenu(NULL, data, &iter);
     688    status = 0;
     689    gtk_tree_selection_selected_foreach(sel, orstatus, &status);
     690    ids = NULL;
     691    gtk_tree_selection_selected_foreach(sel, makeidlist, &ids);
     692    dopopupmenu(NULL, data, ids, status);
    655693  }
    656694
     
    659697
    660698void
    661 dopopupmenu(GdkEventButton *event, struct cbdata *data, GtkTreeIter *iter) {
     699dopopupmenu(GdkEventButton *event, struct cbdata *data,
     700            GList *ids, int status) {
    662701  GtkWidget *menu = gtk_menu_new();
    663702  GtkWidget *item;
    664703  unsigned int ii;
    665   int index, status;
    666 
    667   index = -1;
    668   if(NULL != iter)
    669     gtk_tree_model_get(GTK_TREE_MODEL(data->model), iter,
    670                        MC_ROW_INDEX, &index, MC_STAT, &status, -1);
    671 
    672   /* XXX am I leaking references here? */
     704
    673705  for(ii = 0; ii < ALEN(actionitems); ii++) {
    674706    if(actionitems[ii].nomenu ||
    675707       (actionitems[ii].avail &&
    676         (0 > index || !(actionitems[ii].avail & status))))
     708        (NULL == ids || !(actionitems[ii].avail & status))))
    677709      continue;
    678710    item = gtk_menu_item_new_with_label(actionitems[ii].name);
     711    /* set the action for the menu item */
    679712    g_object_set_data(G_OBJECT(item), LIST_ACTION,
    680713                      GINT_TO_POINTER(actionitems[ii].act));
     714    /* show that this action came from a popup menu */
    681715    g_object_set_data(G_OBJECT(item), LIST_ACTION_FROM,
    682716                      GINT_TO_POINTER(FROM_POPUP));
    683     g_object_set_data(G_OBJECT(item), LIST_INDEX, GINT_TO_POINTER(index));
     717    /* set a glist of selected torrent's IDs */
     718    g_object_set_data(G_OBJECT(item), LIST_INDEX, ids);
     719    /* set the menu widget, so the activate handler can destroy it */
     720    g_object_set_data(G_OBJECT(item), LIST_MENU_WIDGET, menu);
    684721    g_signal_connect(G_OBJECT(item), "activate",
    685722                     G_CALLBACK(actionclick), data);
     
    687724  }
    688725
     726  /* set up the glist to be freed when the menu is destroyed */
     727  g_object_set_data_full(G_OBJECT(menu), LIST_INDEX, ids,
     728                         (GDestroyNotify)g_list_free);
     729
     730  /* destroy the menu if the user doesn't select anything */
     731  g_signal_connect(menu, "selection-done", G_CALLBACK(killmenu), NULL);
     732
    689733  gtk_widget_show_all(menu);
    690734
     
    695739
    696740void
     741killmenu(GtkWidget *menu, gpointer *gdata SHUTUP) {
     742  gtk_widget_destroy(menu);
     743}
     744
     745void
    697746actionclick(GtkWidget *widget, gpointer gdata) {
    698747  struct cbdata *data = gdata;
    699748  GtkTreeSelection *sel = gtk_tree_view_get_selection(data->view);
    700   GtkTreeModel *model;
    701   GtkTreeIter iter;
    702749  enum listact act =
    703750    GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), LIST_ACTION));
    704751  enum listfrom from =
    705752    GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), LIST_ACTION_FROM));
    706   int index;
     753  int index, count;
     754  unsigned int actindex;
    707755  tr_stat_t *sb;
     756  GList *ids, *ii;
     757  gboolean updatesave;
     758
     759  /* destroy the popup menu, if any */
     760  if(FROM_POPUP == from)
     761    gtk_widget_destroy(g_object_get_data(G_OBJECT(widget), LIST_MENU_WIDGET));
    708762
    709763  switch(act) {
     
    718772  }
    719773
    720   index = -1;
    721774  switch(from) {
    722775    case FROM_BUTTON:
    723       if(gtk_tree_selection_get_selected(sel, &model, &iter))
    724         gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
    725                            MC_ROW_INDEX, &index, -1);
     776      ids = NULL;
     777      gtk_tree_selection_selected_foreach(sel, makeidlist, &ids);
    726778      /* XXX should I assert(0 <= index) to insure a row was selected? */
    727779      break;
    728780    case FROM_POPUP:
    729       index = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), LIST_INDEX));
     781      ids = g_object_get_data(G_OBJECT(widget), LIST_INDEX);
    730782      break;
    731783    default:
     
    734786  }
    735787
    736   if(0 <= index) {
     788  for(actindex = 0; actindex < ALEN(actionitems); actindex++)
     789    if(actionitems[actindex].act == act)
     790      break;
     791  assert(actindex < ALEN(actionitems));
     792
     793  updatesave = FALSE;
     794  count = tr_torrentStat(data->tr, &sb);
     795
     796  for(ii = g_list_first(ids); NULL != ii; ii = ii->next) {
     797    index = GPOINTER_TO_INT(ii->data);
     798    if(index >= count) {
     799      assert(!"illegal torrent id");
     800      continue;
     801    }
     802    /* check if this action is valid for this torrent */
     803    if(actionitems[actindex].nomenu ||
     804       (actionitems[actindex].avail &&
     805        !(actionitems[actindex].avail & sb[index].status)))
     806      continue;
     807
    737808    switch(act) {
    738809      case ACT_START:
    739         tr_torrentStart(data->tr, index);
    740         savetorrents(data->tr, data->wind, -1, NULL);
    741         updatemodel(data);
     810        if(TR_STATUS_STOPPING & sb[index].status)
     811          fprintf(stderr, "XXX still running\n");
     812        else
     813          tr_torrentStart(data->tr, index);
     814        updatesave = TRUE;
    742815        break;
    743816      case ACT_STOP:
    744817        tr_torrentStop(data->tr, index);
    745         savetorrents(data->tr, data->wind, -1, NULL);
    746         updatemodel(data);
     818        updatesave = TRUE;
    747819        break;
    748820      case ACT_DELETE:
    749         /* XXX need to be able to stat just one torrent */
    750         if(index >= tr_torrentStat(data->tr, &sb)) {
    751           assert(!"XXX i'm tired");
    752         }
    753821        if(TR_TORRENT_NEEDS_STOP(sb[index].status))
    754822          tr_torrentStop(data->tr, index);
    755         free(sb);
    756823        tr_torrentClose(data->tr, index);
    757         savetorrents(data->tr, data->wind, -1, NULL);
    758         updatemodel(data);
     824        updatesave = TRUE;
    759825        break;
    760826      case ACT_INFO:
    761         makeinfowind(data, index);
     827        makeinfowind(data->wind, data->tr, index);
    762828        break;
    763829      default:
     
    765831        break;
    766832    }
     833  }
     834  free(sb);
     835
     836  if(updatesave) {
     837    savetorrents(data->tr, data->wind, -1, NULL);
     838    updatemodel(data);
     839  }
     840
     841  if(FROM_BUTTON == from)
     842    g_list_free(ids);
     843}
     844
     845void
     846doubleclick(GtkWidget *widget SHUTUP, GtkTreePath *path,
     847            GtkTreeViewColumn *col SHUTUP, gpointer gdata) {
     848  struct cbdata *data = gdata;
     849  GtkTreeIter iter;
     850  int index;
     851
     852  if(gtk_tree_model_get_iter(GTK_TREE_MODEL(data->model), &iter, path)) {
     853    gtk_tree_model_get(GTK_TREE_MODEL(data->model), &iter,
     854                       MC_ROW_INDEX, &index, -1);
     855    makeinfowind(data->wind, data->tr, index);
    767856  }
    768857}
     
    812901}
    813902
    814 const char *
    815 statusstr(int status) {
    816   switch(status) {
    817     case TR_STATUS_CHECK:       return "check";
    818     case TR_STATUS_DOWNLOAD:    return "download";
    819     case TR_STATUS_SEED:        return "seed";
    820     case TR_STATUS_STOPPING:    return "stopping";
    821     case TR_STATUS_STOPPED:     return "stopped";
    822     case TR_STATUS_PAUSE:       return "pause";
    823     case TR_TRACKER_ERROR:      return "error";
    824     default:
    825       assert(!"unknown status code");
    826       return NULL;
    827   }
    828 }
    829 
    830 void
    831 makeinfowind(struct cbdata *data, int index) {
    832   tr_stat_t *sb;
    833   GtkWidget *wind, *table, *name, *value;
    834   char buf[32];
    835 
    836   if(index >= tr_torrentStat(data->tr, &sb)) {
    837     assert(!"XXX i'm tired");
    838   }
    839   wind = gtk_dialog_new_with_buttons(sb[index].info.name, data->wind,
    840     GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
    841 
    842   table = gtk_table_new(21, 2, FALSE);
    843 
    844   name = gtk_label_new("Torrent File");
    845   value = gtk_label_new(sb[index].info.torrent);
    846   gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 0, 1);
    847   gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 0, 1);
    848   name = gtk_label_new("Name");
    849   value = gtk_label_new(sb[index].info.name);
    850   gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 1, 2);
    851   gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 1, 2);
    852   name = gtk_label_new("Tracker Address");
    853   value = gtk_label_new(sb[index].info.trackerAddress);
    854   gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 2, 3);
    855   gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 2, 3);
    856   name = gtk_label_new("Tracker Port");
    857   snprintf(buf, sizeof buf, "%i", sb[index].info.trackerPort);
    858   value = gtk_label_new(buf);
    859   gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 3, 4);
    860   gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 3, 4);
    861   name = gtk_label_new("Tracker Announce URL");
    862   value = gtk_label_new(sb[index].info.trackerAnnounce);
    863   gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 4, 5);
    864   gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 4, 5);
    865   name = gtk_label_new("Piece Size");
    866   snprintf(buf, sizeof buf, "%i", sb[index].info.pieceSize);
    867   value = gtk_label_new(buf);
    868   gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 5, 6);
    869   gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 5, 6);
    870   name = gtk_label_new("Piece Count");
    871   snprintf(buf, sizeof buf, "%i", sb[index].info.pieceCount);
    872   value = gtk_label_new(buf);
    873   gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 6, 7);
    874   gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 6, 7);
    875   name = gtk_label_new("Total Size");
    876   snprintf(buf, sizeof buf, "%llu", sb[index].info.totalSize);
    877   value = gtk_label_new(buf);
    878   gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 7, 8);
    879   gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 7, 8);
    880   name = gtk_label_new("File Count");
    881   snprintf(buf, sizeof buf, "%i", sb[index].info.fileCount);
    882   value = gtk_label_new(buf);
    883   gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 8, 9);
    884   gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 8, 9);
    885   name = gtk_label_new("Status");
    886   value = gtk_label_new(statusstr(sb[index].status));
    887   gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 9, 10);
    888   gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 9, 10);
    889   name = gtk_label_new("Error");
    890   value = gtk_label_new(sb[index].error);
    891   gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 10, 11);
    892   gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 10, 11);
    893   name = gtk_label_new("Progress");
    894   snprintf(buf, sizeof buf, "%f", sb[index].progress);
    895   value = gtk_label_new(buf);
    896   gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 11, 12);
    897   gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 11, 12);
    898   name = gtk_label_new("Download Rate");
    899   value = gtk_label_new(buf);
    900   snprintf(buf, sizeof buf, "%f", sb[index].rateDownload);
    901   gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 12, 13);
    902   gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 12, 13);
    903   name = gtk_label_new("Upload Rate");
    904   snprintf(buf, sizeof buf, "%f", sb[index].rateUpload);
    905   value = gtk_label_new(buf);
    906   gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 13, 14);
    907   gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 13, 14);
    908   name = gtk_label_new("ETA");
    909   snprintf(buf, sizeof buf, "%i", sb[index].eta);
    910   value = gtk_label_new(buf);
    911   gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 14, 15);
    912   gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 14, 15);
    913   name = gtk_label_new("Total Peers");
    914   snprintf(buf, sizeof buf, "%i", sb[index].peersTotal);
    915   value = gtk_label_new(buf);
    916   gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 15, 16);
    917   gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 15, 16);
    918   name = gtk_label_new("Uploading Peers");
    919   snprintf(buf, sizeof buf, "%i", sb[index].peersUploading);
    920   value = gtk_label_new(buf);
    921   gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 16, 17);
    922   gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 16, 17);
    923   name = gtk_label_new("Downloading Peers");
    924   snprintf(buf, sizeof buf, "%i", sb[index].peersDownloading);
    925   value = gtk_label_new(buf);
    926   gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 17, 18);
    927   gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 17, 18);
    928   name = gtk_label_new("Downloaded");
    929   snprintf(buf, sizeof buf, "%llu", sb[index].downloaded);
    930   value = gtk_label_new(buf);
    931   gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 18, 19);
    932   gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 18, 19);
    933   name = gtk_label_new("Uploaded");
    934   snprintf(buf, sizeof buf, "%llu", sb[index].uploaded);
    935   value = gtk_label_new(buf);
    936   gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 19, 20);
    937   gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 19, 20);
    938 
    939   gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(wind)->vbox), table);
    940   g_signal_connect(G_OBJECT(wind), "response",
    941                    G_CALLBACK(gtk_widget_destroy), NULL);
    942   gtk_widget_show_all(wind);
    943   free(sb);
    944 }
    945 
    946903gboolean
    947904savetorrents(tr_handle_t *tr, GtkWindow *wind, int count, tr_stat_t *stat) {
     
    967924  return ret;
    968925}
     926
     927/* use with gtk_tree_selection_selected_foreach to | status of selected rows */
     928void
     929orstatus(GtkTreeModel *model, GtkTreePath *path SHUTUP, GtkTreeIter *iter,
     930         gpointer gdata) {
     931  int *allstatus = gdata;
     932  int status;
     933
     934  gtk_tree_model_get(model, iter, MC_STAT, &status, -1);
     935  *allstatus |= status;
     936}
     937
     938void
     939makeidlist(GtkTreeModel *model, GtkTreePath *path SHUTUP, GtkTreeIter *iter,
     940           gpointer gdata) {
     941  GList **ids = gdata;
     942  int index;
     943
     944  gtk_tree_model_get(model, iter, MC_ROW_INDEX, &index, -1);
     945  *ids = g_list_append(*ids, GINT_TO_POINTER(index));
     946}
  • trunk/gtk/prefs.c

    r18 r22  
    2525*/
    2626
     27#include <assert.h>
    2728#include <errno.h>
    2829#include <stdlib.h>
     
    307308  gtk_widget_destroy(widget);
    308309}
     310
     311#define INFOLINE(tab, ii, nam, val) \
     312  do { \
     313    GtkWidget *wid = gtk_label_new(NULL); \
     314    gtk_misc_set_alignment(GTK_MISC(wid), 1, .5); \
     315    gtk_label_set_markup(GTK_LABEL(wid), "<b>" nam ":</b>"); \
     316    gtk_table_attach_defaults(GTK_TABLE(tab), wid, 0, 1, ii, ii + 1); \
     317    wid = gtk_label_new(val); \
     318    gtk_misc_set_alignment(GTK_MISC(wid), 0, .5); \
     319    gtk_table_attach_defaults(GTK_TABLE(tab), wid, 1, 2, ii, ii + 1); \
     320    ii++; \
     321  } while(0);
     322
     323#define INFOLINEF(tab, ii, fmt, nam, val) \
     324  do { \
     325    char *buf = g_strdup_printf(fmt, val); \
     326    INFOLINE(tab, ii, nam, buf); \
     327    g_free(buf); \
     328  } while(0);
     329
     330#define INFOLINEA(tab, ii, nam, val) \
     331  do { \
     332    char *buf = val; \
     333    INFOLINE(tab, ii, nam, buf); \
     334    g_free(buf); \
     335  } while(0);
     336
     337#define INFOSEP(tab, ii) \
     338  do { \
     339    GtkWidget *wid = gtk_hseparator_new(); \
     340    gtk_table_attach_defaults(GTK_TABLE(tab), wid, 0, 2, ii, ii + 1); \
     341    ii++; \
     342  } while(0);
     343
     344#define INFOSTATUS(st) \
     345  (TR_STATUS_CHECK    & (st) ? "check" : \
     346  (TR_STATUS_DOWNLOAD & (st) ? "download" : \
     347  (TR_STATUS_SEED     & (st) ? "seed" : \
     348  (TR_STATUS_STOPPING & (st) ? "stopping" : \
     349  (TR_STATUS_STOPPED  & (st) ? "stopped" : \
     350  (TR_STATUS_PAUSE    & (st) ? "pause" : \
     351  "???"))))))
     352
     353void
     354makeinfowind(GtkWindow *parent, tr_handle_t *tr, int id) {
     355  tr_stat_t *sb;
     356  GtkWidget *wind, *table, *label;
     357  int ii;
     358  char *str;
     359  const int rowcount = 11;
     360
     361  /* XXX would be nice to be able to stat just one */
     362  if(id >= tr_torrentStat(tr, &sb))
     363    assert(!"XXX ");
     364  str = g_strdup_printf("%s Properties", sb[id].info.name);
     365  wind = gtk_dialog_new_with_buttons(str, parent,
     366    GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
     367  g_free(str);
     368
     369  table = gtk_table_new(rowcount, 2, FALSE);
     370  gtk_table_set_col_spacings(GTK_TABLE(table), 10);
     371  gtk_table_set_row_spacings(GTK_TABLE(table), 10);
     372
     373  label = gtk_label_new(NULL);
     374  str = g_markup_printf_escaped("<big>%s</big>", sb[id].info.name);
     375  gtk_label_set_markup(GTK_LABEL(label), str);
     376  g_free(str);
     377  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 2, 0, 1);
     378
     379  ii = 1;
     380
     381  INFOSEP(table, ii);
     382
     383  INFOLINEA(table, ii, "Tracker", g_strdup_printf("http://%s:%i",
     384            sb[id].info.trackerAddress, sb[id].info.trackerPort));
     385  INFOLINE(table, ii, "Announce", sb[id].info.trackerAnnounce);
     386  INFOLINEA(table, ii, "Piece Size", readablesize(sb[id].info.pieceSize, 1));
     387  INFOLINEF(table, ii, "%i", "Pieces", sb[id].info.pieceCount);
     388  INFOLINEA(table, ii, "Total Size", readablesize(sb[id].info.totalSize, 1));
     389
     390  INFOSEP(table, ii);
     391
     392  INFOLINE(table, ii, "Directory", sb[id].folder);
     393  INFOLINEA(table, ii, "Downloaded", readablesize(sb[id].downloaded, 1));
     394  INFOLINEA(table, ii, "Uploaded", readablesize(sb[id].uploaded, 1));
     395
     396  assert(rowcount == ii);
     397
     398  gtk_container_set_border_width(GTK_CONTAINER(table), 10);
     399  gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(wind)->vbox), table);
     400  g_signal_connect(G_OBJECT(wind), "response",
     401                   G_CALLBACK(gtk_widget_destroy), NULL);
     402  gtk_widget_show_all(wind);
     403  free(sb);
     404}
  • trunk/gtk/prefs.h

    r17 r22  
    5353            torrents_added_func_t donefunc, void *donedata);
    5454
     55/* show the info window for a torrent */
     56void
     57makeinfowind(GtkWindow *parent, tr_handle_t *tr, int index);
     58
    5559#endif /* TG_PREFS_H */
Note: See TracChangeset for help on using the changeset viewer.