Changeset 320 for trunk/gtk


Ignore:
Timestamp:
Jun 10, 2006, 6:53:20 AM (15 years ago)
Author:
joshe
Message:

Add support to the GTK GUI for saving private copies of torrent files.
The prefs dialog for this sucks, but it should work.

Location:
trunk/gtk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/gtk/conf.h

    r261 r320  
    5454cf_freestate(benc_val_t *state);
    5555
     56/* macros for names of prefs we use */
     57#define PREF_PORT               "listening-port"
     58#define PREF_USEDOWNLIMIT       "use-download-limit"
     59#define PREF_DOWNLIMIT          "download-limit"
     60#define PREF_USEUPLIMIT         "use-upload-limit"
     61#define PREF_UPLIMIT            "upload-limit"
     62#define PREF_DIR                "download-directory"
     63#define PREF_ADDSTD             "add-behavior-standard"
     64#define PREF_ADDDND             "add-behavior-dnd"
     65#define PREF_ADDIPC             "add-behavior-ipc"
     66
    5667#endif /* TG_CONF_H */
  • trunk/gtk/dialogs.c

    r261 r320  
    3939#include "util.h"
    4040
     41#define PREFNAME                "transmission-dialog-pref-name"
     42
     43/* default values for a couple prefs */
     44#define DEF_DOWNLIMIT           100
     45#define DEF_USEDOWNLIMIT        FALSE
     46#define DEF_UPLIMIT             20
     47#define DEF_USEUPLIMIT          TRUE
     48
    4149struct prefdata {
    42   GtkSpinButton *port;
    43   GtkCheckButton *use_dlimit;
    44   GtkSpinButton *dlimit;
    45   GtkCheckButton *use_ulimit;
    46   GtkSpinButton *ulimit;
    47   GtkFileChooser *dir;
     50  GList *prefwidgets;
    4851  GtkWindow *parent;
    4952  TrBackend *back;
     
    7578addresp(GtkWidget *widget, gint resp, gpointer gdata);
    7679
     80static void
     81setupprefwidget(GtkWidget *widget, const char *prefname, ...) {
     82  const char *pref = cf_getpref(prefname);
     83  GtkTreeModel *model;
     84  GtkTreeIter iter;
     85  guint prefsflag, modelflag;
     86  va_list ap;
     87
     88  g_object_set_data_full(G_OBJECT(widget), PREFNAME,
     89                         g_strdup(prefname), (GDestroyNotify)g_free);
     90
     91  va_start(ap, prefname);
     92
     93  if(ISA(widget, GTK_TYPE_FILE_CHOOSER)) {
     94    if(NULL != pref)
     95      gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(widget), pref);
     96  }
     97  else if(ISA(widget, GTK_TYPE_SPIN_BUTTON))
     98    gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget),
     99      (NULL == pref ? va_arg(ap, long) : strtol(pref, NULL, 10)));
     100  else if(ISA(widget, GTK_TYPE_TOGGLE_BUTTON))
     101    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
     102      (NULL == pref ? va_arg(ap, gboolean) : strbool(pref)));
     103  else if(ISA(widget, GTK_TYPE_COMBO_BOX)) {
     104    model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
     105    prefsflag = addactionflag(pref);
     106    if(gtk_tree_model_get_iter_first(model, &iter))
     107      do {
     108        gtk_tree_model_get(model, &iter, 1, &modelflag, -1);
     109        if(modelflag == prefsflag) {
     110          gtk_combo_box_set_active_iter(GTK_COMBO_BOX(widget), &iter);
     111          break;
     112        }
     113      } while(gtk_tree_model_iter_next(model, &iter));
     114  }
     115  else {
     116    g_assert_not_reached();
     117  }
     118
     119  va_end(ap);
     120}
     121
     122static void
     123saveprefwidget(GtkWindow *parent, GtkWidget *widget) {
     124  char *prefname;
     125  const char *strval;
     126  char *freeablestr;
     127  GtkTreeModel *model;
     128  GtkTreeIter iter;
     129  guint uintval;
     130
     131  strval = NULL;
     132  freeablestr = NULL;
     133  if(ISA(widget, GTK_TYPE_FILE_CHOOSER)) {
     134    strval = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(widget));
     135    if(NULL != strval) {
     136      if(!mkdir_p(strval, 0777)) {
     137        errmsg(parent, _("Failed to create the directory %s:\n%s"),
     138               strval, strerror(errno));
     139        return;
     140      }
     141    }
     142  }
     143  else if(ISA(widget, GTK_TYPE_SPIN_BUTTON))
     144    freeablestr = g_strdup_printf("%i",
     145      gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)));
     146  else if(ISA(widget, GTK_TYPE_TOGGLE_BUTTON))
     147    strval = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) ?
     148              "yes" : "no");
     149  else if(ISA(widget, GTK_TYPE_COMBO_BOX)) {
     150    if(gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &iter)) {
     151      model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
     152      gtk_tree_model_get(model, &iter, 1, &uintval, -1);
     153      strval = addactionname(uintval);
     154    }
     155  }
     156  else {
     157    g_assert_not_reached();
     158    return;
     159  }
     160
     161  prefname = g_object_get_data(G_OBJECT(widget), PREFNAME);
     162  g_assert(NULL != prefname);
     163
     164  if(NULL != strval)
     165    cf_setpref(prefname, strval);
     166  else if(NULL != freeablestr) {
     167    cf_setpref(prefname, freeablestr);
     168    g_free(freeablestr);
     169  }
     170}
     171
    77172void
    78173makeprefwindow(GtkWindow *parent, TrBackend *back, gboolean *opened) {
     
    82177   GTK_STOCK_APPLY, GTK_RESPONSE_APPLY, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
    83178   GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
    84   const unsigned int rowcount = 6;
     179  const unsigned int rowcount = 9;
    85180  GtkWidget *table = gtk_table_new(rowcount, 2, FALSE);
    86181  GtkWidget *portnum = gtk_spin_button_new_with_range(1, 0xffff, 1);
     
    88183    _("Choose a download directory"),
    89184    GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
     185  GtkWidget *addstd = gtk_combo_box_new();
     186  GtkWidget *adddnd = gtk_combo_box_new();
     187  GtkWidget *addipc = gtk_combo_box_new();
    90188  GtkWidget *label;
    91189  GtkWidget **array;
    92   const char *pref;
    93190  struct prefdata *data = g_new0(struct prefdata, 1);
    94191  struct { GtkWidget *on; GtkWidget *num; GtkWidget *label; gboolean defuse;
     
    104201  };
    105202  unsigned int ii;
     203  GtkTreeModel *model;
     204  GtkTreeIter iter;
     205  GtkCellRenderer *rend;
    106206
    107207  *opened = TRUE;
     
    115215  gtk_window_set_resizable(GTK_WINDOW(wind), FALSE);
    116216
    117   data->port = GTK_SPIN_BUTTON(portnum);
    118   data->use_dlimit = GTK_CHECK_BUTTON(lim[0].on);
    119   data->dlimit = GTK_SPIN_BUTTON(lim[0].num);
    120   data->use_ulimit = GTK_CHECK_BUTTON(lim[1].on);
    121   data->ulimit = GTK_SPIN_BUTTON(lim[1].num);
    122   data->dir = GTK_FILE_CHOOSER(dirstr);
     217  data->prefwidgets = makeglist(portnum, lim[0].on, lim[0].num, lim[1].on,
     218    lim[1].num, dirstr, addstd, adddnd, addipc, NULL);
    123219  data->parent = parent;
    124220  data->back = back;
     
    129225  for(ii = 0; ii < ALEN(lim); ii++) {
    130226    /* limit checkbox */
    131     pref = cf_getpref(lim[ii].usepref);
    132     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lim[ii].on),
    133       (NULL == pref ? lim[ii].defuse : strbool(pref)));
     227    setupprefwidget(lim[ii].on, lim[ii].usepref, (gboolean)lim[ii].defuse);
    134228    array = g_new(GtkWidget*, 2);
    135229    g_signal_connect_data(lim[ii].on, "clicked", G_CALLBACK(clicklimitbox),
     
    140234    gtk_label_set_mnemonic_widget(GTK_LABEL(lim[ii].label), lim[ii].num);
    141235    gtk_misc_set_alignment(GTK_MISC(lim[ii].label), 0, .5);
    142     pref = cf_getpref(lim[ii].numpref);
    143236    gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(lim[ii].num), TRUE);
    144     gtk_spin_button_set_value(GTK_SPIN_BUTTON(lim[ii].num),
    145       (NULL == pref ? lim[ii].def : strtol(pref, NULL, 10)));
     237    setupprefwidget(lim[ii].num, lim[ii].numpref, (long)lim[ii].def);
    146238    gtk_table_attach_defaults(GTK_TABLE(table), lim[ii].label, 0,1,RN(ii*2+1));
    147239    gtk_table_attach_defaults(GTK_TABLE(table), lim[ii].num,   1,2,RN(ii*2+1));
     
    156248  gtk_label_set_mnemonic_widget(GTK_LABEL(label), dirstr);
    157249  gtk_misc_set_alignment(GTK_MISC(label), 0, .5);
    158   if(NULL != (pref = cf_getpref(PREF_DIR)))
    159     gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dirstr), pref);
     250  setupprefwidget(dirstr, PREF_DIR);
    160251  gtk_table_attach_defaults(GTK_TABLE(table), label,           0, 1, RN(ii));
    161252  gtk_table_attach_defaults(GTK_TABLE(table), dirstr,          1, 2, RN(ii));
     
    166257  gtk_label_set_mnemonic_widget(GTK_LABEL(label), portnum);
    167258  gtk_misc_set_alignment(GTK_MISC(label), 0, .5);
    168   pref = cf_getpref(PREF_PORT);
    169259  gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(portnum), TRUE);
    170   gtk_spin_button_set_value(GTK_SPIN_BUTTON(portnum),
    171     (NULL == pref ? TR_DEFAULT_PORT : strtol(pref, NULL, 10)));
     260  setupprefwidget(portnum, PREF_PORT, (long)TR_DEFAULT_PORT);
    172261  gtk_table_attach_defaults(GTK_TABLE(table), label,           0, 1, RN(ii));
    173262  gtk_table_attach_defaults(GTK_TABLE(table), portnum,         1, 2, RN(ii));
     263  ii++;
     264
     265  /* create the model used by the three popup menus */
     266  model = GTK_TREE_MODEL(gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT));
     267  gtk_list_store_append(GTK_LIST_STORE(model), &iter);
     268  gtk_list_store_set(GTK_LIST_STORE(model), &iter, 1, 0, 0,
     269    _("Use the torrent file where it is"), -1);
     270  gtk_list_store_append(GTK_LIST_STORE(model), &iter);
     271  gtk_list_store_set(GTK_LIST_STORE(model), &iter, 1, TR_TORNEW_SAVE_COPY, 0,
     272    _("Keep a copy of the torrent file"), -1);
     273  gtk_list_store_append(GTK_LIST_STORE(model), &iter);
     274  gtk_list_store_set(GTK_LIST_STORE(model), &iter, 1, TR_TORNEW_SAVE_MOVE, 0,
     275    _("Keep a copy and remove the original"), -1);
     276
     277  /* std */
     278  label = gtk_label_new_with_mnemonic(_("For torrents added _normally:"));
     279  gtk_label_set_mnemonic_widget(GTK_LABEL(label), addstd);
     280  gtk_misc_set_alignment(GTK_MISC(label), 0, .5);
     281  gtk_combo_box_set_model(GTK_COMBO_BOX(addstd), model);
     282  rend = gtk_cell_renderer_text_new();
     283  gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(addstd), rend, TRUE);
     284  gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(addstd), rend, "text", 0);
     285  setupprefwidget(addstd, PREF_ADDSTD);
     286  gtk_table_attach_defaults(GTK_TABLE(table), label,           0, 1, RN(ii));
     287  gtk_table_attach_defaults(GTK_TABLE(table), addstd,          1, 2, RN(ii));
     288  ii++;
     289
     290  /* dnd */
     291  label = gtk_label_new_with_mnemonic(_("For torrents dra_gged and dropped:"));
     292  gtk_label_set_mnemonic_widget(GTK_LABEL(label), adddnd);
     293  gtk_misc_set_alignment(GTK_MISC(label), 0, .5);
     294  gtk_combo_box_set_model(GTK_COMBO_BOX(adddnd), model);
     295  rend = gtk_cell_renderer_text_new();
     296  gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(adddnd), rend, TRUE);
     297  gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(adddnd), rend, "text", 0);
     298  setupprefwidget(adddnd, PREF_ADDDND);
     299  gtk_table_attach_defaults(GTK_TABLE(table), label,           0, 1, RN(ii));
     300  gtk_table_attach_defaults(GTK_TABLE(table), adddnd,          1, 2, RN(ii));
     301  ii++;
     302
     303  /* ipc */
     304  label = gtk_label_new_with_mnemonic(
     305    _("For torrents added e_xternally:"));
     306  gtk_label_set_mnemonic_widget(GTK_LABEL(label), addipc);
     307  gtk_misc_set_alignment(GTK_MISC(label), 0, .5);
     308  gtk_combo_box_set_model(GTK_COMBO_BOX(addipc), model);
     309  rend = gtk_cell_renderer_text_new();
     310  gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(addipc), rend, TRUE);
     311  gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(addipc), rend, "text", 0);
     312  setupprefwidget(addipc, PREF_ADDIPC);
     313  gtk_table_attach_defaults(GTK_TABLE(table), label,           0, 1, RN(ii));
     314  gtk_table_attach_defaults(GTK_TABLE(table), addipc,          1, 2, RN(ii));
    174315  ii++;
    175316
     
    212353clickdialog(GtkWidget *widget, int resp, gpointer gdata) {
    213354  struct prefdata *data = gdata;
    214   int intval;
    215   const char *strval;
    216   char *strnum, *errstr;
    217   gboolean bval;
     355  char *errstr;
     356  GList *ii;
    218357
    219358  if(GTK_RESPONSE_APPLY == resp || GTK_RESPONSE_OK == resp) {
    220     /* check directory */
    221     if(NULL != (strval = gtk_file_chooser_get_current_folder(data->dir))) {
    222       if(!mkdir_p(strval, 0777)) {
    223         errmsg(data->parent,
    224                _("Failed to create the directory %s:\n%s"),
    225                strval, strerror(errno));
    226         return;
    227       }
    228 
    229       /* save dir pref */
    230       cf_setpref(PREF_DIR, strval);
    231     }
    232 
    233     /* save port pref */
    234     strnum = g_strdup_printf("%i",
    235       gtk_spin_button_get_value_as_int(data->port));
    236     cf_setpref(PREF_PORT, strnum);
    237     g_free(strnum);
    238 
    239     /* save usedownlimit pref */
    240     bval = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->use_dlimit));
    241     cf_setpref(PREF_USEDOWNLIMIT, (bval ? "yes" : "no"));
    242 
    243     /* save downlimit pref */
    244     intval = gtk_spin_button_get_value_as_int(data->dlimit);
    245     strnum = g_strdup_printf("%i", intval);
    246     cf_setpref(PREF_DOWNLIMIT, strnum);
    247 
    248     /* save useuplimit pref */
    249     bval = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->use_ulimit));
    250     cf_setpref(PREF_USEUPLIMIT, (bval ? "yes" : "no"));
    251 
    252     /* save downlimit pref */
    253     intval = gtk_spin_button_get_value_as_int(data->ulimit);
    254     strnum = g_strdup_printf("%i", intval);
    255     cf_setpref(PREF_UPLIMIT, strnum);
    256 
    257     /* save prefs */
     359    /* save all the prefs */
     360    for(ii = g_list_first(data->prefwidgets); NULL != ii; ii = ii->next)
     361      saveprefwidget(data->parent, ii->data);
     362
     363    /* write prefs to disk */
    258364    cf_saveprefs(&errstr);
    259365    if(NULL != errstr) {
    260366      errmsg(data->parent, "%s", errstr);
    261       g_free(strnum);
    262367      g_free(errstr);
    263368    }
    264369
    265370    /* XXX would be nice to have errno strings, are they printed to stdout? */
     371
    266372    tr_setBindPort(tr_backend_handle(data->back),
    267                    gtk_spin_button_get_value_as_int(data->port));
     373                   strtol(cf_getpref(PREF_PORT), NULL, 10));
    268374    setlimit(data->back);
    269375  }
     
    386492      stupidgtk = g_list_append(stupidgtk, ii->data);
    387493    paused = !data->autostart;
    388     data->addfunc(data->data, NULL, stupidgtk, dir, &paused);
     494    data->addfunc(data->data, NULL, stupidgtk, dir,
     495                  addactionflag(cf_getpref(PREF_ADDSTD)));
    389496    if(NULL != dir)
    390497      g_free(dir);
  • trunk/gtk/dialogs.h

    r261 r320  
    3434#include "util.h"
    3535
    36 /* macros for names of prefs we use */
    37 #define PREF_PORT               "listening-port"
    38 #define PREF_USEDOWNLIMIT       "use-download-limit"
    39 #define PREF_DOWNLIMIT          "download-limit"
    40 #define PREF_USEUPLIMIT         "use-upload-limit"
    41 #define PREF_UPLIMIT            "upload-limit"
    42 #define PREF_DIR                "download-directory"
    43 
    44 /* default values for a couple prefs */
    45 #define DEF_DOWNLIMIT           100
    46 #define DEF_USEDOWNLIMIT        FALSE
    47 #define DEF_UPLIMIT             20
    48 #define DEF_USEUPLIMIT          TRUE
    49 
    5036void
    5137makeprefwindow(GtkWindow *parent, TrBackend *back, gboolean *opened);
  • trunk/gtk/ipc.c

    r261 r320  
    388388         g_utf8_validate(val->val.l.vals[ii].val.s.s, -1, NULL))
    389389        files = g_list_append(files, val->val.l.vals[ii].val.s.s);
    390     srv->addfunc(srv->cbdata, NULL, files, NULL, NULL);
     390    srv->addfunc(srv->cbdata, NULL, files, NULL,
     391                 addactionflag(cf_getpref(PREF_ADDIPC)));
    391392    g_list_free(files);
    392393  }
  • trunk/gtk/main.c

    r269 r320  
    126126void
    127127addtorrents(void *vdata, void *state, GList *files,
    128             const char *dir, gboolean *paused);
     128            const char *dir, guint flags);
    129129void
    130130savetorrents(struct cbdata *data);
     
    321321  setupdrag(list, data);
    322322
    323   addtorrents(data, state, args, NULL, NULL);
     323  addtorrents(data, state, args, NULL, addactionflag(cf_getpref(PREF_ADDIPC)));
    324324
    325325  data->timer = g_timeout_add(UPDATE_INTERVAL, updatemodel, data);
     
    593593    /* try to add any torrents we found */
    594594    if(NULL != paths) {
    595       addtorrents(data, NULL, paths, NULL, NULL);
     595      addtorrents(data, NULL, paths, NULL,
     596                  addactionflag(cf_getpref(PREF_ADDDND)));
    596597      freestrlist(paths);
    597598    }
     
    942943            g_object_ref(tor);
    943944            tr_torrent_stop_politely(tor);
     945            if(TR_FSAVEPRIVATE & tr_torrent_info(tor)->flags)
     946              tr_torrentRemoveSaved(tr_torrent_handle(tor));
    944947            gtk_list_store_remove(GTK_LIST_STORE(data->model), &iter);
    945948            changed = TRUE;
     
    996999void
    9971000addtorrents(void *vdata, void *state, GList *files,
    998             const char *dir, gboolean *paused) {
     1001            const char *dir, guint flags) {
    9991002  struct cbdata *data = vdata;
    10001003  GList *torlist, *errlist, *ii;
     
    10231026    for(ii = g_list_first(files); NULL != ii; ii = ii->next) {
    10241027      errstr = NULL;
    1025       tor = tr_torrent_new(G_OBJECT(data->back), ii->data,
    1026                            dir, paused, &errstr);
     1028      tor = tr_torrent_new(G_OBJECT(data->back), ii->data, dir,
     1029                           flags, &errstr);
    10271030      if(NULL != tor)
    10281031        torlist = g_list_append(torlist, tor);
  • trunk/gtk/tr_backend.c

    r269 r320  
    219219  cf_savestate(&state, errstr);
    220220  tr_bencFree(&state);
     221
     222  for(ii = back->torrents; NULL != ii; ii = ii->next)
     223    tr_torrent_state_saved(ii->data);
    221224}
    222225
  • trunk/gtk/tr_torrent.c

    r310 r320  
    134134  self->dir = NULL;
    135135  self->closing = FALSE;
     136  self->delfile = NULL;
    136137  self->disposed = FALSE;
    137138}
     
    223224  }
    224225
     226  if(NULL != self->delfile)
     227    g_free(self->delfile);
     228
    225229  /* Chain up to the parent class */
    226230  parent->dispose(obj);
     
    259263TrTorrent *
    260264tr_torrent_new(GObject *backend, const char *torrent, const char *dir,
    261                gboolean *paused, char **err) {
     265               guint flags, char **err) {
    262266  TrTorrent *ret;
    263267  tr_torrent_t *handle;
    264   int errcode;
     268  tr_handle_t *back;
     269  int errcode, trflags;
    265270
    266271  TR_IS_BACKEND(backend);
     
    269274  *err = NULL;
    270275
     276  back = tr_backend_handle(TR_BACKEND(backend));
     277  trflags = 0;
     278  if((TR_TORNEW_SAVE_COPY|TR_TORNEW_SAVE_MOVE) & flags)
     279    trflags |= TR_FSAVEPRIVATE;
    271280  errcode = -1;
    272   handle = tr_torrentInit(tr_backend_handle(TR_BACKEND(backend)),
    273                           torrent, 0, &errcode);
     281
     282  if(TR_TORNEW_LOAD_SAVED & flags)
     283    handle = tr_torrentInitSaved(back, torrent, 0, &errcode);
     284  else
     285    handle = tr_torrentInit(back, torrent, trflags, &errcode);
     286
    274287  if(NULL == handle) {
    275288    switch(errcode) {
     
    290303                     "backend", backend, "download-directory", dir, NULL);
    291304  tr_backend_add_torrent(TR_BACKEND(backend), G_OBJECT(ret));
    292 
    293   g_object_set(ret, "paused", (NULL == paused ? FALSE : *paused), NULL);
     305 
     306  g_object_set(ret, "paused", (TR_TORNEW_PAUSED & flags ? TRUE : FALSE), NULL);
     307
     308  if(TR_TORNEW_SAVE_MOVE & flags)
     309    ret->delfile = g_strdup(torrent);
    294310
    295311  return ret;
     
    300316  int ii;
    301317  benc_val_t *name, *data;
    302   char *torrent, *dir;
     318  char *torrent, *hash, *dir;
    303319  gboolean hadpaused, paused;
     320  guint flags;
    304321
    305322  *err = NULL;
     
    308325    return NULL;
    309326
    310   torrent = dir = NULL;
     327  torrent = hash = dir = NULL;
    311328  hadpaused = FALSE;
     329  paused = FALSE;               /* silence stupid compiler warning */
    312330
    313331  for(ii = 0; ii + 1 < state->val.l.count; ii += 2) {
     
    318336      if(0 == strcmp("torrent", name->val.s.s))
    319337        torrent = data->val.s.s;
     338      if(0 == strcmp("hash", name->val.s.s))
     339        hash = data->val.s.s;
    320340      else if(0 == strcmp("dir", name->val.s.s))
    321341        dir = data->val.s.s;
     
    327347  }
    328348
    329   if(NULL == torrent || NULL == dir)
    330     return NULL;
    331 
    332   return tr_torrent_new(backend, torrent, dir,
    333                         (hadpaused ? &paused : NULL), err);
    334 }
     349  if((NULL != torrent && NULL != hash) ||
     350     (NULL == torrent && NULL == hash) || NULL == dir)
     351    return NULL;
     352
     353  flags = 0;
     354  if(hadpaused)
     355    flags |= (paused ? TR_TORNEW_PAUSED : TR_TORNEW_RUNNING);
     356  if(NULL != hash) {
     357    flags |= TR_TORNEW_LOAD_SAVED;
     358    torrent = hash;
     359  }
     360
     361  return tr_torrent_new(backend, torrent, dir, flags, err);
     362}
     363
     364#define SETSTRVAL(vv, ss) \
     365  do { \
     366    (vv)->type = TYPE_STR; \
     367    (vv)->val.s.s = g_strdup((ss)); \
     368    (vv)->val.s.i = strlen((ss)); \
     369  } while(0)
    335370
    336371void
    337372tr_torrent_get_state(TrTorrent *tor, benc_val_t *state) {
    338373  tr_info_t *in = tr_torrentInfo(tor->handle);
    339   const char *strs[] = {
    340     "torrent", in->torrent, "dir", tr_torrentGetFolder(tor->handle), "paused",
    341   };
    342   unsigned int ii;
    343   const unsigned int len = 6;
    344374
    345375  TR_IS_TORRENT(tor);
     
    352382
    353383  state->type = TYPE_DICT;
    354   state->val.l.vals = g_new0(benc_val_t, len);
    355   state->val.l.alloc = state->val.l.count = len;
    356 
    357   g_assert(len > ALEN(strs));
    358   for(ii = 0; ii < ALEN(strs); ii++) {
    359     state->val.l.vals[ii].type = TYPE_STR;
    360     state->val.l.vals[ii].val.s.s = g_strdup(strs[ii]);
    361     state->val.l.vals[ii].val.s.i = strlen(strs[ii]);
    362   }
    363 
    364   state->val.l.vals[ii].type = TYPE_INT;
    365   state->val.l.vals[ii].val.i = tr_torrent_paused(tor);
    366   ii++;
    367 
    368   g_assert(len == ii);
     384  state->val.l.vals = g_new0(benc_val_t, 6);
     385  state->val.l.alloc = state->val.l.count = 6;
     386
     387  if(TR_FSAVEPRIVATE & in->flags) {
     388    SETSTRVAL(state->val.l.vals + 0, "hash");
     389    SETSTRVAL(state->val.l.vals + 1, in->hashString);
     390  } else {
     391    SETSTRVAL(state->val.l.vals + 0, "torrent");
     392    SETSTRVAL(state->val.l.vals + 1, in->torrent);
     393  }
     394  SETSTRVAL(state->val.l.vals + 2, "dir");
     395  SETSTRVAL(state->val.l.vals + 3, tr_torrentGetFolder(tor->handle));
     396  SETSTRVAL(state->val.l.vals + 4, "paused");
     397  state->val.l.vals[5].type = TYPE_INT;
     398  state->val.l.vals[5].val.i = tr_torrent_paused(tor);
     399}
     400
     401/* XXX this should probably be done with a signal */
     402void
     403tr_torrent_state_saved(TrTorrent *tor) {
     404  TR_IS_TORRENT(tor);
     405
     406  if(tor->disposed)
     407    return;
     408
     409  if(NULL != tor->delfile) {
     410    unlink(tor->delfile);
     411    g_free(tor->delfile);
     412    tor->delfile = NULL;
     413  }
    369414}
    370415
  • trunk/gtk/tr_torrent.h

    r269 r320  
    5757  char *dir;
    5858  gboolean closing;
     59  char *delfile;
    5960  gboolean disposed;
    6061};
     
    7778tr_torrent_info(TrTorrent *tor);
    7879
     80/* explicitly start the torrent running or paused */
     81#define TR_TORNEW_PAUSED        0x01
     82#define TR_TORNEW_RUNNING       0x02
     83/* load a saved torrent file, torrent param is hash instead of filename */
     84#define TR_TORNEW_LOAD_SAVED    0x04
     85/* save a private copy of the torrent file */
     86#define TR_TORNEW_SAVE_COPY     0x08
     87/* save a private copy of the torrent file and remove the original */
     88#define TR_TORNEW_SAVE_MOVE     0x10
     89
    7990TrTorrent *
    8091tr_torrent_new(GObject *backend, const char *torrent, const char *dir,
    81                gboolean *paused, char **err);
     92               guint flags, char **err);
    8293
    8394TrTorrent *
     
    93104void
    94105tr_torrent_get_state(TrTorrent *tor, benc_val_t *state);
     106void
     107tr_torrent_state_saved(TrTorrent *tor);
    95108#endif
    96109
  • trunk/gtk/util.c

    r261 r320  
    3838#include <glib/gi18n.h>
    3939
     40#include "tr_torrent.h"
    4041#include "util.h"
    4142
     
    228229}
    229230
     231guint
     232addactionflag(const char *action) {
     233  if(NULL == action)
     234    return TR_TORNEW_SAVE_COPY;
     235  else if(0 == strcmp("copy", action))
     236    return TR_TORNEW_SAVE_COPY;
     237  else if(0 == strcmp("move", action))
     238    return TR_TORNEW_SAVE_MOVE;
     239  else
     240    return 0;
     241}
     242
     243const char *
     244addactionname(guint flag) {
     245  static char name[6];
     246
     247  if(TR_TORNEW_SAVE_COPY & flag)
     248    strcpy(name, "copy");
     249  else if(TR_TORNEW_SAVE_MOVE & flag)
     250    strcpy(name, "move");
     251  else
     252    strcpy(name, "leave");
     253
     254  return name;
     255}
     256
     257GList *
     258makeglist(void *ptr, ...) {
     259  va_list ap;
     260  GList *ret;
     261
     262  ret = g_list_append(NULL, ptr);
     263
     264  va_start(ap, ptr); 
     265  while(NULL != (ptr = va_arg(ap, void*)))
     266    ret = g_list_append(ret, ptr);
     267  va_end(ap);
     268
     269  return ret;
     270}
     271
    230272GtkWidget *
    231273errmsg(GtkWindow *wind, const char *format, ...) {
  • trunk/gtk/util.h

    r261 r320  
    4040#endif
    4141
    42 typedef void (*add_torrents_func_t)(void*,void*,GList*,const char*,gboolean*);
     42typedef void (*add_torrents_func_t)(void*,void*,GList*,const char*,guint);
    4343
    4444/* return number of items in array */
    4545#define ALEN(a)                 (sizeof(a) / sizeof((a)[0]))
     46
     47#define ISA(o, t)               (g_type_is_a(G_OBJECT_TYPE(G_OBJECT(o)), (t)))
    4648
    4749/* used for a callback function with a data parameter */
     
    8385checkfilenames(int argc, char **argv);
    8486
     87/* returns the flag for an action string */
     88guint
     89addactionflag(const char *action);
     90
     91/* returns the action string for a flag */
     92const char *
     93addactionname(guint flag);
     94
     95/* turn a NULL-terminated list of void* arguments into a glist */
     96GList *
     97makeglist(void *ptr, ...);
     98
    8599#ifdef GTK_MAJOR_VERSION
    86100
Note: See TracChangeset for help on using the changeset viewer.