From a007678f344943d6ea86392723004a3a72320d9e Mon Sep 17 00:00:00 2001 From: Alan Fitton Date: Wed, 4 Jan 2012 10:40:44 +0000 Subject: make the torrent add tree view and the files tree view fairly consistent, sharing code where possible. this allows changing priority and enabled using a directory. expand/collapse all buttons. the one taken from Transmission for torrent add dialog now has menus and the mime icons. may be bugs here, I know there's one with directories appearing as mixed and not updating upwards properly, but it's a start. --- src/Makefile.am | 3 + src/protocol-constants.h | 4 +- src/trg-cell-renderer-priority.c | 2 +- src/trg-cell-renderer-priority.h | 1 - src/trg-cell-renderer-wanted.c | 117 +++++++ src/trg-cell-renderer-wanted.h | 51 +++ src/trg-client.c | 7 +- src/trg-files-model-common.c | 192 +++++++++++ src/trg-files-model-common.h | 33 ++ src/trg-files-model.c | 55 ++- src/trg-files-tree-view-common.c | 199 +++++++++++ src/trg-files-tree-view-common.h | 32 ++ src/trg-files-tree-view.c | 267 ++++----------- src/trg-files-tree-view.h | 16 + src/trg-torrent-add-dialog.c | 709 ++++++++++++--------------------------- src/trg-tree-view.c | 11 +- src/trg-tree-view.h | 2 +- 17 files changed, 958 insertions(+), 743 deletions(-) create mode 100644 src/trg-cell-renderer-wanted.c create mode 100644 src/trg-cell-renderer-wanted.h create mode 100644 src/trg-files-model-common.c create mode 100644 src/trg-files-model-common.h create mode 100644 src/trg-files-tree-view-common.c create mode 100644 src/trg-files-tree-view-common.h diff --git a/src/Makefile.am b/src/Makefile.am index 9ec2231..36df2fc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -63,9 +63,11 @@ transmission_remote_gtk_SOURCES = main.c \ trg-sortable-filtered-model.c \ trg-peers-model.c \ trg-peers-tree-view.c \ + trg-files-model-common.c \ trg-model.c \ trg-persistent-tree-view.c \ trg-files-model.c \ + trg-files-tree-view-common.c \ trg-files-tree-view.c \ trg-state-selector.c \ trg-general-panel.c \ @@ -85,6 +87,7 @@ transmission_remote_gtk_SOURCES = main.c \ trg-cell-renderer-eta.c \ trg-remote-prefs-dialog.c \ trg-cell-renderer-priority.c \ + trg-cell-renderer-wanted.c \ trg-cell-renderer-file-icon.c \ trg-cell-renderer-epoch.c \ trg-cell-renderer-numgteqthan.c \ diff --git a/src/protocol-constants.h b/src/protocol-constants.h index 94471ad..f3f9b1d 100644 --- a/src/protocol-constants.h +++ b/src/protocol-constants.h @@ -182,8 +182,8 @@ typedef enum { } tr_torrent_activity; enum { - TR_PRI_UNSET = -3, - TR_PRI_MIXED = -2, + TR_PRI_UNSET = -3, // Not actually in the protocol. Just used in UI. + TR_PRI_MIXED = -2, // Neither is this. TR_PRI_LOW = -1, TR_PRI_NORMAL = 0, /* since NORMAL is 0, memset initializes nicely */ TR_PRI_HIGH = 1 diff --git a/src/trg-cell-renderer-priority.c b/src/trg-cell-renderer-priority.c index 9d1f7ad..7714267 100644 --- a/src/trg-cell-renderer-priority.c +++ b/src/trg-cell-renderer-priority.c @@ -112,7 +112,7 @@ trg_cell_renderer_priority_class_init(TrgCellRendererPriorityClass * klass) static void trg_cell_renderer_priority_init(TrgCellRendererPriority * - self G_GNUC_UNUSED) + self) { } diff --git a/src/trg-cell-renderer-priority.h b/src/trg-cell-renderer-priority.h index dd33c11..7813053 100644 --- a/src/trg-cell-renderer-priority.h +++ b/src/trg-cell-renderer-priority.h @@ -17,7 +17,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ - #ifndef TRG_CELL_RENDERER_PRIORITY_H_ #define TRG_CELL_RENDERER_PRIORITY_H_ diff --git a/src/trg-cell-renderer-wanted.c b/src/trg-cell-renderer-wanted.c new file mode 100644 index 0000000..aeb4ab9 --- /dev/null +++ b/src/trg-cell-renderer-wanted.c @@ -0,0 +1,117 @@ +/* + * transmission-remote-gtk - A GTK RPC client to Transmission + * Copyright (C) 2011 Alan Fitton + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include + +#include "trg-cell-renderer-wanted.h" +#include "protocol-constants.h" +#include "trg-files-model.h" +#include "util.h" + +enum { + PROP_0, + PROP_WANTED_VALUE +}; + +G_DEFINE_TYPE(TrgCellRendererWanted, trg_cell_renderer_wanted, + GTK_TYPE_CELL_RENDERER_TOGGLE) +#define TRG_CELL_RENDERER_WANTED_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRG_TYPE_CELL_RENDERER_WANTED, TrgCellRendererWantedPrivate)) +typedef struct _TrgCellRendererWantedPrivate + TrgCellRendererWantedPrivate; + +struct _TrgCellRendererWantedPrivate { + gint64 wanted_value; +}; + +static void +trg_cell_renderer_wanted_get_property(GObject * object, + guint property_id, GValue * value, + GParamSpec * pspec) +{ + TrgCellRendererWantedPrivate *priv = + TRG_CELL_RENDERER_WANTED_GET_PRIVATE(object); + switch (property_id) { + case PROP_WANTED_VALUE: + g_value_set_int64(value, priv->wanted_value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void +trg_cell_renderer_wanted_set_property(GObject * object, + guint property_id, + const GValue * value, + GParamSpec * pspec) +{ + TrgCellRendererWantedPrivate *priv = + TRG_CELL_RENDERER_WANTED_GET_PRIVATE(object); + + if (property_id == PROP_WANTED_VALUE) { + priv->wanted_value = g_value_get_int(value); + g_object_set(G_OBJECT(object), "inconsistent", (priv->wanted_value == TR_PRI_MIXED), + "active", (priv->wanted_value == TRUE), NULL); + } else { + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + } +} + +static void +trg_cell_renderer_wanted_class_init(TrgCellRendererWantedClass * klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + object_class->get_property = trg_cell_renderer_wanted_get_property; + object_class->set_property = trg_cell_renderer_wanted_set_property; + + g_object_class_install_property(object_class, + PROP_WANTED_VALUE, + g_param_spec_int + ("wanted-value", + "Wanted Value", + "Wanted Value", TR_PRI_UNSET, + TR_PRI_HIGH, TR_PRI_NORMAL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + g_type_class_add_private(klass, + sizeof(TrgCellRendererWantedPrivate)); +} + +static void +trg_cell_renderer_wanted_init(TrgCellRendererWanted * + self) +{ + /*g_object_set(G_OBJECT(self), "xalign", (gfloat) 0.5, "yalign", (gfloat) 0.5, + NULL);*/ +} + +GtkCellRenderer *trg_cell_renderer_wanted_new(void) +{ + return + GTK_CELL_RENDERER(g_object_new + (TRG_TYPE_CELL_RENDERER_WANTED, NULL)); +} diff --git a/src/trg-cell-renderer-wanted.h b/src/trg-cell-renderer-wanted.h new file mode 100644 index 0000000..6a48f4c --- /dev/null +++ b/src/trg-cell-renderer-wanted.h @@ -0,0 +1,51 @@ +/* + * transmission-remote-gtk - A GTK RPC client to Transmission + * Copyright (C) 2011 Alan Fitton + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef TRG_CELL_RENDERER_WANTED_H_ +#define TRG_CELL_RENDERER_WANTED_H_ + +#include +#include + +G_BEGIN_DECLS +#define TRG_TYPE_CELL_RENDERER_WANTED trg_cell_renderer_wanted_get_type() +#define TRG_CELL_RENDERER_WANTED(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), TRG_TYPE_CELL_RENDERER_WANTED, TrgCellRendererWanted)) +#define TRG_CELL_RENDERER_WANTED_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), TRG_TYPE_CELL_RENDERER_WANTED, TrgCellRendererWantedClass)) +#define TRG_IS_CELL_RENDERER_WANTED(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TRG_TYPE_CELL_RENDERER_WANTED)) +#define TRG_IS_CELL_RENDERER_WANTED_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), TRG_TYPE_CELL_RENDERER_WANTED)) +#define TRG_CELL_RENDERER_WANTED_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), TRG_TYPE_CELL_RENDERER_WANTED, TrgCellRendererWantedClass)) + typedef struct { + GtkCellRendererToggle parent; +} TrgCellRendererWanted; + +typedef struct { + GtkCellRendererToggleClass parent_class; +} TrgCellRendererWantedClass; + +GType trg_cell_renderer_wanted_get_type(void); + +GtkCellRenderer *trg_cell_renderer_wanted_new(void); + +G_END_DECLS +#endif /* TRG_CELL_RENDERER_WANTED_H_ */ diff --git a/src/trg-client.c b/src/trg-client.c index 05cd148..0b1d1f6 100644 --- a/src/trg-client.c +++ b/src/trg-client.c @@ -443,14 +443,11 @@ static size_t header_callback(void *ptr, size_t size, size_t nmemb, void *data) } static void trg_tls_update(TrgClient * tc, trg_tls * tls, gint serial) { - TrgPrefs *prefs = trg_client_get_prefs(tc); gchar *proxy; curl_easy_setopt(tls->curl, CURLOPT_PASSWORD, trg_client_get_password(tc)); curl_easy_setopt(tls->curl, CURLOPT_USERNAME, trg_client_get_username(tc)); curl_easy_setopt(tls->curl, CURLOPT_URL, trg_client_get_url(tc)); - curl_easy_setopt(tls->curl, CURLOPT_TIMEOUT, - trg_prefs_get_int(prefs, TRG_PREFS_KEY_TIMEOUT, TRG_PREFS_CONNECTION)); #ifndef CURL_NO_SSL if (trg_client_get_ssl(tc)) @@ -484,6 +481,7 @@ trg_tls *trg_tls_new(TrgClient * tc) { static int trg_http_perform_inner(TrgClient * tc, gchar * reqstr, trg_response * response, gboolean recurse) { TrgClientPrivate *priv = TRG_CLIENT_GET_PRIVATE(tc); + TrgPrefs *prefs = trg_client_get_prefs(tc); gpointer threadLocalStorage = g_private_get(priv->tlsKey); trg_tls *tls; long httpCode = 0; @@ -508,6 +506,9 @@ static int trg_http_perform_inner(TrgClient * tc, gchar * reqstr, curl_easy_setopt(tls->curl, CURLOPT_HTTPHEADER, headers); } + curl_easy_setopt(tls->curl, CURLOPT_TIMEOUT, + (long)trg_prefs_get_int(prefs, TRG_PREFS_KEY_TIMEOUT, TRG_PREFS_CONNECTION)); + g_mutex_unlock(priv->configMutex); response->size = 0; diff --git a/src/trg-files-model-common.c b/src/trg-files-model-common.c new file mode 100644 index 0000000..5cf16a3 --- /dev/null +++ b/src/trg-files-model-common.c @@ -0,0 +1,192 @@ +/* + * transmission-remote-gtk - A GTK RPC client to Transmission + * Copyright (C) 2011 Alan Fitton + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include + +#include +#include +#include + +#include "protocol-constants.h" +#include "trg-files-model-common.h" + +struct SubtreeForeachData { + gint column; + gint new_value; + GtkTreePath *path; +}; + +static void set_wanted_foreachfunc(GtkTreeModel * model, + GtkTreePath * path G_GNUC_UNUSED, GtkTreeIter * iter, gpointer data) { + struct SubtreeForeachData* args = (struct SubtreeForeachData*) data; + + gtk_tree_store_set(GTK_TREE_STORE(model), iter, args->column, + args->new_value, -1); + + trg_files_tree_model_setSubtree(model, path, iter, args->column, + args->new_value); +} + +static void set_priority_foreachfunc(GtkTreeModel * model, GtkTreePath * path, + GtkTreeIter * iter, gpointer data) { + struct SubtreeForeachData* args = (struct SubtreeForeachData*) data; + GValue value = { 0 }; + + g_value_init(&value, G_TYPE_INT); + g_value_set_int(&value, args->new_value); + + gtk_tree_store_set_value(GTK_TREE_STORE(model), iter, args->column, &value); + + trg_files_tree_model_setSubtree(model, path, iter, args->column, + args->new_value); +} + +void trg_files_model_set_wanted(GtkTreeView *tv, gint column, + gint new_value) { + struct SubtreeForeachData args; + GtkTreeSelection *selection = gtk_tree_view_get_selection(tv); + + args.column = column; + args.new_value = new_value; + + gtk_tree_selection_selected_foreach(selection, set_wanted_foreachfunc, + &args); +} + +void trg_files_tree_model_set_priority(GtkTreeView *tv, gint column, + gint new_value) { + struct SubtreeForeachData args; + GtkTreeSelection *selection = gtk_tree_view_get_selection(tv); + + args.column = column; + args.new_value = new_value; + + gtk_tree_selection_selected_foreach(selection, set_priority_foreachfunc, + &args); + +} + +static gboolean setSubtreeForeach(GtkTreeModel * model, GtkTreePath * path, + GtkTreeIter * iter, gpointer gdata) { + struct SubtreeForeachData *data = gdata; + + if (!gtk_tree_path_compare(path, data->path) + || gtk_tree_path_is_descendant(path, data->path)) { + GValue value = { 0 }; + + g_value_init(&value, G_TYPE_INT); + g_value_set_int(&value, data->new_value); + + gtk_tree_store_set_value(GTK_TREE_STORE(model), iter, data->column, + &value); + } + + return FALSE; /* keep walking */ +} + +void trg_files_tree_model_propogateChangeUp(GtkTreeModel * model, + GtkTreeIter * iter, gint column, gint new_value) { + GtkTreeIter back_iter = *iter; + gint result; + + while (1) { + GtkTreeIter tmp_iter; + gint n_children, i; + + if (!gtk_tree_model_iter_parent(model, &tmp_iter, &back_iter)) + break; + + n_children = gtk_tree_model_iter_n_children(model, &tmp_iter); + + for (i = 0; i < n_children; i++) { + GtkTreeIter child; + gint current_value; + + if (!gtk_tree_model_iter_nth_child(model, &child, &tmp_iter, i)) + continue; + + gtk_tree_model_get(model, &child, column, ¤t_value, -1); + if (current_value != new_value) { + result = TR_PRI_MIXED; + break; + } + } + + gtk_tree_store_set(GTK_TREE_STORE(model), &tmp_iter, column, result, + -1); + + back_iter = tmp_iter; + } +} + +void trg_files_tree_model_setSubtree(GtkTreeModel * model, GtkTreePath * path, + GtkTreeIter * iter, gint column, gint new_value) { + GtkTreeIter back_iter = *iter; + + if (gtk_tree_model_iter_has_child(model, iter)) { + struct SubtreeForeachData tmp; + GtkTreeIter parent; + + tmp.column = column; + tmp.new_value = new_value; + tmp.path = path; + + gtk_tree_model_foreach(model, setSubtreeForeach, &tmp); + gtk_tree_model_iter_parent(model, &parent, iter); + } else { + gtk_tree_store_set(GTK_TREE_STORE(model), &back_iter, column, new_value, + -1); + } + + trg_files_tree_model_propogateChangeUp(model, iter, column, new_value); +} + +struct UpdateParentsSizeForeachData { + gint size_column; + GtkTreeIter *descendent_iter; +}; + +static gboolean trg_files_model_update_parents_size_foreach(GtkTreeModel *model, + GtkTreePath *path, GtkTreeIter *iter, gpointer data) { + struct UpdateParentsSizeForeachData *args = (struct UpdateParentsSizeForeachData*)data; + + GtkTreePath *descendentPath = gtk_tree_model_get_path(model, + args->descendent_iter); + + if (gtk_tree_path_is_ancestor(path, descendentPath) + && gtk_tree_model_get_iter(model, args->descendent_iter, descendentPath)) { + gint64 size, oldSize; + gtk_tree_model_get(model, args->descendent_iter, args->size_column, &size, -1); + gtk_tree_model_get(model, iter, args->size_column, &oldSize, -1); + gtk_tree_store_set(GTK_TREE_STORE(model), iter, args->size_column, + size + oldSize, -1); + } + + gtk_tree_path_free(descendentPath); + + return FALSE; +} + +void trg_files_model_update_parents(GtkTreeModel *model, GtkTreeIter *iter, gint size_column) { + struct UpdateParentsSizeForeachData args; + args.descendent_iter = iter; + args.size_column = size_column; + gtk_tree_model_foreach(model, + trg_files_model_update_parents_size_foreach, &args); +} diff --git a/src/trg-files-model-common.h b/src/trg-files-model-common.h new file mode 100644 index 0000000..0ba3d63 --- /dev/null +++ b/src/trg-files-model-common.h @@ -0,0 +1,33 @@ +/* + * transmission-remote-gtk - A GTK RPC client to Transmission + * Copyright (C) 2011 Alan Fitton + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef TRG_FILES_TREE_MODEL_COMMON_H_ +#define TRG_FILES_TREE_MODEL_COMMON_H_ + +void trg_files_tree_model_propogateChangeUp(GtkTreeModel * model, GtkTreeIter * iter, gint column, gint new_value); +void +trg_files_tree_model_setSubtree(GtkTreeModel * model, GtkTreePath * path, GtkTreeIter * iter, + gint column, gint new_value); +void trg_files_tree_model_set_priority(GtkTreeView *tv, gint column, gint new_value); +void trg_files_model_set_wanted(GtkTreeView *tv, gint column, gint new_value); +gboolean trg_files_model_update_parent_size(GtkTreeModel *model, + GtkTreePath *path, GtkTreeIter *iter, gpointer data); +void trg_files_model_update_parents(GtkTreeModel *model, GtkTreeIter *iter, gint size_column); + +#endif /* TRG_FILES_TREE_MODEL_COMMON_H_ */ diff --git a/src/trg-files-model.c b/src/trg-files-model.c index b58f62f..6390b61 100644 --- a/src/trg-files-model.c +++ b/src/trg-files-model.c @@ -22,6 +22,8 @@ #include #include "protocol-constants.h" +#include "trg-files-model-common.h" +#include "trg-files-tree-view-common.h" #include "trg-files-model.h" #include "trg-client.h" #include "torrent.h" @@ -60,26 +62,6 @@ static void rowref_to_iter(GtkTreeModel *model, GtkTreeRowReference *rr, gtk_tree_path_free(path); } -static gboolean trg_files_update_new_parents(GtkTreeModel *model, - GtkTreePath *path, GtkTreeIter *iter, gpointer data) { - GtkTreeIter *descendentIter = (GtkTreeIter*) data; - GtkTreePath *descendentPath = gtk_tree_model_get_path(model, - descendentIter); - - if (gtk_tree_path_is_ancestor(path, descendentPath) - && gtk_tree_model_get_iter(model, descendentIter, descendentPath)) { - gint64 size, oldSize; - gtk_tree_model_get(model, descendentIter, FILESCOL_SIZE, &size, -1); - gtk_tree_model_get(model, iter, FILESCOL_SIZE, &oldSize, -1); - gtk_tree_store_set(GTK_TREE_STORE(model), iter, FILESCOL_SIZE, - size + oldSize, -1); - } - - gtk_tree_path_free(descendentPath); - - return FALSE; -} - struct updateAllArgs { GtkTreeIter *descendentIter; gint64 increment; @@ -134,10 +116,8 @@ static void trg_files_model_iter_new(TrgFilesModel * model, GtkTreeIter * iter, elements[i], FILESCOL_SIZE, file_get_length(file), FILESCOL_ID, id, -1); - if (parentRowRef) { - gtk_tree_model_foreach(GTK_TREE_MODEL(model), - trg_files_update_new_parents, iter); - } + if (parentRowRef) + trg_files_model_update_parents(GTK_TREE_MODEL(model), iter, FILESCOL_SIZE); break; } @@ -169,8 +149,9 @@ static void trg_files_model_iter_new(TrgFilesModel * model, GtkTreeIter * iter, gtk_tree_store_append(GTK_TREE_STORE(model), iter, parentRowRef ? &parentIter : NULL); - gtk_tree_store_set(GTK_TREE_STORE(model), iter, FILESCOL_NAME, - elements[i], -1); + gtk_tree_store_set(GTK_TREE_STORE(model), iter, + FILESCOL_PRIORITY, TR_PRI_UNSET, + FILESCOL_NAME, elements[i], -1); g_value_init(&gvalue, G_TYPE_INT); g_value_set_int(&gvalue, -1); @@ -178,8 +159,8 @@ static void trg_files_model_iter_new(TrgFilesModel * model, GtkTreeIter * iter, &gvalue); memset(&gvalue, 0, sizeof(GValue)); - g_value_init(&gvalue, G_TYPE_INT64); - g_value_set_int64(&gvalue, TR_PRI_UNSET); + g_value_init(&gvalue, G_TYPE_INT); + g_value_set_int(&gvalue, TR_PRI_UNSET); gtk_tree_store_set_value(GTK_TREE_STORE(model), iter, FILESCOL_PRIORITY, &gvalue); @@ -209,7 +190,7 @@ static void trg_files_model_iter_update(TrgFilesModel * model, gboolean wanted = json_node_get_int(json_array_get_element(wantedArray, id)) == 1; - gint64 priority = json_node_get_int( + gint priority = (gint)json_node_get_int( json_array_get_element(prioritiesArray, id)); gdouble progress = file_get_progress(fileLength, fileCompleted); @@ -233,12 +214,14 @@ static void trg_files_model_iter_update(TrgFilesModel * model, trg_files_update_all_parents, &args); } - if (priv->accept) { - gtk_tree_store_set(GTK_TREE_STORE(model), filesIter, FILESCOL_WANTED, - wanted ? GTK_STOCK_APPLY : GTK_STOCK_CANCEL - , FILESCOL_PRIORITY, priority, -1); - + if (isFirst) { + trg_files_tree_model_propogateChangeUp(GTK_TREE_MODEL(model), filesIter, FILESCOL_PRIORITY, priority); + trg_files_tree_model_propogateChangeUp(GTK_TREE_MODEL(model), filesIter, FILESCOL_WANTED, wanted); } + + if (priv->accept) + gtk_tree_store_set(GTK_TREE_STORE(model), filesIter, FILESCOL_WANTED, + wanted, FILESCOL_PRIORITY, priority, -1); } static void trg_files_model_class_init(TrgFilesModelClass * klass) { @@ -255,8 +238,8 @@ static void trg_files_model_init(TrgFilesModel * self) { column_types[FILESCOL_SIZE] = G_TYPE_INT64; column_types[FILESCOL_PROGRESS] = G_TYPE_DOUBLE; column_types[FILESCOL_ID] = G_TYPE_INT; - column_types[FILESCOL_WANTED] = G_TYPE_STRING; - column_types[FILESCOL_PRIORITY] = G_TYPE_INT64; + column_types[FILESCOL_WANTED] = G_TYPE_INT; + column_types[FILESCOL_PRIORITY] = G_TYPE_INT; column_types[FILESCOL_BYTESCOMPLETED] = G_TYPE_INT64; gtk_tree_store_set_column_types(GTK_TREE_STORE(self), FILESCOL_COLUMNS, diff --git a/src/trg-files-tree-view-common.c b/src/trg-files-tree-view-common.c new file mode 100644 index 0000000..319d77d --- /dev/null +++ b/src/trg-files-tree-view-common.c @@ -0,0 +1,199 @@ +/* + * transmission-remote-gtk - A GTK RPC client to Transmission + * Copyright (C) 2011 Alan Fitton + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include + +#include +#include +#include + +#include "protocol-constants.h" +#include "trg-files-model-common.h" +#include "trg-files-tree-view-common.h" + +static void expand_all_cb(GtkWidget *w, gpointer data) +{ + gtk_tree_view_expand_all(GTK_TREE_VIEW(data)); +} + +static void collapse_all_cb(GtkWidget *w, gpointer data) +{ + gtk_tree_view_collapse_all(GTK_TREE_VIEW(data)); +} + +static void view_popup_menu(GtkWidget * treeview, GdkEventButton * event, + GCallback low_cb, GCallback normal_cb, GCallback high_cb, + GCallback wanted_cb, GCallback unwanted_cb, gpointer data G_GNUC_UNUSED) { + GtkWidget *menu, *menuitem; + + menu = gtk_menu_new(); + + menuitem = gtk_menu_item_new_with_label(_("High Priority")); + g_signal_connect(menuitem, "activate", high_cb, treeview); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + + menuitem = gtk_menu_item_new_with_label(_("Normal Priority")); + g_signal_connect(menuitem, "activate", normal_cb, treeview); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + + menuitem = gtk_menu_item_new_with_label(_("Low Priority")); + g_signal_connect(menuitem, "activate", low_cb, treeview); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + + gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new()); + + menuitem = gtk_image_menu_item_new_with_label(GTK_STOCK_APPLY); + gtk_image_menu_item_set_use_stock(GTK_IMAGE_MENU_ITEM(menuitem), TRUE); + gtk_image_menu_item_set_always_show_image(GTK_IMAGE_MENU_ITEM + (menuitem), TRUE); + gtk_menu_item_set_label(GTK_MENU_ITEM(menuitem), _("Download")); + g_signal_connect(menuitem, "activate", wanted_cb, treeview); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + + menuitem = gtk_image_menu_item_new_with_label(GTK_STOCK_CANCEL); + gtk_image_menu_item_set_use_stock(GTK_IMAGE_MENU_ITEM(menuitem), TRUE); + gtk_image_menu_item_set_always_show_image(GTK_IMAGE_MENU_ITEM + (menuitem), TRUE); + gtk_menu_item_set_label(GTK_MENU_ITEM(menuitem), _("Skip")); + g_signal_connect(menuitem, "activate", unwanted_cb, treeview); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + + gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new()); + + menuitem = gtk_image_menu_item_new_with_label(_("Expand All")); + g_signal_connect(menuitem, "activate", G_CALLBACK(expand_all_cb), treeview); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + + menuitem = gtk_image_menu_item_new_with_label(_("Collapse All")); + g_signal_connect(menuitem, "activate", G_CALLBACK(collapse_all_cb), treeview); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + + gtk_widget_show_all(menu); + + gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, + (event != NULL) ? event->button : 0, + gdk_event_get_time((GdkEvent *) event)); + } + +gboolean trg_files_tree_view_viewOnPopupMenu(GtkWidget * treeview, + GCallback low_cb, GCallback normal_cb, GCallback high_cb, + GCallback wanted_cb, GCallback unwanted_cb, gpointer userdata) { + view_popup_menu(treeview, NULL, low_cb, normal_cb, high_cb, wanted_cb, + unwanted_cb, userdata); + return TRUE; +} + +static gboolean onViewPathToggled(GtkTreeView * view, GtkTreeViewColumn * col, + GtkTreePath * path, gint pri_id, gint enabled_id, gpointer data) { + int cid; + gboolean handled = FALSE; + + if (!col || !path) + return FALSE; + + cid = gtk_tree_view_column_get_sort_column_id(col); + if ((cid == pri_id) || (cid == enabled_id)) { + GtkTreeIter iter; + GtkTreeModel *model = gtk_tree_view_get_model(view); + + gtk_tree_model_get_iter(model, &iter, path); + + if (cid == pri_id) { + int priority; + gtk_tree_model_get(model, &iter, pri_id, &priority, -1); + switch (priority) { + case TR_PRI_NORMAL: + priority = TR_PRI_HIGH; + break; + case TR_PRI_HIGH: + priority = TR_PRI_LOW; + break; + default: + priority = TR_PRI_NORMAL; + break; + } + trg_files_tree_model_setSubtree(model, path, &iter, pri_id, + priority); + } else { + int enabled; + gtk_tree_model_get(model, &iter, enabled_id, &enabled, -1); + enabled = !enabled; + + trg_files_tree_model_setSubtree(model, path, &iter, enabled_id, + enabled); + } + + handled = TRUE; + } + + return handled; +} + +static gboolean getAndSelectEventPath(GtkTreeView * treeview, + GdkEventButton * event, GtkTreeViewColumn ** col, GtkTreePath ** path) { + GtkTreeSelection *sel; + + if (gtk_tree_view_get_path_at_pos(treeview, event->x, event->y, path, col, + NULL, NULL)) { + sel = gtk_tree_view_get_selection(treeview); + if (!gtk_tree_selection_path_is_selected(sel, *path)) { + gtk_tree_selection_unselect_all(sel); + gtk_tree_selection_select_path(sel, *path); + } + return TRUE; + } + + return FALSE; +} + +gboolean trg_files_tree_view_onViewButtonPressed(GtkWidget * w, + GdkEventButton * event, gint pri_id, gint enabled_id, GCallback low_cb, + GCallback normal_cb, GCallback high_cb, GCallback wanted_cb, + GCallback unwanted_cb, gpointer gdata) { + GtkTreeViewColumn *col = NULL; + GtkTreePath *path = NULL; + GtkTreeSelection *selection; + gboolean handled = FALSE; + GtkTreeView *treeview = GTK_TREE_VIEW(w); + + if (event->type == GDK_BUTTON_PRESS && event->button == 1 + && !(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) + && getAndSelectEventPath(treeview, event, &col, &path)) { + handled = onViewPathToggled(treeview, col, path, pri_id, enabled_id, + NULL); + } else if (event->type == GDK_BUTTON_PRESS && event->button == 3) { + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); + + if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(treeview), + (gint) event->x, (gint) event->y, &path, NULL, NULL, NULL)) { + if (!gtk_tree_selection_path_is_selected(selection, path)) { + gtk_tree_selection_unselect_all(selection); + gtk_tree_selection_select_path(selection, path); + } + + view_popup_menu(w, event, low_cb, normal_cb, high_cb, wanted_cb, + unwanted_cb, gdata); + handled = TRUE; + } + } + + gtk_tree_path_free(path); + + return handled; +} diff --git a/src/trg-files-tree-view-common.h b/src/trg-files-tree-view-common.h new file mode 100644 index 0000000..e34c916 --- /dev/null +++ b/src/trg-files-tree-view-common.h @@ -0,0 +1,32 @@ +/* + * transmission-remote-gtk - A GTK RPC client to Transmission + * Copyright (C) 2011 Alan Fitton + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef TRG_FILES_TREE_VIEW_COMMON_H_ +#define TRG_FILES_TREE_VIEW_COMMON_H_ + +gboolean +trg_files_tree_view_onViewButtonPressed(GtkWidget * w, GdkEventButton * event, + gint pri_id, gint enabled_id, + GCallback low_cb, GCallback normal_cb, GCallback high_cb, + GCallback wanted_cb, GCallback unwanted_cb, gpointer gdata); +gboolean trg_files_tree_view_viewOnPopupMenu(GtkWidget * treeview, + GCallback low_cb, GCallback normal_cb, GCallback high_cb, + GCallback wanted_cb, GCallback unwanted_cb, gpointer userdata); + +#endif /* TRG_FILES_TREE_VIEW_COMMON_H_ */ diff --git a/src/trg-files-tree-view.c b/src/trg-files-tree-view.c index eb145af..a1d791e 100644 --- a/src/trg-files-tree-view.c +++ b/src/trg-files-tree-view.c @@ -22,6 +22,8 @@ #include "trg-client.h" #include "trg-tree-view.h" +#include "trg-files-model-common.h" +#include "trg-files-tree-view-common.h" #include "trg-files-tree-view.h" #include "trg-files-model.h" #include "trg-main-window.h" @@ -40,68 +42,29 @@ struct _TrgFilesTreeViewPrivate { TrgMainWindow *win; }; -static void trg_files_tree_view_class_init(TrgFilesTreeViewClass * klass) -{ +static void trg_files_tree_view_class_init(TrgFilesTreeViewClass * klass) { g_type_class_add_private(klass, sizeof(TrgFilesTreeViewPrivate)); } -static void set_wanted_foreachfunc(GtkTreeModel * model, - GtkTreePath * path G_GNUC_UNUSED, - GtkTreeIter * iter, - gpointer data) -{ - gint id; - gtk_tree_model_get(model, iter, FILESCOL_ID, &id, -1); - - if (id >= 0) { - gtk_tree_store_set(GTK_TREE_STORE(model), iter, FILESCOL_WANTED, - (gchar*)data, -1); - } -} - -static void set_priority_foreachfunc(GtkTreeModel * model, - GtkTreePath * path G_GNUC_UNUSED, - GtkTreeIter * iter, gpointer data) -{ - gint id; - GValue value = { 0 }; - - gtk_tree_model_get(model, iter, FILESCOL_ID, &id, -1); - - if(id >= 0) { - g_value_init(&value, G_TYPE_INT64); - g_value_set_int64(&value, (gint64) GPOINTER_TO_INT(data)); - - gtk_tree_store_set_value(GTK_TREE_STORE(model), iter, - FILESCOL_PRIORITY, &value); - } -} - -static void send_updated_file_prefs_foreachfunc(GtkTreeModel * model, - GtkTreePath * - path G_GNUC_UNUSED, - GtkTreeIter * iter, - gpointer data) -{ +static gboolean send_updated_file_prefs_foreachfunc(GtkTreeModel * model, + GtkTreePath * path G_GNUC_UNUSED, GtkTreeIter * iter, gpointer data) { JsonObject *args = (JsonObject *) data; - gint64 priority; + gint priority; gint id; - gchar *wanted; + gint wanted; gtk_tree_model_get(model, iter, FILESCOL_ID, &id, -1); if (id < 0) - return; + return FALSE; - gtk_tree_model_get(model, iter, FILESCOL_WANTED, &wanted, - FILESCOL_PRIORITY, &priority, -1); + gtk_tree_model_get(model, iter, FILESCOL_WANTED, &wanted, FILESCOL_PRIORITY, + &priority, -1); - if (!g_strcmp0(wanted, GTK_STOCK_CANCEL)) - add_file_id_to_array(args, FIELD_FILES_UNWANTED, id); - else + if (wanted) add_file_id_to_array(args, FIELD_FILES_WANTED, id); - - g_free(wanted); + else + add_file_id_to_array(args, FIELD_FILES_UNWANTED, id); if (priority == TR_PRI_LOW) add_file_id_to_array(args, FIELD_FILES_PRIORITY_LOW, id); @@ -109,33 +72,32 @@ static void send_updated_file_prefs_foreachfunc(GtkTreeModel * model, add_file_id_to_array(args, FIELD_FILES_PRIORITY_HIGH, id); else add_file_id_to_array(args, FIELD_FILES_PRIORITY_NORMAL, id); + + return FALSE; } -static gboolean on_files_update(gpointer data) -{ +static gboolean on_files_update(gpointer data) { trg_response *response = (trg_response *) data; TrgFilesTreeViewPrivate *priv = - TRG_FILES_TREE_VIEW_GET_PRIVATE(response->cb_data); - GtkTreeModel *model = - gtk_tree_view_get_model(GTK_TREE_VIEW(response->cb_data)); + TRG_FILES_TREE_VIEW_GET_PRIVATE(response->cb_data); + GtkTreeModel *model = gtk_tree_view_get_model( + GTK_TREE_VIEW(response->cb_data)); trg_files_model_set_accept(TRG_FILES_MODEL(model), TRUE); response->cb_data = priv->win; + return on_generic_interactive_action(data); } -static void send_updated_file_prefs(TrgFilesTreeView * tv) -{ +static void send_updated_file_prefs(TrgFilesTreeView * tv) { TrgFilesTreeViewPrivate *priv = TRG_FILES_TREE_VIEW_GET_PRIVATE(tv); JsonNode *req; JsonObject *args; - GtkTreeSelection *selection; GtkTreeModel *model; gint64 targetId; JsonArray *targetIdArray; - selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)); model = gtk_tree_view_get_model(GTK_TREE_VIEW(tv)); targetId = trg_files_model_get_torrent_id(TRG_FILES_MODEL(model)); targetIdArray = json_array_new(); @@ -145,188 +107,87 @@ static void send_updated_file_prefs(TrgFilesTreeView * tv) args = node_get_arguments(req); request_set_tag(req, targetId); - gtk_tree_selection_selected_foreach(selection, - send_updated_file_prefs_foreachfunc, - args); + gtk_tree_model_foreach(model, send_updated_file_prefs_foreachfunc, args); trg_files_model_set_accept(TRG_FILES_MODEL(model), FALSE); dispatch_async(priv->client, req, on_files_update, tv); } -static void set_low(GtkWidget * w G_GNUC_UNUSED, gpointer data) -{ - TrgFilesTreeView *tv = TRG_FILES_TREE_VIEW(data); - GtkTreeSelection *selection = - gtk_tree_view_get_selection(GTK_TREE_VIEW(data)); - gtk_tree_selection_selected_foreach(selection, - set_priority_foreachfunc, - GINT_TO_POINTER(TR_PRI_LOW)); - send_updated_file_prefs(tv); -} - -static void set_normal(GtkWidget * w G_GNUC_UNUSED, gpointer data) -{ - TrgFilesTreeView *tv = TRG_FILES_TREE_VIEW(data); - GtkTreeSelection *selection = - gtk_tree_view_get_selection(GTK_TREE_VIEW(data)); - gtk_tree_selection_selected_foreach(selection, - set_priority_foreachfunc, - GINT_TO_POINTER(TR_PRI_NORMAL)); - send_updated_file_prefs(tv); +static void set_low(GtkWidget * w G_GNUC_UNUSED, gpointer data) { + trg_files_tree_model_set_priority(GTK_TREE_VIEW(data), FILESCOL_PRIORITY, + TR_PRI_LOW); + send_updated_file_prefs(TRG_FILES_TREE_VIEW(data)); } -static void set_high(GtkWidget * w G_GNUC_UNUSED, gpointer data) -{ - TrgFilesTreeView *tv = TRG_FILES_TREE_VIEW(data); - GtkTreeSelection *selection = - gtk_tree_view_get_selection(GTK_TREE_VIEW(data)); - gtk_tree_selection_selected_foreach(selection, - set_priority_foreachfunc, - GINT_TO_POINTER(TR_PRI_HIGH)); - send_updated_file_prefs(tv); +static void set_normal(GtkWidget * w G_GNUC_UNUSED, gpointer data) { + trg_files_tree_model_set_priority(GTK_TREE_VIEW(data), FILESCOL_PRIORITY, + TR_PRI_NORMAL); + send_updated_file_prefs(TRG_FILES_TREE_VIEW(data)); } -static void set_unwanted(GtkWidget * w G_GNUC_UNUSED, gpointer data) -{ - TrgFilesTreeView *tv = TRG_FILES_TREE_VIEW(data); - GtkTreeSelection *selection = - gtk_tree_view_get_selection(GTK_TREE_VIEW(data)); - gtk_tree_selection_selected_foreach(selection, - set_wanted_foreachfunc, GTK_STOCK_CANCEL); - send_updated_file_prefs(tv); +static void set_high(GtkWidget * w G_GNUC_UNUSED, gpointer data) { + trg_files_tree_model_set_priority(GTK_TREE_VIEW(data), FILESCOL_PRIORITY, + TR_PRI_HIGH); + send_updated_file_prefs(TRG_FILES_TREE_VIEW(data)); } -static void set_wanted(GtkWidget * w G_GNUC_UNUSED, gpointer data) -{ - TrgFilesTreeView *tv = TRG_FILES_TREE_VIEW(data); - GtkTreeSelection *selection = - gtk_tree_view_get_selection(GTK_TREE_VIEW(data)); - gtk_tree_selection_selected_foreach(selection, - set_wanted_foreachfunc, GTK_STOCK_APPLY); - send_updated_file_prefs(tv); +static void set_unwanted(GtkWidget * w G_GNUC_UNUSED, gpointer data) { + trg_files_model_set_wanted(GTK_TREE_VIEW(data), FILESCOL_WANTED, FALSE); + send_updated_file_prefs(TRG_FILES_TREE_VIEW(data)); } -static void -view_popup_menu(GtkWidget * treeview, GdkEventButton * event, - gpointer data G_GNUC_UNUSED) -{ - GtkWidget *menu, *menuitem; - - menu = gtk_menu_new(); - - menuitem = gtk_menu_item_new_with_label(_("High Priority")); - g_signal_connect(menuitem, "activate", G_CALLBACK(set_high), treeview); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); - - menuitem = gtk_menu_item_new_with_label(_("Normal Priority")); - g_signal_connect(menuitem, "activate", G_CALLBACK(set_normal), - treeview); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); - - menuitem = gtk_menu_item_new_with_label(_("Low Priority")); - g_signal_connect(menuitem, "activate", G_CALLBACK(set_low), treeview); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); - - gtk_menu_shell_append(GTK_MENU_SHELL(menu), - gtk_separator_menu_item_new()); - - menuitem = gtk_image_menu_item_new_with_label(GTK_STOCK_APPLY); - gtk_image_menu_item_set_use_stock(GTK_IMAGE_MENU_ITEM(menuitem), TRUE); - gtk_image_menu_item_set_always_show_image(GTK_IMAGE_MENU_ITEM - (menuitem), TRUE); - gtk_menu_item_set_label(GTK_MENU_ITEM(menuitem), _("Download")); - g_signal_connect(menuitem, "activate", G_CALLBACK(set_wanted), - treeview); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); - - menuitem = gtk_image_menu_item_new_with_label(GTK_STOCK_CANCEL); - gtk_image_menu_item_set_use_stock(GTK_IMAGE_MENU_ITEM(menuitem), TRUE); - gtk_image_menu_item_set_always_show_image(GTK_IMAGE_MENU_ITEM - (menuitem), TRUE); - gtk_menu_item_set_label(GTK_MENU_ITEM(menuitem), _("Skip")); - g_signal_connect(menuitem, "activate", G_CALLBACK(set_unwanted), - treeview); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); - - gtk_widget_show_all(menu); - - gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, - (event != NULL) ? event->button : 0, - gdk_event_get_time((GdkEvent *) event)); +static void set_wanted(GtkWidget * w G_GNUC_UNUSED, gpointer data) { + trg_files_model_set_wanted(GTK_TREE_VIEW(data), FILESCOL_WANTED, TRUE); + send_updated_file_prefs(TRG_FILES_TREE_VIEW(data)); } -static gboolean -view_onButtonPressed(GtkWidget * treeview, GdkEventButton * event, - gpointer userdata) -{ - GtkTreeSelection *selection; - GtkTreePath *path; - - if (event->type == GDK_BUTTON_PRESS && event->button == 3) { - selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); - - if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(treeview), - (gint) event->x, - (gint) event->y, &path, - NULL, NULL, NULL)) { - if (!gtk_tree_selection_path_is_selected(selection, path)) { - gtk_tree_selection_unselect_all(selection); - gtk_tree_selection_select_path(selection, path); - } - gtk_tree_path_free(path); - - view_popup_menu(treeview, event, userdata); - return TRUE; - } - } +static gboolean view_onButtonPressed(GtkWidget * treeview, + GdkEventButton * event, gpointer userdata) { + gboolean handled = trg_files_tree_view_onViewButtonPressed(treeview, event, + FILESCOL_PRIORITY, FILESCOL_WANTED, G_CALLBACK(set_low), + G_CALLBACK(set_normal), G_CALLBACK(set_high), + G_CALLBACK(set_wanted), G_CALLBACK(set_unwanted), userdata); - return FALSE; -} + if (handled) + send_updated_file_prefs(TRG_FILES_TREE_VIEW(treeview)); -static gboolean view_onPopupMenu(GtkWidget * treeview, gpointer userdata) -{ - view_popup_menu(treeview, NULL, userdata); - return TRUE; + return handled; } -static void trg_files_tree_view_init(TrgFilesTreeView * self) -{ +static void trg_files_tree_view_init(TrgFilesTreeView * self) { TrgTreeView *ttv = TRG_TREE_VIEW(self); trg_column_description *desc; - desc = - trg_tree_view_reg_column(ttv, TRG_COLTYPE_FILEICONTEXT, FILESCOL_NAME, - _("Name"), "name", 0); + desc = trg_tree_view_reg_column(ttv, TRG_COLTYPE_FILEICONTEXT, + FILESCOL_NAME, _("Name"), "name", 0); desc->model_column_extra = FILESCOL_ID; - trg_tree_view_reg_column(ttv, TRG_COLTYPE_SIZE, FILESCOL_SIZE, - _("Size"), "size", 0); + trg_tree_view_reg_column(ttv, TRG_COLTYPE_SIZE, FILESCOL_SIZE, _("Size"), + "size", 0); trg_tree_view_reg_column(ttv, TRG_COLTYPE_PROG, FILESCOL_PROGRESS, - _("Progress"), "progress", 0); - trg_tree_view_reg_column(ttv, TRG_COLTYPE_ICON, FILESCOL_WANTED, - _("Wanted"), "wanted", 0); + _("Progress"), "progress", 0); + trg_tree_view_reg_column(ttv, TRG_COLTYPE_WANTED, FILESCOL_WANTED, + _("Download"), "wanted", 0); trg_tree_view_reg_column(ttv, TRG_COLTYPE_PRIO, FILESCOL_PRIORITY, - _("Priority"), "priority", 0); + _("Priority"), "priority", 0); gtk_tree_view_set_search_column(GTK_TREE_VIEW(self), FILESCOL_NAME); g_signal_connect(self, "button-press-event", - G_CALLBACK(view_onButtonPressed), NULL); - g_signal_connect(self, "popup-menu", G_CALLBACK(view_onPopupMenu), - NULL); + G_CALLBACK(view_onButtonPressed), NULL); + g_signal_connect(self, "popup-menu", + G_CALLBACK(trg_files_tree_view_viewOnPopupMenu), NULL); } TrgFilesTreeView *trg_files_tree_view_new(TrgFilesModel * model, - TrgMainWindow * win, - TrgClient * client) -{ + TrgMainWindow * win, TrgClient * client) { GObject *obj = g_object_new(TRG_TYPE_FILES_TREE_VIEW, NULL); TrgFilesTreeViewPrivate *priv = TRG_FILES_TREE_VIEW_GET_PRIVATE(obj); - trg_tree_view_set_prefs(TRG_TREE_VIEW(obj), - trg_client_get_prefs(client)); + trg_tree_view_set_prefs(TRG_TREE_VIEW(obj), trg_client_get_prefs(client)); gtk_tree_view_set_model(GTK_TREE_VIEW(obj), GTK_TREE_MODEL(model)); + priv->client = client; priv->win = win; diff --git a/src/trg-files-tree-view.h b/src/trg-files-tree-view.h index 17ab161..00223e8 100644 --- a/src/trg-files-tree-view.h +++ b/src/trg-files-tree-view.h @@ -46,11 +46,27 @@ typedef struct { GtkTreeViewClass parent_class; } TrgFilesTreeViewClass; +enum { + NOT_SET = 1000, + MIXED = 1001 +}; + GType trg_files_tree_view_get_type(void); TrgFilesTreeView *trg_files_tree_view_new(TrgFilesModel * model, TrgMainWindow * win, TrgClient * client); +void +trg_files_tree_view_renderPriority(GtkTreeViewColumn * column G_GNUC_UNUSED, + GtkCellRenderer * renderer, + GtkTreeModel * model, + GtkTreeIter * iter, gpointer data G_GNUC_UNUSED); +void +trg_files_tree_view_renderDownload(GtkTreeViewColumn * column G_GNUC_UNUSED, + GtkCellRenderer * renderer, + GtkTreeModel * model, + GtkTreeIter * iter, gpointer data G_GNUC_UNUSED); + G_END_DECLS #endif /* TRG_FILES_TREE_VIEW_H_ */ diff --git a/src/trg-torrent-add-dialog.c b/src/trg-torrent-add-dialog.c index e5b4a7b..48f4666 100644 --- a/src/trg-torrent-add-dialog.c +++ b/src/trg-torrent-add-dialog.c @@ -33,7 +33,12 @@ #include "trg-main-window.h" #include "trg-file-parser.h" #include "trg-torrent-add-dialog.h" +#include "trg-files-tree-view-common.h" +#include "trg-files-model-common.h" #include "trg-cell-renderer-size.h" +#include "trg-cell-renderer-priority.h" +#include "trg-cell-renderer-file-icon.h" +#include "trg-cell-renderer-wanted.h" #include "trg-destination-combo.h" #include "trg-prefs.h" #include "requests.h" @@ -42,34 +47,17 @@ #include "protocol-constants.h" enum { - PROP_0, - PROP_FILENAME, - PROP_PARENT, - PROP_CLIENT + PROP_0, PROP_FILENAME, PROP_PARENT, PROP_CLIENT }; enum { - FC_ICON, - FC_INDEX, - FC_LABEL, - FC_SIZE, - FC_PRIORITY, - FC_ENABLED, - N_FILE_COLS + FC_ICON, FC_INDEX, FC_LABEL, FC_SIZE, FC_PRIORITY, FC_ENABLED, N_FILE_COLS }; -enum { - NOT_SET = 1000, - MIXED = 1001 -}; - -#define TR_COLUMN_ID_KEY "tr-id-key" - G_DEFINE_TYPE(TrgTorrentAddDialog, trg_torrent_add_dialog, GTK_TYPE_DIALOG) #define TRG_TORRENT_ADD_DIALOG_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRG_TYPE_TORRENT_ADD_DIALOG, TrgTorrentAddDialogPrivate)) -typedef struct _TrgTorrentAddDialogPrivate - TrgTorrentAddDialogPrivate; +typedef struct _TrgTorrentAddDialogPrivate TrgTorrentAddDialogPrivate; struct _TrgTorrentAddDialogPrivate { TrgClient *client; @@ -84,14 +72,10 @@ struct _TrgTorrentAddDialogPrivate { GtkWidget *delete_check; }; -static void -trg_torrent_add_dialog_set_property(GObject * object, - guint prop_id, - const GValue * value, - GParamSpec * pspec G_GNUC_UNUSED) -{ +static void trg_torrent_add_dialog_set_property(GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec G_GNUC_UNUSED) { TrgTorrentAddDialogPrivate *priv = - TRG_TORRENT_ADD_DIALOG_GET_PRIVATE(object); + TRG_TORRENT_ADD_DIALOG_GET_PRIVATE(object); switch (prop_id) { case PROP_FILENAME: @@ -106,14 +90,10 @@ trg_torrent_add_dialog_set_property(GObject * object, } } -static void -trg_torrent_add_dialog_get_property(GObject * object, - guint prop_id, - GValue * value, - GParamSpec * pspec G_GNUC_UNUSED) -{ +static void trg_torrent_add_dialog_get_property(GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec G_GNUC_UNUSED) { TrgTorrentAddDialogPrivate *priv = - TRG_TORRENT_ADD_DIALOG_GET_PRIVATE(object); + TRG_TORRENT_ADD_DIALOG_GET_PRIVATE(object); switch (prop_id) { case PROP_FILENAME: @@ -125,25 +105,21 @@ trg_torrent_add_dialog_get_property(GObject * object, } } -static void add_set_common_args(JsonObject * args, gint priority, - gchar * dir) -{ +static void add_set_common_args(JsonObject * args, gint priority, gchar * dir) { json_object_set_string_member(args, FIELD_FILE_DOWNLOAD_DIR, dir); json_object_set_int_member(args, FIELD_BANDWIDTH_PRIORITY, - (gint64) priority); + (gint64) priority); } -static gpointer add_files_threadfunc(gpointer data) -{ +static gpointer add_files_threadfunc(gpointer data) { struct add_torrent_threadfunc_args *files_thread_data = - (struct add_torrent_threadfunc_args *) data; + (struct add_torrent_threadfunc_args *) data; GSList *li; for (li = files_thread_data->list; li; li = g_slist_next(li)) { gchar *fileName = (gchar *) li->data; - JsonNode *request = - torrent_add(fileName, files_thread_data->flags); + JsonNode *request = torrent_add(fileName, files_thread_data->flags); JsonObject *args; trg_response *response; @@ -154,7 +130,7 @@ static gpointer add_files_threadfunc(gpointer data) if (files_thread_data->extraArgs) add_set_common_args(args, files_thread_data->priority, - files_thread_data->dir); + files_thread_data->dir); response = dispatch(files_thread_data->client, request); response->cb_data = files_thread_data->cb_data; @@ -171,8 +147,7 @@ static gpointer add_files_threadfunc(gpointer data) return NULL; } -void launch_add_thread(struct add_torrent_threadfunc_args *args) -{ +void launch_add_thread(struct add_torrent_threadfunc_args *args) { GError *error = NULL; g_thread_create(add_files_threadfunc, args, FALSE, &error); @@ -185,18 +160,14 @@ void launch_add_thread(struct add_torrent_threadfunc_args *args) } static gboolean add_file_indexes_foreachfunc(GtkTreeModel * model, - GtkTreePath * - path G_GNUC_UNUSED, - GtkTreeIter * iter, - gpointer data) -{ + GtkTreePath * path G_GNUC_UNUSED, GtkTreeIter * iter, gpointer data) { JsonObject *args = (JsonObject *) data; gint priority, index, wanted; - gtk_tree_model_get(model, iter, FC_PRIORITY, &priority, - FC_ENABLED, &wanted, FC_INDEX, &index, -1); + gtk_tree_model_get(model, iter, FC_PRIORITY, &priority, FC_ENABLED, &wanted, + FC_INDEX, &index, -1); - if (gtk_tree_model_iter_has_child(model, iter)) + if (gtk_tree_model_iter_has_child(model, iter) || index < 0) return FALSE; if (wanted) @@ -214,44 +185,36 @@ static gboolean add_file_indexes_foreachfunc(GtkTreeModel * model, return FALSE; } -static void -trg_torrent_add_response_cb(GtkDialog * dlg, gint res_id, gpointer data) -{ - TrgTorrentAddDialogPrivate *priv = - TRG_TORRENT_ADD_DIALOG_GET_PRIVATE(dlg); +static void trg_torrent_add_response_cb(GtkDialog * dlg, gint res_id, + gpointer data) { + TrgTorrentAddDialogPrivate *priv = TRG_TORRENT_ADD_DIALOG_GET_PRIVATE(dlg); guint flags = 0x00; - if (gtk_toggle_button_get_active - (GTK_TOGGLE_BUTTON(priv->paused_check))) + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->paused_check))) flags |= TORRENT_ADD_FLAG_PAUSED; - if (gtk_toggle_button_get_active - (GTK_TOGGLE_BUTTON(priv->delete_check))) + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->delete_check))) flags |= TORRENT_ADD_FLAG_DELETE; if (res_id == GTK_RESPONSE_ACCEPT) { - gint priority = - gtk_combo_box_get_active(GTK_COMBO_BOX(priv->priority_combo)) - - 1; - gchar *dir = - trg_destination_combo_get_dir(TRG_DESTINATION_COMBO - (priv->dest_combo)); + gint priority = gtk_combo_box_get_active( + GTK_COMBO_BOX(priv->priority_combo)) - 1; + gchar *dir = trg_destination_combo_get_dir(TRG_DESTINATION_COMBO + (priv->dest_combo)); if (g_slist_length(priv->filenames) == 1) { - JsonNode *req = - torrent_add((gchar *) priv->filenames->data, flags); + JsonNode *req = torrent_add((gchar *) priv->filenames->data, flags); if (req) { JsonObject *args = node_get_arguments(req); gtk_tree_model_foreach(GTK_TREE_MODEL(priv->store), - add_file_indexes_foreachfunc, args); + add_file_indexes_foreachfunc, args); add_set_common_args(args, priority, dir); - dispatch_async(priv->client, req, - on_generic_interactive_action, - priv->parent); + dispatch_async(priv->client, req, on_generic_interactive_action, + priv->parent); } g_str_slist_free(priv->filenames); } else { struct add_torrent_threadfunc_args *args = - g_new(struct add_torrent_threadfunc_args, 1); + g_new(struct add_torrent_threadfunc_args, 1); args->list = priv->filenames; args->cb_data = priv->parent; args->client = priv->client; @@ -271,208 +234,38 @@ trg_torrent_add_response_cb(GtkDialog * dlg, gint res_id, gpointer data) gtk_widget_destroy(GTK_WIDGET(dlg)); } -static void -renderPriority(GtkTreeViewColumn * column G_GNUC_UNUSED, - GtkCellRenderer * renderer, - GtkTreeModel * model, - GtkTreeIter * iter, gpointer data G_GNUC_UNUSED) -{ - int priority; - const char *text; - gtk_tree_model_get(model, iter, FC_PRIORITY, &priority, -1); - switch (priority) { - case TR_PRI_HIGH: - text = _("High"); - break; - case TR_PRI_NORMAL: - text = _("Normal"); - break; - case TR_PRI_LOW: - text = _("Low"); - break; - default: - text = _("Mixed"); - break; - } - g_object_set(renderer, "text", text, NULL); -} - -static void -renderDownload(GtkTreeViewColumn * column G_GNUC_UNUSED, - GtkCellRenderer * renderer, - GtkTreeModel * model, - GtkTreeIter * iter, gpointer data G_GNUC_UNUSED) -{ - gint enabled; - gtk_tree_model_get(model, iter, FC_ENABLED, &enabled, -1); - g_object_set(renderer, "inconsistent", (enabled == MIXED), - "active", (enabled == TRUE), NULL); +static void set_low(GtkWidget * w G_GNUC_UNUSED, gpointer data) { + trg_files_tree_model_set_priority(GTK_TREE_VIEW(data), FC_PRIORITY, + TR_PRI_LOW); } -struct SubtreeForeachData { - gint column; - gint new_value; - GtkTreePath *path; -}; - -static gboolean -setSubtreeForeach(GtkTreeModel * model, - GtkTreePath * path, GtkTreeIter * iter, gpointer gdata) -{ - struct SubtreeForeachData *data = gdata; - - if (!gtk_tree_path_compare(path, data->path) - || gtk_tree_path_is_descendant(path, data->path)) { - gtk_tree_store_set(GTK_TREE_STORE(model), iter, data->column, - data->new_value, -1); - } - - return FALSE; /* keep walking */ +static void set_normal(GtkWidget * w G_GNUC_UNUSED, gpointer data) { + trg_files_tree_model_set_priority(GTK_TREE_VIEW(data), FC_PRIORITY, + TR_PRI_NORMAL); } -static void -setSubtree(GtkTreeModel * model, GtkTreePath * path, GtkTreeIter * iter, - gint column, gint new_value) -{ - gint result = new_value; - GtkTreeIter back_iter = *iter; - - if (gtk_tree_model_iter_has_child(model, iter)) { - struct SubtreeForeachData tmp; - GtkTreeIter parent; - - tmp.column = column; - tmp.new_value = new_value; - tmp.path = path; - gtk_tree_model_foreach(model, setSubtreeForeach, &tmp); - - gtk_tree_model_iter_parent(model, &parent, iter); - } else { - gtk_tree_store_set(GTK_TREE_STORE(model), &back_iter, column, - new_value, -1); - } - - while (1) { - GtkTreeIter tmp_iter; - gint n_children, i; - - if (!gtk_tree_model_iter_parent(model, &tmp_iter, &back_iter)) - break; - - n_children = gtk_tree_model_iter_n_children(model, &tmp_iter); - - for (i = 0; i < n_children; i++) { - GtkTreeIter child; - gint current_value; - - if (!gtk_tree_model_iter_nth_child - (model, &child, &tmp_iter, i)) - continue; - - gtk_tree_model_get(model, &child, column, ¤t_value, -1); - if (current_value != new_value) { - result = MIXED; - break; - } - } - - gtk_tree_store_set(GTK_TREE_STORE(model), &tmp_iter, column, - result, -1); - - back_iter = tmp_iter; - } +static void set_high(GtkWidget * w G_GNUC_UNUSED, gpointer data) { + trg_files_tree_model_set_priority(GTK_TREE_VIEW(data), FC_PRIORITY, + TR_PRI_HIGH); } -static gboolean -onViewPathToggled(GtkTreeView * view, - GtkTreeViewColumn * col, - GtkTreePath * path, gpointer data) -{ - int cid; - gboolean handled = FALSE; - - if (!col || !path) - return FALSE; - - cid = - GPOINTER_TO_INT(g_object_get_data - (G_OBJECT(col), TR_COLUMN_ID_KEY)); - if ((cid == FC_PRIORITY) || (cid == FC_ENABLED)) { - GtkTreeIter iter; - GtkTreeModel *model = gtk_tree_view_get_model(view); - - gtk_tree_model_get_iter(model, &iter, path); - - if (cid == FC_PRIORITY) { - int priority; - gtk_tree_model_get(model, &iter, FC_PRIORITY, &priority, -1); - switch (priority) { - case TR_PRI_NORMAL: - priority = TR_PRI_HIGH; - break; - case TR_PRI_HIGH: - priority = TR_PRI_LOW; - break; - default: - priority = TR_PRI_NORMAL; - break; - } - setSubtree(model, path, &iter, FC_PRIORITY, priority); - } else { - int enabled; - gtk_tree_model_get(model, &iter, FC_ENABLED, &enabled, -1); - enabled = !enabled; - - setSubtree(model, path, &iter, FC_ENABLED, enabled); - } - - handled = TRUE; - } - - return handled; +static void set_unwanted(GtkWidget * w G_GNUC_UNUSED, gpointer data) { + trg_files_model_set_wanted(GTK_TREE_VIEW(data), FC_ENABLED, FALSE); } -static gboolean -getAndSelectEventPath(GtkTreeView * treeview, - GdkEventButton * event, - GtkTreeViewColumn ** col, GtkTreePath ** path) -{ - GtkTreeSelection *sel; - - if (gtk_tree_view_get_path_at_pos(treeview, - event->x, event->y, - path, col, NULL, NULL)) { - sel = gtk_tree_view_get_selection(treeview); - if (!gtk_tree_selection_path_is_selected(sel, *path)) { - gtk_tree_selection_unselect_all(sel); - gtk_tree_selection_select_path(sel, *path); - } - return TRUE; - } - - return FALSE; +static void set_wanted(GtkWidget * w G_GNUC_UNUSED, gpointer data) { + trg_files_model_set_wanted(GTK_TREE_VIEW(data), FC_ENABLED, TRUE); } -static gboolean -onViewButtonPressed(GtkWidget * w, GdkEventButton * event, gpointer gdata) -{ - GtkTreeViewColumn *col = NULL; - GtkTreePath *path = NULL; - gboolean handled = FALSE; - GtkTreeView *treeview = GTK_TREE_VIEW(w); - - if (event->type == GDK_BUTTON_PRESS && event->button == 1 - && !(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) - && getAndSelectEventPath(treeview, event, &col, &path)) { - handled = onViewPathToggled(treeview, col, path, NULL); - } - - gtk_tree_path_free(path); - return handled; +static gboolean onViewButtonPressed(GtkWidget * w, GdkEventButton * event, + gpointer gdata) { + return trg_files_tree_view_onViewButtonPressed(w, event, FC_PRIORITY, + FC_ENABLED, G_CALLBACK(set_low), G_CALLBACK(set_normal), + G_CALLBACK(set_high), G_CALLBACK(set_wanted), + G_CALLBACK(set_unwanted), gdata); } -GtkWidget *gtr_file_list_new(GtkTreeStore ** store) -{ +GtkWidget *gtr_file_list_new(GtkTreeStore ** store) { int size; int width; GtkWidget *view; @@ -492,12 +285,11 @@ GtkWidget *gtr_file_list_new(GtkTreeStore ** store) gtk_tree_view_set_rules_hint(tree_view, TRUE); gtk_container_set_border_width(GTK_CONTAINER(view), GUI_PAD_BIG); g_signal_connect(view, "button-press-event", - G_CALLBACK(onViewButtonPressed), view); + G_CALLBACK(onViewButtonPressed), view); pango_context = gtk_widget_create_pango_context(view); - pango_font_description = - pango_font_description_copy(pango_context_get_font_description - (pango_context)); + pango_font_description = pango_font_description_copy( + pango_context_get_font_description(pango_context)); size = pango_font_description_get_size(pango_font_description); pango_font_description_set_size(pango_font_description, size * 0.8); g_object_unref(G_OBJECT(pango_context)); @@ -510,17 +302,18 @@ GtkWidget *gtr_file_list_new(GtkTreeStore ** store) /* add file column */ col = GTK_TREE_VIEW_COLUMN(g_object_new(GTK_TYPE_TREE_VIEW_COLUMN, - "expand", TRUE, - "title", _("Name"), NULL)); + "expand", TRUE, + "title", _("Name"), NULL)); gtk_tree_view_column_set_resizable(col, TRUE); - rend = gtk_cell_renderer_pixbuf_new(); + rend = trg_cell_renderer_file_icon_new(); gtk_tree_view_column_pack_start(col, rend, FALSE); - gtk_tree_view_column_add_attribute(col, rend, "stock-id", FC_ICON); + gtk_tree_view_column_set_attributes(col, rend, "file-name", FC_LABEL, + "file-id", FC_INDEX, NULL); /* add text renderer */ rend = gtk_cell_renderer_text_new(); g_object_set(rend, "ellipsize", PANGO_ELLIPSIZE_END, "font-desc", - pango_font_description, NULL); + pango_font_description, NULL); gtk_tree_view_column_pack_start(col, rend, TRUE); gtk_tree_view_column_set_attributes(col, rend, "text", FC_LABEL, NULL); gtk_tree_view_column_set_sort_column_id(col, FC_LABEL); @@ -530,30 +323,26 @@ GtkWidget *gtr_file_list_new(GtkTreeStore ** store) title = _("Size"); rend = trg_cell_renderer_size_new(); - g_object_set(rend, "alignment", PANGO_ALIGN_RIGHT, - "font-desc", pango_font_description, - "xpad", GUI_PAD, "xalign", 1.0f, "yalign", 0.5f, NULL); + g_object_set(rend, "alignment", PANGO_ALIGN_RIGHT, "font-desc", + pango_font_description, "xpad", GUI_PAD, "xalign", 1.0f, "yalign", + 0.5f, NULL); col = gtk_tree_view_column_new_with_attributes(title, rend, NULL); gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_GROW_ONLY); gtk_tree_view_column_set_sort_column_id(col, FC_SIZE); - gtk_tree_view_column_set_attributes(col, rend, "size-value", FC_SIZE, - NULL); + gtk_tree_view_column_set_attributes(col, rend, "size-value", FC_SIZE, NULL); gtk_tree_view_append_column(tree_view, col); /* add "enabled" column */ title = _("Download"); pango_layout = gtk_widget_create_pango_layout(view, title); pango_layout_get_pixel_size(pango_layout, &width, NULL); - width += 30; /* room for the sort indicator */ + width += 30; /* room for the sort indicator */ g_object_unref(G_OBJECT(pango_layout)); - rend = gtk_cell_renderer_toggle_new(); - col = gtk_tree_view_column_new_with_attributes(title, rend, NULL); - g_object_set_data(G_OBJECT(col), TR_COLUMN_ID_KEY, - GINT_TO_POINTER(FC_ENABLED)); + rend = trg_cell_renderer_wanted_new(); + col = gtk_tree_view_column_new_with_attributes(title, rend, "wanted-value", + FC_ENABLED, NULL); gtk_tree_view_column_set_fixed_width(col, width); gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_FIXED); - gtk_tree_view_column_set_cell_data_func(col, rend, renderDownload, - NULL, NULL); gtk_tree_view_column_set_sort_column_id(col, FC_ENABLED); gtk_tree_view_append_column(tree_view, col); @@ -561,27 +350,22 @@ GtkWidget *gtr_file_list_new(GtkTreeStore ** store) title = _("Priority"); pango_layout = gtk_widget_create_pango_layout(view, title); pango_layout_get_pixel_size(pango_layout, &width, NULL); - width += 30; /* room for the sort indicator */ + width += 30; /* room for the sort indicator */ g_object_unref(G_OBJECT(pango_layout)); - rend = gtk_cell_renderer_text_new(); - g_object_set(rend, "xalign", (gfloat) 0.5, "yalign", (gfloat) 0.5, - NULL); - col = gtk_tree_view_column_new_with_attributes(title, rend, NULL); - g_object_set_data(G_OBJECT(col), TR_COLUMN_ID_KEY, - GINT_TO_POINTER(FC_PRIORITY)); + rend = trg_cell_renderer_priority_new(); + col = gtk_tree_view_column_new_with_attributes(title, rend, + "priority-value", FC_PRIORITY, NULL); gtk_tree_view_column_set_fixed_width(col, width); gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_FIXED); gtk_tree_view_column_set_sort_column_id(col, FC_PRIORITY); - gtk_tree_view_column_set_cell_data_func(col, rend, renderPriority, - NULL, NULL); gtk_tree_view_append_column(tree_view, col); - *store = gtk_tree_store_new(N_FILE_COLS, G_TYPE_STRING, /* icon */ - G_TYPE_UINT, /* index */ - G_TYPE_STRING, /* label */ - G_TYPE_INT64, /* size */ - G_TYPE_INT, /* priority */ - G_TYPE_INT); /* dl enabled */ + *store = gtk_tree_store_new(N_FILE_COLS, G_TYPE_STRING, /* icon */ + G_TYPE_INT, /* index */ + G_TYPE_STRING, /* label */ + G_TYPE_INT64, /* size */ + G_TYPE_INT, /* priority */ + G_TYPE_INT); /* dl enabled */ gtk_tree_view_set_model(tree_view, GTK_TREE_MODEL(*store)); g_object_unref(G_OBJECT(*store)); @@ -589,10 +373,9 @@ GtkWidget *gtr_file_list_new(GtkTreeStore ** store) /* create the scrolled window and stick the view in it */ scroll = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll), - GTK_SHADOW_IN); + GTK_SHADOW_IN); gtk_container_add(GTK_CONTAINER(scroll), view); gtk_widget_set_size_request(scroll, -1, 200); @@ -600,8 +383,7 @@ GtkWidget *gtr_file_list_new(GtkTreeStore ** store) return scroll; } -static GtkWidget *gtr_dialog_get_content_area(GtkDialog * dialog) -{ +static GtkWidget *gtr_dialog_get_content_area(GtkDialog * dialog) { #if GTK_CHECK_VERSION( 2,14,0 ) return gtk_dialog_get_content_area(dialog); #else @@ -609,22 +391,18 @@ static GtkWidget *gtr_dialog_get_content_area(GtkDialog * dialog) #endif } -static void gtr_dialog_set_content(GtkDialog * dialog, GtkWidget * content) -{ +static void gtr_dialog_set_content(GtkDialog * dialog, GtkWidget * content) { GtkWidget *vbox = gtr_dialog_get_content_area(dialog); gtk_box_pack_start(GTK_BOX(vbox), content, TRUE, TRUE, 0); gtk_widget_show_all(content); } -GtkWidget *gtr_priority_combo_new(void) -{ - return gtr_combo_box_new_enum(_("Low"), TR_PRI_LOW, - _("Normal"), TR_PRI_NORMAL, - _("High"), TR_PRI_HIGH, NULL); +GtkWidget *gtr_priority_combo_new(void) { + return gtr_combo_box_new_enum(_("Low"), TR_PRI_LOW, _("Normal"), + TR_PRI_NORMAL, _("High"), TR_PRI_HIGH, NULL); } -static void addTorrentFilters(GtkFileChooser * chooser) -{ +static void addTorrentFilters(GtkFileChooser * chooser) { GtkFileFilter *filter; filter = gtk_file_filter_new(); @@ -639,58 +417,55 @@ static void addTorrentFilters(GtkFileChooser * chooser) } static void store_add_node(GtkTreeStore * store, GtkTreeIter * parent, - trg_torrent_file_node * node) -{ + trg_torrent_file_node * node) { GtkTreeIter child; GList *li; if (node->name) { gtk_tree_store_append(store, &child, parent); - gtk_tree_store_set(store, &child, FC_LABEL, node->name, -1); - gtk_tree_store_set(store, &child, FC_ICON, - node->children ? GTK_STOCK_DIRECTORY : - GTK_STOCK_FILE, -1); - gtk_tree_store_set(store, &child, FC_ENABLED, 1, -1); + gtk_tree_store_set(store, &child, FC_LABEL, node->name, FC_ENABLED, 1, + FC_ICON, node->children ? GTK_STOCK_DIRECTORY : GTK_STOCK_FILE, + FC_INDEX, node->children ? -1 : node->index, + FC_PRIORITY, TR_PRI_NORMAL, + -1); + if (!node->children) { - gtk_tree_store_set(store, &child, FC_INDEX, node->index, -1); gtk_tree_store_set(store, &child, FC_SIZE, node->length, -1); - gtk_tree_store_set(store, &child, FC_PRIORITY, 0, -1); + trg_files_model_update_parents(GTK_TREE_MODEL(store), &child, FC_SIZE); } } for (li = node->children; li; li = g_list_next(li)) store_add_node(store, node->name ? &child : NULL, - (trg_torrent_file_node *) li->data); + (trg_torrent_file_node *) li->data); } -static void torrent_not_parsed_warning(GtkWindow * parent) -{ +static void torrent_not_parsed_warning(GtkWindow * parent) { GtkWidget *dialog = - gtk_message_dialog_new(parent, GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, - _ - ("Unable to parse torrent file. File preferences unavailable, but you can still try uploading it.")); + gtk_message_dialog_new( + parent, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_WARNING, + GTK_BUTTONS_OK, + _ + ("Unable to parse torrent file. File preferences unavailable, but you can still try uploading it.")); gtk_window_set_transient_for(GTK_WINDOW(dialog), parent); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } -static void torrent_not_found_error(GtkWindow * parent, gchar * file) -{ - GtkWidget *dialog = - gtk_message_dialog_new(parent, GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, - _("Unable to open torrent file: %s"), file); +static void torrent_not_found_error(GtkWindow * parent, gchar * file) { + GtkWidget *dialog = gtk_message_dialog_new(parent, + GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, + _("Unable to open torrent file: %s"), file); gtk_window_set_transient_for(GTK_WINDOW(dialog), parent); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } static void trg_torrent_add_dialog_set_filenames(TrgTorrentAddDialog * d, - GSList * filenames) -{ - TrgTorrentAddDialogPrivate *priv = - TRG_TORRENT_ADD_DIALOG_GET_PRIVATE(d); + GSList * filenames) { + TrgTorrentAddDialogPrivate *priv = TRG_TORRENT_ADD_DIALOG_GET_PRIVATE(d); GtkButton *chooser = GTK_BUTTON(priv->source_chooser); gint nfiles = filenames ? g_slist_length(filenames) : 0; @@ -724,8 +499,7 @@ static void trg_torrent_add_dialog_set_filenames(TrgTorrentAddDialog * d, trg_torrent_file_free(tor_data); } } else { - torrent_not_found_error(GTK_WINDOW(priv->parent), - file_name); + torrent_not_found_error(GTK_WINDOW(priv->parent), file_name); } gtk_widget_set_sensitive(priv->file_list, tor_data != NULL); @@ -743,80 +517,60 @@ static void trg_torrent_add_dialog_set_filenames(TrgTorrentAddDialog * d, } static void trg_torrent_add_dialog_generic_save_dir(GtkFileChooser * c, - TrgPrefs * prefs) -{ + TrgPrefs * prefs) { gchar *cwd = gtk_file_chooser_get_current_folder(c); if (cwd) { trg_prefs_set_string(prefs, TRG_PREFS_KEY_LAST_TORRENT_DIR, cwd, - TRG_PREFS_GLOBAL); + TRG_PREFS_GLOBAL); g_free(cwd); } } static GtkWidget *trg_torrent_add_dialog_generic(GtkWindow * parent, - TrgPrefs * prefs) -{ + TrgPrefs * prefs) { GtkWidget *w = gtk_file_chooser_dialog_new(_("Add a Torrent"), parent, - GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL, - GTK_STOCK_ADD, - GTK_RESPONSE_ACCEPT, - NULL); - gchar *dir = - trg_prefs_get_string(prefs, TRG_PREFS_KEY_LAST_TORRENT_DIR, - TRG_PREFS_GLOBAL); + GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_ADD, GTK_RESPONSE_ACCEPT, NULL); + gchar *dir = trg_prefs_get_string(prefs, TRG_PREFS_KEY_LAST_TORRENT_DIR, + TRG_PREFS_GLOBAL); if (dir) { gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(w), dir); g_free(dir); } addTorrentFilters(GTK_FILE_CHOOSER(w)); - gtk_dialog_set_alternative_button_order(GTK_DIALOG(w), - GTK_RESPONSE_ACCEPT, - GTK_RESPONSE_CANCEL, -1); + gtk_dialog_set_alternative_button_order(GTK_DIALOG(w), GTK_RESPONSE_ACCEPT, + GTK_RESPONSE_CANCEL, -1); gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(w), TRUE); return w; } -static void trg_torrent_add_dialog_source_click_cb(GtkWidget * w, - gpointer data) -{ - TrgTorrentAddDialogPrivate *priv = - TRG_TORRENT_ADD_DIALOG_GET_PRIVATE(data); +static void trg_torrent_add_dialog_source_click_cb(GtkWidget * w, gpointer data) { + TrgTorrentAddDialogPrivate *priv = TRG_TORRENT_ADD_DIALOG_GET_PRIVATE(data); GtkWidget *d = trg_torrent_add_dialog_generic(GTK_WINDOW(data), - trg_client_get_prefs - (priv->client)); + trg_client_get_prefs(priv->client)); if (gtk_dialog_run(GTK_DIALOG(d)) == GTK_RESPONSE_ACCEPT) { if (priv->filenames) g_str_slist_free(priv->filenames); - priv->filenames = - gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(d)); + priv->filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(d)); trg_torrent_add_dialog_generic_save_dir(GTK_FILE_CHOOSER(d), - trg_client_get_prefs - (priv->client)); + trg_client_get_prefs(priv->client)); trg_torrent_add_dialog_set_filenames(TRG_TORRENT_ADD_DIALOG(data), - priv->filenames); + priv->filenames); } gtk_widget_destroy(GTK_WIDGET(d)); } static GObject *trg_torrent_add_dialog_constructor(GType type, - guint - n_construct_properties, - GObjectConstructParam - * construct_params) -{ + guint n_construct_properties, GObjectConstructParam * construct_params) { GObject *obj = G_OBJECT_CLASS - (trg_torrent_add_dialog_parent_class)->constructor(type, - n_construct_properties, - construct_params); - TrgTorrentAddDialogPrivate *priv = - TRG_TORRENT_ADD_DIALOG_GET_PRIVATE(obj); + (trg_torrent_add_dialog_parent_class)->constructor(type, + n_construct_properties, construct_params); + TrgTorrentAddDialogPrivate *priv = TRG_TORRENT_ADD_DIALOG_GET_PRIVATE(obj); TrgPrefs *prefs = trg_client_get_prefs(priv->client); GtkWidget *t, *l; @@ -825,18 +579,15 @@ static GObject *trg_torrent_add_dialog_constructor(GType type, /* window */ gtk_window_set_title(GTK_WINDOW(obj), _("Add Torrent")); - gtk_window_set_transient_for(GTK_WINDOW(obj), - GTK_WINDOW(priv->parent)); + gtk_window_set_transient_for(GTK_WINDOW(obj), GTK_WINDOW(priv->parent)); gtk_window_set_destroy_with_parent(GTK_WINDOW(obj), TRUE); /* buttons */ gtk_dialog_add_button(GTK_DIALOG(obj), GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL); - gtk_dialog_add_button(GTK_DIALOG(obj), GTK_STOCK_OPEN, - GTK_RESPONSE_ACCEPT); + GTK_RESPONSE_CANCEL); + gtk_dialog_add_button(GTK_DIALOG(obj), GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT); gtk_dialog_set_alternative_button_order(GTK_DIALOG(obj), - GTK_RESPONSE_ACCEPT, - GTK_RESPONSE_CANCEL, -1); + GTK_RESPONSE_ACCEPT, GTK_RESPONSE_CANCEL, -1); gtk_dialog_set_default_response(GTK_DIALOG(obj), GTK_RESPONSE_ACCEPT); /* workspace */ @@ -848,96 +599,88 @@ static GObject *trg_torrent_add_dialog_constructor(GType type, priv->file_list = gtr_file_list_new(&priv->store); gtk_widget_set_sensitive(priv->file_list, FALSE); - priv->paused_check = - gtk_check_button_new_with_mnemonic(_("Start _paused")); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->paused_check), - trg_prefs_get_bool(prefs, - TRG_PREFS_KEY_START_PAUSED, - TRG_PREFS_GLOBAL)); - - priv->delete_check = - gtk_check_button_new_with_mnemonic(_ - ("Delete local .torrent file after adding")); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->delete_check), - trg_prefs_get_bool(prefs, - TRG_PREFS_KEY_DELETE_LOCAL_TORRENT, - TRG_PREFS_GLOBAL)); + priv->paused_check = gtk_check_button_new_with_mnemonic(_("Start _paused")); + gtk_toggle_button_set_active( + GTK_TOGGLE_BUTTON(priv->paused_check), + trg_prefs_get_bool(prefs, TRG_PREFS_KEY_START_PAUSED, + TRG_PREFS_GLOBAL)); + + priv->delete_check = gtk_check_button_new_with_mnemonic(_ + ("Delete local .torrent file after adding")); + gtk_toggle_button_set_active( + GTK_TOGGLE_BUTTON(priv->delete_check), + trg_prefs_get_bool(prefs, TRG_PREFS_KEY_DELETE_LOCAL_TORRENT, + TRG_PREFS_GLOBAL)); priv->priority_combo = gtr_priority_combo_new(); gtk_combo_box_set_active(GTK_COMBO_BOX(priv->priority_combo), 1); l = gtk_label_new_with_mnemonic(_("_Torrent file:")); gtk_misc_set_alignment(GTK_MISC(l), 0.0f, 0.5f); - gtk_table_attach(GTK_TABLE(t), l, col, col + 1, row, row + 1, GTK_FILL, - 0, 0, 0); + gtk_table_attach(GTK_TABLE(t), l, col, col + 1, row, row + 1, GTK_FILL, 0, + 0, 0); ++col; priv->source_chooser = gtk_button_new(); gtk_button_set_alignment(GTK_BUTTON(priv->source_chooser), 0.0f, 0.5f); trg_torrent_add_dialog_set_filenames(TRG_TORRENT_ADD_DIALOG(obj), - priv->filenames); + priv->filenames); gtk_table_attach(GTK_TABLE(t), priv->source_chooser, col, col + 1, row, - row + 1, ~0, 0, 0, 0); + row + 1, ~0, 0, 0, 0); gtk_label_set_mnemonic_widget(GTK_LABEL(l), priv->source_chooser); g_signal_connect(priv->source_chooser, "clicked", - G_CALLBACK(trg_torrent_add_dialog_source_click_cb), - obj); + G_CALLBACK(trg_torrent_add_dialog_source_click_cb), obj); ++row; col = 0; l = gtk_label_new_with_mnemonic(_("_Destination folder:")); gtk_misc_set_alignment(GTK_MISC(l), 0.0f, 0.5f); - gtk_table_attach(GTK_TABLE(t), l, col, col + 1, row, row + 1, GTK_FILL, - 0, 0, 0); + gtk_table_attach(GTK_TABLE(t), l, col, col + 1, row, row + 1, GTK_FILL, 0, + 0, 0); ++col; priv->dest_combo = trg_destination_combo_new(priv->client, NULL); gtk_combo_box_set_active(GTK_COMBO_BOX(priv->dest_combo), 0); - gtk_table_attach(GTK_TABLE(t), priv->dest_combo, col, col + 1, row, - row + 1, ~0, 0, 0, 0); + gtk_table_attach(GTK_TABLE(t), priv->dest_combo, col, col + 1, row, row + 1, + ~0, 0, 0, 0); gtk_label_set_mnemonic_widget(GTK_LABEL(l), priv->dest_combo); ++row; col = 0; gtk_widget_set_size_request(priv->file_list, 466u, 300u); - gtk_table_attach_defaults(GTK_TABLE(t), priv->file_list, col, col + 2, - row, row + 1); + gtk_table_attach_defaults(GTK_TABLE(t), priv->file_list, col, col + 2, row, + row + 1); ++row; col = 0; l = gtk_label_new_with_mnemonic(_("Torrent _priority:")); gtk_misc_set_alignment(GTK_MISC(l), 0.0f, 0.5f); - gtk_table_attach(GTK_TABLE(t), l, col, col + 1, row, row + 1, ~0, 0, 0, - 0); + gtk_table_attach(GTK_TABLE(t), l, col, col + 1, row, row + 1, ~0, 0, 0, 0); ++col; gtk_table_attach(GTK_TABLE(t), priv->priority_combo, col, col + 1, row, - row + 1, ~0, 0, 0, 0); + row + 1, ~0, 0, 0, 0); gtk_label_set_mnemonic_widget(GTK_LABEL(l), priv->priority_combo); ++row; col = 0; gtk_table_attach(GTK_TABLE(t), priv->paused_check, col, col + 2, row, - row + 1, GTK_FILL, 0, 0, 0); + row + 1, GTK_FILL, 0, 0, 0); ++row; col = 0; gtk_table_attach(GTK_TABLE(t), priv->delete_check, col, col + 2, row, - row + 1, GTK_FILL, 0, 0, 0); + row + 1, GTK_FILL, 0, 0, 0); gtr_dialog_set_content(GTK_DIALOG(obj), t); - g_signal_connect(G_OBJECT(obj), - "response", - G_CALLBACK(trg_torrent_add_response_cb), - priv->parent); + g_signal_connect(G_OBJECT(obj), "response", + G_CALLBACK(trg_torrent_add_response_cb), priv->parent); return obj; } -static void -trg_torrent_add_dialog_class_init(TrgTorrentAddDialogClass * klass) -{ +static void trg_torrent_add_dialog_class_init(TrgTorrentAddDialogClass * klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); g_type_class_add_private(klass, sizeof(TrgTorrentAddDialogPrivate)); @@ -946,66 +689,51 @@ trg_torrent_add_dialog_class_init(TrgTorrentAddDialogClass * klass) object_class->get_property = trg_torrent_add_dialog_get_property; object_class->constructor = trg_torrent_add_dialog_constructor; - g_object_class_install_property(object_class, - PROP_FILENAME, - g_param_spec_pointer("filenames", - "filenames", - "filenames", - G_PARAM_READWRITE - | - G_PARAM_CONSTRUCT_ONLY - | - G_PARAM_STATIC_NAME - | - G_PARAM_STATIC_NICK - | - G_PARAM_STATIC_BLURB)); - - g_object_class_install_property(object_class, - PROP_CLIENT, - g_param_spec_pointer("client", - "client", - "client", - G_PARAM_READWRITE - | - G_PARAM_CONSTRUCT_ONLY - | - G_PARAM_STATIC_NAME - | - G_PARAM_STATIC_NICK - | - G_PARAM_STATIC_BLURB)); - - g_object_class_install_property(object_class, - PROP_PARENT, - g_param_spec_object("parent", "parent", - "parent", - TRG_TYPE_MAIN_WINDOW, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY - | - G_PARAM_STATIC_NAME - | - G_PARAM_STATIC_NICK - | - G_PARAM_STATIC_BLURB)); + g_object_class_install_property( + object_class, + PROP_FILENAME, + g_param_spec_pointer( + "filenames", + "filenames", + "filenames", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY + | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK + | G_PARAM_STATIC_BLURB)); + + g_object_class_install_property( + object_class, + PROP_CLIENT, + g_param_spec_pointer( + "client", + "client", + "client", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY + | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK + | G_PARAM_STATIC_BLURB)); + + g_object_class_install_property( + object_class, + PROP_PARENT, + g_param_spec_object( + "parent", + "parent", + "parent", + TRG_TYPE_MAIN_WINDOW, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY + | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK + | G_PARAM_STATIC_BLURB)); } -static void trg_torrent_add_dialog_init(TrgTorrentAddDialog * self) -{ +static void trg_torrent_add_dialog_init(TrgTorrentAddDialog * self) { } TrgTorrentAddDialog *trg_torrent_add_dialog_new(TrgMainWindow * parent, - TrgClient * client, - GSList * filenames) -{ - return g_object_new(TRG_TYPE_TORRENT_ADD_DIALOG, - "filenames", filenames, - "parent", parent, "client", client, NULL); + TrgClient * client, GSList * filenames) { + return g_object_new(TRG_TYPE_TORRENT_ADD_DIALOG, "filenames", filenames, + "parent", parent, "client", client, NULL); } -void trg_torrent_add_dialog(TrgMainWindow * win, TrgClient * client) -{ +void trg_torrent_add_dialog(TrgMainWindow * win, TrgClient * client) { GtkWidget *w; GtkWidget *c; TrgPrefs *prefs = trg_client_get_prefs(client); @@ -1013,30 +741,29 @@ void trg_torrent_add_dialog(TrgMainWindow * win, TrgClient * client) w = trg_torrent_add_dialog_generic(GTK_WINDOW(win), prefs); c = gtk_check_button_new_with_mnemonic(_("Show _options dialog")); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(c), - trg_prefs_get_bool(prefs, - TRG_PREFS_KEY_ADD_OPTIONS_DIALOG, - TRG_PREFS_GLOBAL)); + gtk_toggle_button_set_active( + GTK_TOGGLE_BUTTON(c), + trg_prefs_get_bool(prefs, TRG_PREFS_KEY_ADD_OPTIONS_DIALOG, + TRG_PREFS_GLOBAL)); gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(w), c); if (gtk_dialog_run(GTK_DIALOG(w)) == GTK_RESPONSE_ACCEPT) { GtkFileChooser *chooser = GTK_FILE_CHOOSER(w); GtkToggleButton *tb = - GTK_TOGGLE_BUTTON(gtk_file_chooser_get_extra_widget(chooser)); + GTK_TOGGLE_BUTTON(gtk_file_chooser_get_extra_widget(chooser)); gboolean showOptions = gtk_toggle_button_get_active(tb); GSList *l = gtk_file_chooser_get_filenames(chooser); - trg_torrent_add_dialog_generic_save_dir(GTK_FILE_CHOOSER(w), - prefs); + trg_torrent_add_dialog_generic_save_dir(GTK_FILE_CHOOSER(w), prefs); if (showOptions) { - TrgTorrentAddDialog *dialog = - trg_torrent_add_dialog_new(win, client, l); + TrgTorrentAddDialog *dialog = trg_torrent_add_dialog_new(win, + client, l); gtk_widget_show_all(GTK_WIDGET(dialog)); } else { struct add_torrent_threadfunc_args *args = - g_new0(struct add_torrent_threadfunc_args, 1); + g_new0(struct add_torrent_threadfunc_args, 1); args->list = l; args->cb_data = win; diff --git a/src/trg-tree-view.c b/src/trg-tree-view.c index acb4bdc..de2cd71 100644 --- a/src/trg-tree-view.c +++ b/src/trg-tree-view.c @@ -27,6 +27,7 @@ #include "trg-cell-renderer-speed.h" #include "trg-cell-renderer-size.h" #include "trg-cell-renderer-ratio.h" +#include "trg-cell-renderer-wanted.h" #include "trg-cell-renderer-eta.h" #include "trg-cell-renderer-epoch.h" #include "trg-cell-renderer-priority.h" @@ -363,14 +364,14 @@ static void trg_tree_view_add_column_after(TrgTreeView * tv, desc->model_column, NULL); break; - case TRG_COLTYPE_ICON: + case TRG_COLTYPE_WANTED: column = gtk_tree_view_column_new(); - renderer = gtk_cell_renderer_pixbuf_new(); - gtk_cell_renderer_set_alignment(GTK_CELL_RENDERER(renderer), 0.5f, - 0.0); + renderer = trg_cell_renderer_wanted_new(); + /*gtk_cell_renderer_set_alignment(GTK_CELL_RENDERER(renderer), 0.5f, + 0.0);*/ gtk_tree_view_column_set_title(column, desc->header); gtk_tree_view_column_pack_start(column, renderer, TRUE); - gtk_tree_view_column_set_attributes(column, renderer, "stock-id", + gtk_tree_view_column_set_attributes(column, renderer, "wanted-value", desc->model_column, NULL); break; case TRG_COLTYPE_STOCKICONTEXT: diff --git a/src/trg-tree-view.h b/src/trg-tree-view.h index 249bce6..562ca5c 100644 --- a/src/trg-tree-view.h +++ b/src/trg-tree-view.h @@ -53,7 +53,7 @@ G_END_DECLS GList *trg_tree_view_get_selected_refs_list(GtkTreeView * tv); enum { TRG_COLTYPE_STOCKICONTEXT, TRG_COLTYPE_FILEICONTEXT, - TRG_COLTYPE_ICON, + TRG_COLTYPE_WANTED, TRG_COLTYPE_TEXT, TRG_COLTYPE_SIZE, TRG_COLTYPE_RATIO, -- cgit v1.2.3