mirror of
https://github.com/transmission/transmission
synced 2025-01-30 19:03:04 +00:00
Update 2005-12-27
This commit is contained in:
parent
82c038fabc
commit
943df43518
3 changed files with 260 additions and 182 deletions
342
gtk/main.c
342
gtk/main.c
|
@ -98,21 +98,29 @@ listclick(GtkWidget *widget, GdkEventButton *event, gpointer gdata);
|
|||
gboolean
|
||||
listpopup(GtkWidget *widget, gpointer gdata);
|
||||
void
|
||||
dopopupmenu(GdkEventButton *event, struct cbdata *data, GtkTreeIter *iter);
|
||||
dopopupmenu(GdkEventButton *event, struct cbdata *data,
|
||||
GList *ids, int status);
|
||||
void
|
||||
killmenu(GtkWidget *menu, gpointer *gdata SHUTUP);
|
||||
void
|
||||
actionclick(GtkWidget *widget, gpointer gdata);
|
||||
void
|
||||
doubleclick(GtkWidget *widget, GtkTreePath *path, GtkTreeViewColumn *col,
|
||||
gpointer gdata);
|
||||
|
||||
gboolean
|
||||
addtorrent(tr_handle_t *tr, GtkWindow *parentwind, const char *torrent,
|
||||
const char *dir, gboolean paused);
|
||||
void
|
||||
addedtorrents(void *vdata);
|
||||
const char *
|
||||
statusstr(int status);
|
||||
void
|
||||
makeinfowind(struct cbdata *data, int index);
|
||||
gboolean
|
||||
savetorrents(tr_handle_t *tr, GtkWindow *wind, int count, tr_stat_t *stat);
|
||||
void
|
||||
orstatus(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
|
||||
gpointer gdata);
|
||||
void
|
||||
makeidlist(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
|
||||
gpointer gdata);
|
||||
|
||||
#define TR_TYPE_PIECES_NAME "tr-type-pieces"
|
||||
#define TR_TYPE_PIECES ((const GType)tr_type_pieces)
|
||||
|
@ -124,7 +132,8 @@ enum listact { ACT_OPEN, ACT_START, ACT_STOP, ACT_DELETE, ACT_INFO, ACT_PREF };
|
|||
#define LIST_ACTION_FROM "torrent-list-action-from"
|
||||
enum listfrom { FROM_BUTTON, FROM_POPUP };
|
||||
|
||||
#define LIST_INDEX "torrent-list-index"
|
||||
#define LIST_INDEX "torrent-list-indexes"
|
||||
#define LIST_MENU_WIDGET "torrent-list-popup-menu-widget"
|
||||
|
||||
struct { const gchar *name; const gchar *id; enum listact act; gboolean nomenu;
|
||||
int avail; const char *ttext; const char *tpriv; }
|
||||
|
@ -445,11 +454,13 @@ makewind_list(struct cbdata *data) {
|
|||
|
||||
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(view), TRUE);
|
||||
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
|
||||
gtk_tree_selection_set_mode(GTK_TREE_SELECTION(sel), GTK_SELECTION_SINGLE);
|
||||
gtk_tree_selection_set_mode(GTK_TREE_SELECTION(sel), GTK_SELECTION_MULTIPLE);
|
||||
g_signal_connect(G_OBJECT(sel), "changed", G_CALLBACK(fixbuttons), data);
|
||||
g_signal_connect(G_OBJECT(view), "button-press-event",
|
||||
G_CALLBACK(listclick), data);
|
||||
g_signal_connect(G_OBJECT(view), "popup-menu", G_CALLBACK(listpopup), data);
|
||||
g_signal_connect(G_OBJECT(view), "row-activated",
|
||||
G_CALLBACK(doubleclick), data);
|
||||
gtk_widget_show_all(view);
|
||||
|
||||
return view;
|
||||
|
@ -468,16 +479,15 @@ stylekludge(GObject *obj, GParamSpec *spec, gpointer gdata) {
|
|||
void
|
||||
fixbuttons(GtkTreeSelection *sel, gpointer gdata) {
|
||||
struct cbdata *data = gdata;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
gboolean selected;
|
||||
unsigned int ii;
|
||||
int status;
|
||||
|
||||
if(NULL == sel)
|
||||
sel = gtk_tree_view_get_selection(data->view);
|
||||
if((selected = gtk_tree_selection_get_selected(sel, &model, &iter)))
|
||||
gtk_tree_model_get(model, &iter, MC_STAT, &status, -1);
|
||||
status = 0;
|
||||
gtk_tree_selection_selected_foreach(sel, orstatus, &status);
|
||||
selected = (0 < gtk_tree_selection_count_selected_rows(sel));
|
||||
|
||||
for(ii = 0; ii < ALEN(actionitems); ii++)
|
||||
if(actionitems[ii].avail)
|
||||
|
@ -619,19 +629,42 @@ updatemodel(gpointer gdata) {
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* show a popup menu for a right-click on the list */
|
||||
gboolean
|
||||
listclick(GtkWidget *widget SHUTUP, GdkEventButton *event, gpointer gdata) {
|
||||
struct cbdata *data = gdata;
|
||||
GtkTreeSelection *sel = gtk_tree_view_get_selection(data->view);
|
||||
GtkTreePath *path;
|
||||
GtkTreeIter iter;
|
||||
int index, status;
|
||||
GList *ids;
|
||||
|
||||
if(GDK_BUTTON_PRESS == event->type && 3 == event->button) {
|
||||
/* find what row, if any, the user clicked on */
|
||||
if(!gtk_tree_view_get_path_at_pos(data->view, event->x, event->y, &path,
|
||||
NULL, NULL, NULL))
|
||||
dopopupmenu(event, data, NULL);
|
||||
/* no row was clicked, do the popup with no torrent IDs or status */
|
||||
dopopupmenu(event, data, NULL, 0);
|
||||
else {
|
||||
if(gtk_tree_model_get_iter(GTK_TREE_MODEL(data->model), &iter, path))
|
||||
dopopupmenu(event, data, &iter);
|
||||
if(gtk_tree_model_get_iter(GTK_TREE_MODEL(data->model), &iter, path)) {
|
||||
/* get ID and status for the right-clicked row */
|
||||
gtk_tree_model_get(GTK_TREE_MODEL(data->model), &iter,
|
||||
MC_ROW_INDEX, &index, MC_STAT, &status, -1);
|
||||
/* get a list of selected IDs */
|
||||
ids = NULL;
|
||||
gtk_tree_selection_selected_foreach(sel, makeidlist, &ids);
|
||||
/* is the clicked row selected? */
|
||||
if(NULL == g_list_find(ids, GINT_TO_POINTER(index))) {
|
||||
/* no, do the popup for just the clicked row */
|
||||
g_list_free(ids);
|
||||
dopopupmenu(event, data, g_list_append(NULL, GINT_TO_POINTER(index)),
|
||||
status);
|
||||
} else {
|
||||
/* yes, do the popup for all the selected rows */
|
||||
gtk_tree_selection_selected_foreach(sel, orstatus, &status);
|
||||
dopopupmenu(event, data, ids, status);
|
||||
}
|
||||
}
|
||||
gtk_tree_path_free(path);
|
||||
}
|
||||
return TRUE;
|
||||
|
@ -645,47 +678,58 @@ listpopup(GtkWidget *widget SHUTUP, gpointer gdata) {
|
|||
struct cbdata *data = gdata;
|
||||
GtkTreeSelection *sel = gtk_tree_view_get_selection(data->view);
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
GList *ids;
|
||||
int status;
|
||||
|
||||
if(!gtk_tree_selection_get_selected(sel, &model, &iter))
|
||||
dopopupmenu(NULL, data, NULL);
|
||||
if(0 >= gtk_tree_selection_count_selected_rows(sel))
|
||||
dopopupmenu(NULL, data, NULL, 0);
|
||||
else {
|
||||
assert(model == GTK_TREE_MODEL(data->model));
|
||||
dopopupmenu(NULL, data, &iter);
|
||||
status = 0;
|
||||
gtk_tree_selection_selected_foreach(sel, orstatus, &status);
|
||||
ids = NULL;
|
||||
gtk_tree_selection_selected_foreach(sel, makeidlist, &ids);
|
||||
dopopupmenu(NULL, data, ids, status);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
dopopupmenu(GdkEventButton *event, struct cbdata *data, GtkTreeIter *iter) {
|
||||
dopopupmenu(GdkEventButton *event, struct cbdata *data,
|
||||
GList *ids, int status) {
|
||||
GtkWidget *menu = gtk_menu_new();
|
||||
GtkWidget *item;
|
||||
unsigned int ii;
|
||||
int index, status;
|
||||
|
||||
index = -1;
|
||||
if(NULL != iter)
|
||||
gtk_tree_model_get(GTK_TREE_MODEL(data->model), iter,
|
||||
MC_ROW_INDEX, &index, MC_STAT, &status, -1);
|
||||
|
||||
/* XXX am I leaking references here? */
|
||||
for(ii = 0; ii < ALEN(actionitems); ii++) {
|
||||
if(actionitems[ii].nomenu ||
|
||||
(actionitems[ii].avail &&
|
||||
(0 > index || !(actionitems[ii].avail & status))))
|
||||
(NULL == ids || !(actionitems[ii].avail & status))))
|
||||
continue;
|
||||
item = gtk_menu_item_new_with_label(actionitems[ii].name);
|
||||
/* set the action for the menu item */
|
||||
g_object_set_data(G_OBJECT(item), LIST_ACTION,
|
||||
GINT_TO_POINTER(actionitems[ii].act));
|
||||
/* show that this action came from a popup menu */
|
||||
g_object_set_data(G_OBJECT(item), LIST_ACTION_FROM,
|
||||
GINT_TO_POINTER(FROM_POPUP));
|
||||
g_object_set_data(G_OBJECT(item), LIST_INDEX, GINT_TO_POINTER(index));
|
||||
/* set a glist of selected torrent's IDs */
|
||||
g_object_set_data(G_OBJECT(item), LIST_INDEX, ids);
|
||||
/* set the menu widget, so the activate handler can destroy it */
|
||||
g_object_set_data(G_OBJECT(item), LIST_MENU_WIDGET, menu);
|
||||
g_signal_connect(G_OBJECT(item), "activate",
|
||||
G_CALLBACK(actionclick), data);
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
|
||||
}
|
||||
|
||||
/* set up the glist to be freed when the menu is destroyed */
|
||||
g_object_set_data_full(G_OBJECT(menu), LIST_INDEX, ids,
|
||||
(GDestroyNotify)g_list_free);
|
||||
|
||||
/* destroy the menu if the user doesn't select anything */
|
||||
g_signal_connect(menu, "selection-done", G_CALLBACK(killmenu), NULL);
|
||||
|
||||
gtk_widget_show_all(menu);
|
||||
|
||||
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
|
||||
|
@ -693,18 +737,28 @@ dopopupmenu(GdkEventButton *event, struct cbdata *data, GtkTreeIter *iter) {
|
|||
gdk_event_get_time((GdkEvent*)event));
|
||||
}
|
||||
|
||||
void
|
||||
killmenu(GtkWidget *menu, gpointer *gdata SHUTUP) {
|
||||
gtk_widget_destroy(menu);
|
||||
}
|
||||
|
||||
void
|
||||
actionclick(GtkWidget *widget, gpointer gdata) {
|
||||
struct cbdata *data = gdata;
|
||||
GtkTreeSelection *sel = gtk_tree_view_get_selection(data->view);
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
enum listact act =
|
||||
GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), LIST_ACTION));
|
||||
enum listfrom from =
|
||||
GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), LIST_ACTION_FROM));
|
||||
int index;
|
||||
int index, count;
|
||||
unsigned int actindex;
|
||||
tr_stat_t *sb;
|
||||
GList *ids, *ii;
|
||||
gboolean updatesave;
|
||||
|
||||
/* destroy the popup menu, if any */
|
||||
if(FROM_POPUP == from)
|
||||
gtk_widget_destroy(g_object_get_data(G_OBJECT(widget), LIST_MENU_WIDGET));
|
||||
|
||||
switch(act) {
|
||||
case ACT_OPEN:
|
||||
|
@ -717,54 +771,89 @@ actionclick(GtkWidget *widget, gpointer gdata) {
|
|||
break;
|
||||
}
|
||||
|
||||
index = -1;
|
||||
switch(from) {
|
||||
case FROM_BUTTON:
|
||||
if(gtk_tree_selection_get_selected(sel, &model, &iter))
|
||||
gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
|
||||
MC_ROW_INDEX, &index, -1);
|
||||
ids = NULL;
|
||||
gtk_tree_selection_selected_foreach(sel, makeidlist, &ids);
|
||||
/* XXX should I assert(0 <= index) to insure a row was selected? */
|
||||
break;
|
||||
case FROM_POPUP:
|
||||
index = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), LIST_INDEX));
|
||||
ids = g_object_get_data(G_OBJECT(widget), LIST_INDEX);
|
||||
break;
|
||||
default:
|
||||
assert(!"unknown action source");
|
||||
break;
|
||||
}
|
||||
|
||||
if(0 <= index) {
|
||||
for(actindex = 0; actindex < ALEN(actionitems); actindex++)
|
||||
if(actionitems[actindex].act == act)
|
||||
break;
|
||||
assert(actindex < ALEN(actionitems));
|
||||
|
||||
updatesave = FALSE;
|
||||
count = tr_torrentStat(data->tr, &sb);
|
||||
|
||||
for(ii = g_list_first(ids); NULL != ii; ii = ii->next) {
|
||||
index = GPOINTER_TO_INT(ii->data);
|
||||
if(index >= count) {
|
||||
assert(!"illegal torrent id");
|
||||
continue;
|
||||
}
|
||||
/* check if this action is valid for this torrent */
|
||||
if(actionitems[actindex].nomenu ||
|
||||
(actionitems[actindex].avail &&
|
||||
!(actionitems[actindex].avail & sb[index].status)))
|
||||
continue;
|
||||
|
||||
switch(act) {
|
||||
case ACT_START:
|
||||
tr_torrentStart(data->tr, index);
|
||||
savetorrents(data->tr, data->wind, -1, NULL);
|
||||
updatemodel(data);
|
||||
if(TR_STATUS_STOPPING & sb[index].status)
|
||||
fprintf(stderr, "XXX still running\n");
|
||||
else
|
||||
tr_torrentStart(data->tr, index);
|
||||
updatesave = TRUE;
|
||||
break;
|
||||
case ACT_STOP:
|
||||
tr_torrentStop(data->tr, index);
|
||||
savetorrents(data->tr, data->wind, -1, NULL);
|
||||
updatemodel(data);
|
||||
updatesave = TRUE;
|
||||
break;
|
||||
case ACT_DELETE:
|
||||
/* XXX need to be able to stat just one torrent */
|
||||
if(index >= tr_torrentStat(data->tr, &sb)) {
|
||||
assert(!"XXX i'm tired");
|
||||
}
|
||||
if(TR_TORRENT_NEEDS_STOP(sb[index].status))
|
||||
tr_torrentStop(data->tr, index);
|
||||
free(sb);
|
||||
tr_torrentClose(data->tr, index);
|
||||
savetorrents(data->tr, data->wind, -1, NULL);
|
||||
updatemodel(data);
|
||||
updatesave = TRUE;
|
||||
break;
|
||||
case ACT_INFO:
|
||||
makeinfowind(data, index);
|
||||
makeinfowind(data->wind, data->tr, index);
|
||||
break;
|
||||
default:
|
||||
assert(!"unknown type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(sb);
|
||||
|
||||
if(updatesave) {
|
||||
savetorrents(data->tr, data->wind, -1, NULL);
|
||||
updatemodel(data);
|
||||
}
|
||||
|
||||
if(FROM_BUTTON == from)
|
||||
g_list_free(ids);
|
||||
}
|
||||
|
||||
void
|
||||
doubleclick(GtkWidget *widget SHUTUP, GtkTreePath *path,
|
||||
GtkTreeViewColumn *col SHUTUP, gpointer gdata) {
|
||||
struct cbdata *data = gdata;
|
||||
GtkTreeIter iter;
|
||||
int index;
|
||||
|
||||
if(gtk_tree_model_get_iter(GTK_TREE_MODEL(data->model), &iter, path)) {
|
||||
gtk_tree_model_get(GTK_TREE_MODEL(data->model), &iter,
|
||||
MC_ROW_INDEX, &index, -1);
|
||||
makeinfowind(data->wind, data->tr, index);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
@ -811,138 +900,6 @@ addedtorrents(void *vdata) {
|
|||
savetorrents(data->tr, data->wind, -1, NULL);
|
||||
}
|
||||
|
||||
const char *
|
||||
statusstr(int status) {
|
||||
switch(status) {
|
||||
case TR_STATUS_CHECK: return "check";
|
||||
case TR_STATUS_DOWNLOAD: return "download";
|
||||
case TR_STATUS_SEED: return "seed";
|
||||
case TR_STATUS_STOPPING: return "stopping";
|
||||
case TR_STATUS_STOPPED: return "stopped";
|
||||
case TR_STATUS_PAUSE: return "pause";
|
||||
case TR_TRACKER_ERROR: return "error";
|
||||
default:
|
||||
assert(!"unknown status code");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
makeinfowind(struct cbdata *data, int index) {
|
||||
tr_stat_t *sb;
|
||||
GtkWidget *wind, *table, *name, *value;
|
||||
char buf[32];
|
||||
|
||||
if(index >= tr_torrentStat(data->tr, &sb)) {
|
||||
assert(!"XXX i'm tired");
|
||||
}
|
||||
wind = gtk_dialog_new_with_buttons(sb[index].info.name, data->wind,
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
|
||||
|
||||
table = gtk_table_new(21, 2, FALSE);
|
||||
|
||||
name = gtk_label_new("Torrent File");
|
||||
value = gtk_label_new(sb[index].info.torrent);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 0, 1);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 0, 1);
|
||||
name = gtk_label_new("Name");
|
||||
value = gtk_label_new(sb[index].info.name);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 1, 2);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 1, 2);
|
||||
name = gtk_label_new("Tracker Address");
|
||||
value = gtk_label_new(sb[index].info.trackerAddress);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 2, 3);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 2, 3);
|
||||
name = gtk_label_new("Tracker Port");
|
||||
snprintf(buf, sizeof buf, "%i", sb[index].info.trackerPort);
|
||||
value = gtk_label_new(buf);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 3, 4);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 3, 4);
|
||||
name = gtk_label_new("Tracker Announce URL");
|
||||
value = gtk_label_new(sb[index].info.trackerAnnounce);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 4, 5);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 4, 5);
|
||||
name = gtk_label_new("Piece Size");
|
||||
snprintf(buf, sizeof buf, "%i", sb[index].info.pieceSize);
|
||||
value = gtk_label_new(buf);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 5, 6);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 5, 6);
|
||||
name = gtk_label_new("Piece Count");
|
||||
snprintf(buf, sizeof buf, "%i", sb[index].info.pieceCount);
|
||||
value = gtk_label_new(buf);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 6, 7);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 6, 7);
|
||||
name = gtk_label_new("Total Size");
|
||||
snprintf(buf, sizeof buf, "%llu", sb[index].info.totalSize);
|
||||
value = gtk_label_new(buf);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 7, 8);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 7, 8);
|
||||
name = gtk_label_new("File Count");
|
||||
snprintf(buf, sizeof buf, "%i", sb[index].info.fileCount);
|
||||
value = gtk_label_new(buf);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 8, 9);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 8, 9);
|
||||
name = gtk_label_new("Status");
|
||||
value = gtk_label_new(statusstr(sb[index].status));
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 9, 10);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 9, 10);
|
||||
name = gtk_label_new("Error");
|
||||
value = gtk_label_new(sb[index].error);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 10, 11);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 10, 11);
|
||||
name = gtk_label_new("Progress");
|
||||
snprintf(buf, sizeof buf, "%f", sb[index].progress);
|
||||
value = gtk_label_new(buf);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 11, 12);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 11, 12);
|
||||
name = gtk_label_new("Download Rate");
|
||||
value = gtk_label_new(buf);
|
||||
snprintf(buf, sizeof buf, "%f", sb[index].rateDownload);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 12, 13);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 12, 13);
|
||||
name = gtk_label_new("Upload Rate");
|
||||
snprintf(buf, sizeof buf, "%f", sb[index].rateUpload);
|
||||
value = gtk_label_new(buf);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 13, 14);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 13, 14);
|
||||
name = gtk_label_new("ETA");
|
||||
snprintf(buf, sizeof buf, "%i", sb[index].eta);
|
||||
value = gtk_label_new(buf);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 14, 15);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 14, 15);
|
||||
name = gtk_label_new("Total Peers");
|
||||
snprintf(buf, sizeof buf, "%i", sb[index].peersTotal);
|
||||
value = gtk_label_new(buf);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 15, 16);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 15, 16);
|
||||
name = gtk_label_new("Uploading Peers");
|
||||
snprintf(buf, sizeof buf, "%i", sb[index].peersUploading);
|
||||
value = gtk_label_new(buf);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 16, 17);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 16, 17);
|
||||
name = gtk_label_new("Downloading Peers");
|
||||
snprintf(buf, sizeof buf, "%i", sb[index].peersDownloading);
|
||||
value = gtk_label_new(buf);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 17, 18);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 17, 18);
|
||||
name = gtk_label_new("Downloaded");
|
||||
snprintf(buf, sizeof buf, "%llu", sb[index].downloaded);
|
||||
value = gtk_label_new(buf);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 18, 19);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 18, 19);
|
||||
name = gtk_label_new("Uploaded");
|
||||
snprintf(buf, sizeof buf, "%llu", sb[index].uploaded);
|
||||
value = gtk_label_new(buf);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), name, 0, 1, 19, 20);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), value, 1, 2, 19, 20);
|
||||
|
||||
gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(wind)->vbox), table);
|
||||
g_signal_connect(G_OBJECT(wind), "response",
|
||||
G_CALLBACK(gtk_widget_destroy), NULL);
|
||||
gtk_widget_show_all(wind);
|
||||
free(sb);
|
||||
}
|
||||
|
||||
gboolean
|
||||
savetorrents(tr_handle_t *tr, GtkWindow *wind, int count, tr_stat_t *stat) {
|
||||
char *errstr;
|
||||
|
@ -966,3 +923,24 @@ savetorrents(tr_handle_t *tr, GtkWindow *wind, int count, tr_stat_t *stat) {
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* use with gtk_tree_selection_selected_foreach to | status of selected rows */
|
||||
void
|
||||
orstatus(GtkTreeModel *model, GtkTreePath *path SHUTUP, GtkTreeIter *iter,
|
||||
gpointer gdata) {
|
||||
int *allstatus = gdata;
|
||||
int status;
|
||||
|
||||
gtk_tree_model_get(model, iter, MC_STAT, &status, -1);
|
||||
*allstatus |= status;
|
||||
}
|
||||
|
||||
void
|
||||
makeidlist(GtkTreeModel *model, GtkTreePath *path SHUTUP, GtkTreeIter *iter,
|
||||
gpointer gdata) {
|
||||
GList **ids = gdata;
|
||||
int index;
|
||||
|
||||
gtk_tree_model_get(model, iter, MC_ROW_INDEX, &index, -1);
|
||||
*ids = g_list_append(*ids, GINT_TO_POINTER(index));
|
||||
}
|
||||
|
|
96
gtk/prefs.c
96
gtk/prefs.c
|
@ -24,6 +24,7 @@
|
|||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -306,3 +307,98 @@ addresp(GtkWidget *widget, gint resp, gpointer gdata) {
|
|||
|
||||
gtk_widget_destroy(widget);
|
||||
}
|
||||
|
||||
#define INFOLINE(tab, ii, nam, val) \
|
||||
do { \
|
||||
GtkWidget *wid = gtk_label_new(NULL); \
|
||||
gtk_misc_set_alignment(GTK_MISC(wid), 1, .5); \
|
||||
gtk_label_set_markup(GTK_LABEL(wid), "<b>" nam ":</b>"); \
|
||||
gtk_table_attach_defaults(GTK_TABLE(tab), wid, 0, 1, ii, ii + 1); \
|
||||
wid = gtk_label_new(val); \
|
||||
gtk_misc_set_alignment(GTK_MISC(wid), 0, .5); \
|
||||
gtk_table_attach_defaults(GTK_TABLE(tab), wid, 1, 2, ii, ii + 1); \
|
||||
ii++; \
|
||||
} while(0);
|
||||
|
||||
#define INFOLINEF(tab, ii, fmt, nam, val) \
|
||||
do { \
|
||||
char *buf = g_strdup_printf(fmt, val); \
|
||||
INFOLINE(tab, ii, nam, buf); \
|
||||
g_free(buf); \
|
||||
} while(0);
|
||||
|
||||
#define INFOLINEA(tab, ii, nam, val) \
|
||||
do { \
|
||||
char *buf = val; \
|
||||
INFOLINE(tab, ii, nam, buf); \
|
||||
g_free(buf); \
|
||||
} while(0);
|
||||
|
||||
#define INFOSEP(tab, ii) \
|
||||
do { \
|
||||
GtkWidget *wid = gtk_hseparator_new(); \
|
||||
gtk_table_attach_defaults(GTK_TABLE(tab), wid, 0, 2, ii, ii + 1); \
|
||||
ii++; \
|
||||
} while(0);
|
||||
|
||||
#define INFOSTATUS(st) \
|
||||
(TR_STATUS_CHECK & (st) ? "check" : \
|
||||
(TR_STATUS_DOWNLOAD & (st) ? "download" : \
|
||||
(TR_STATUS_SEED & (st) ? "seed" : \
|
||||
(TR_STATUS_STOPPING & (st) ? "stopping" : \
|
||||
(TR_STATUS_STOPPED & (st) ? "stopped" : \
|
||||
(TR_STATUS_PAUSE & (st) ? "pause" : \
|
||||
"???"))))))
|
||||
|
||||
void
|
||||
makeinfowind(GtkWindow *parent, tr_handle_t *tr, int id) {
|
||||
tr_stat_t *sb;
|
||||
GtkWidget *wind, *table, *label;
|
||||
int ii;
|
||||
char *str;
|
||||
const int rowcount = 11;
|
||||
|
||||
/* XXX would be nice to be able to stat just one */
|
||||
if(id >= tr_torrentStat(tr, &sb))
|
||||
assert(!"XXX ");
|
||||
str = g_strdup_printf("%s Properties", sb[id].info.name);
|
||||
wind = gtk_dialog_new_with_buttons(str, parent,
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
|
||||
g_free(str);
|
||||
|
||||
table = gtk_table_new(rowcount, 2, FALSE);
|
||||
gtk_table_set_col_spacings(GTK_TABLE(table), 10);
|
||||
gtk_table_set_row_spacings(GTK_TABLE(table), 10);
|
||||
|
||||
label = gtk_label_new(NULL);
|
||||
str = g_markup_printf_escaped("<big>%s</big>", sb[id].info.name);
|
||||
gtk_label_set_markup(GTK_LABEL(label), str);
|
||||
g_free(str);
|
||||
gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 2, 0, 1);
|
||||
|
||||
ii = 1;
|
||||
|
||||
INFOSEP(table, ii);
|
||||
|
||||
INFOLINEA(table, ii, "Tracker", g_strdup_printf("http://%s:%i",
|
||||
sb[id].info.trackerAddress, sb[id].info.trackerPort));
|
||||
INFOLINE(table, ii, "Announce", sb[id].info.trackerAnnounce);
|
||||
INFOLINEA(table, ii, "Piece Size", readablesize(sb[id].info.pieceSize, 1));
|
||||
INFOLINEF(table, ii, "%i", "Pieces", sb[id].info.pieceCount);
|
||||
INFOLINEA(table, ii, "Total Size", readablesize(sb[id].info.totalSize, 1));
|
||||
|
||||
INFOSEP(table, ii);
|
||||
|
||||
INFOLINE(table, ii, "Directory", sb[id].folder);
|
||||
INFOLINEA(table, ii, "Downloaded", readablesize(sb[id].downloaded, 1));
|
||||
INFOLINEA(table, ii, "Uploaded", readablesize(sb[id].uploaded, 1));
|
||||
|
||||
assert(rowcount == ii);
|
||||
|
||||
gtk_container_set_border_width(GTK_CONTAINER(table), 10);
|
||||
gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(wind)->vbox), table);
|
||||
g_signal_connect(G_OBJECT(wind), "response",
|
||||
G_CALLBACK(gtk_widget_destroy), NULL);
|
||||
gtk_widget_show_all(wind);
|
||||
free(sb);
|
||||
}
|
||||
|
|
|
@ -52,4 +52,8 @@ void
|
|||
makeaddwind(add_torrent_func_t addfunc, GtkWindow *parent, tr_handle_t *tr,
|
||||
torrents_added_func_t donefunc, void *donedata);
|
||||
|
||||
/* show the info window for a torrent */
|
||||
void
|
||||
makeinfowind(GtkWindow *parent, tr_handle_t *tr, int index);
|
||||
|
||||
#endif /* TG_PREFS_H */
|
||||
|
|
Loading…
Reference in a new issue