summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alan Fitton <ajf@eth0.org.uk>2011-02-17 09:45:23 +0000
committerGravatar Alan Fitton <ajf@eth0.org.uk>2011-02-17 09:45:23 +0000
commit973aaa9d9a020e1644ce2fe45fd3613422f6ada9 (patch)
treec12c0ecfe8e9f890b7414287cd62e5085fcf0a7d
parentc10b672d05b8b6b68bbc1ccb92da8b5caa451c68 (diff)
a bunch of changes needed to facilitate changing trackers (unfinished). also tidy up general details panel a bit, fix a crash if a stats update is received after stats dialog is closed.
-rw-r--r--configure.ac4
-rw-r--r--redhat/transmission-remote-gtk.spec2
-rw-r--r--src/torrent.c5
-rw-r--r--src/torrent.h1
-rw-r--r--src/trg-client.c10
-rw-r--r--src/trg-client.h2
-rw-r--r--src/trg-general-panel.c58
-rw-r--r--src/trg-main-window.c18
-rw-r--r--src/trg-menu-bar.c1
-rw-r--r--src/trg-menu-bar.h2
-rw-r--r--src/trg-model.c40
-rw-r--r--src/trg-model.h5
-rw-r--r--src/trg-peers-model.c1
-rw-r--r--src/trg-stats-dialog.c10
-rw-r--r--src/trg-status-bar.c2
-rw-r--r--src/trg-status-bar.h2
-rw-r--r--src/trg-torrent-model.c54
-rw-r--r--src/trg-torrent-model.h10
-rw-r--r--src/trg-trackers-model.c17
-rw-r--r--src/trg-trackers-model.h6
-rw-r--r--src/trg-trackers-tree-view.c140
-rw-r--r--src/trg-trackers-tree-view.h4
-rw-r--r--src/trg-tree-view.c4
-rw-r--r--src/trg-tree-view.h2
24 files changed, 288 insertions, 112 deletions
diff --git a/configure.ac b/configure.ac
index 0dcf36a..e4c01e5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
#AC_PREREQ([2.65])
-AC_INIT(transmission-remote-gtk, 0.1.1, alan@eth0.org.uk)
-AM_INIT_AUTOMAKE(transmission-remote-gtk, 0.1.1)
+AC_INIT(transmission-remote-gtk, 0.1.2, alan@eth0.org.uk)
+AM_INIT_AUTOMAKE(transmission-remote-gtk, 0.1.2)
AC_OUTPUT(Makefile src/Makefile)
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
diff --git a/redhat/transmission-remote-gtk.spec b/redhat/transmission-remote-gtk.spec
index 2e912f7..1c99129 100644
--- a/redhat/transmission-remote-gtk.spec
+++ b/redhat/transmission-remote-gtk.spec
@@ -1,5 +1,5 @@
Name: transmission-remote-gtk
-Version: 0.1.1
+Version: 0.1.2
Release: 1%{?dist:%{dist}}
Summary: Remote control client for Transmission BitTorrent
diff --git a/src/torrent.c b/src/torrent.c
index 9ecb354..d6fcde2 100644
--- a/src/torrent.c
+++ b/src/torrent.c
@@ -208,6 +208,11 @@ gchar *torrent_get_status_string(gint64 value)
}
}
+gint64 tracker_get_id(JsonObject *t)
+{
+ return json_object_get_int_member(t, FIELD_ID);
+}
+
gint64 tracker_get_tier(JsonObject * t)
{
return json_object_get_int_member(t, FIELD_TIER);
diff --git a/src/torrent.h b/src/torrent.h
index bfac5a6..093759f 100644
--- a/src/torrent.h
+++ b/src/torrent.h
@@ -51,6 +51,7 @@ JsonArray *torrent_get_wanted(JsonObject * t);
JsonArray *torrent_get_priorities(JsonObject * t);
gint64 torrent_get_id(JsonObject * t);
gint64 tracker_get_tier(JsonObject * t);
+gint64 tracker_get_id(JsonObject *t);
const gchar *tracker_get_announce(JsonObject * t);
const gchar *tracker_get_scrape(JsonObject * t);
JsonArray *torrent_get_files(JsonObject * args);
diff --git a/src/trg-client.c b/src/trg-client.c
index 97462bb..bb8dd68 100644
--- a/src/trg-client.c
+++ b/src/trg-client.c
@@ -37,6 +37,16 @@ trg_client *trg_init_client()
#define check_for_error(error) if (error) { g_error_free(error); return TRG_GCONF_SCHEMA_ERROR; }
+void trg_client_set_session(trg_client *tc, JsonObject *session)
+{
+ if (tc->session != NULL)
+ json_object_unref(tc->session);
+
+ session_get_version(session, &(tc->version));
+
+ tc->session = session;
+}
+
int trg_client_populate_with_settings(trg_client * tc, GConfClient * gconf)
{
gint port;
diff --git a/src/trg-client.h b/src/trg-client.h
index 2fbcad9..51f3100 100644
--- a/src/trg-client.h
+++ b/src/trg-client.h
@@ -34,6 +34,7 @@ typedef struct {
gint64 updateSerial;
JsonObject *session;
gboolean ssl;
+ float version;
char *url;
char *username;
char *password;
@@ -45,5 +46,6 @@ typedef struct {
trg_client *trg_init_client();
int trg_client_populate_with_settings(trg_client * tc,
GConfClient * gconf);
+void trg_client_set_session(trg_client *tc, JsonObject *session);
#endif /* TRG_CLIENT_H_ */
diff --git a/src/trg-general-panel.c b/src/trg-general-panel.c
index 7d6525f..b52347f 100644
--- a/src/trg-general-panel.c
+++ b/src/trg-general-panel.c
@@ -92,32 +92,31 @@ void trg_general_panel_update(TrgGeneralPanel * panel, JsonObject * t,
sizeOfBuf = sizeof(buf);
- tr_strlsize(buf, torrent_get_size(t), sizeOfBuf);
+ trg_strlsize(buf, torrent_get_size(t));
gtk_label_set_text(GTK_LABEL(priv->gen_size_label), buf);
- tr_strlspeed(buf, torrent_get_rate_down(t) / KILOBYTE_FACTOR,
- sizeOfBuf);
+ trg_strlspeed(buf, torrent_get_rate_down(t) / KILOBYTE_FACTOR);
gtk_label_set_text(GTK_LABEL(priv->gen_down_rate_label), buf);
- tr_strlspeed(buf, torrent_get_rate_up(t) / KILOBYTE_FACTOR, sizeOfBuf);
+ trg_strlspeed(buf, torrent_get_rate_up(t) / KILOBYTE_FACTOR);
gtk_label_set_text(GTK_LABEL(priv->gen_up_rate_label), buf);
- tr_strlsize(buf, torrent_get_uploaded(t), sizeOfBuf);
+ trg_strlsize(buf, torrent_get_uploaded(t));
gtk_label_set_text(GTK_LABEL(priv->gen_uploaded_label), buf);
- tr_strlsize(buf, torrent_get_downloaded(t), sizeOfBuf);
+ trg_strlsize(buf, torrent_get_downloaded(t));
gtk_label_set_text(GTK_LABEL(priv->gen_downloaded_label), buf);
- tr_strlratio(buf,
+ trg_strlratio(buf,
(double) torrent_get_uploaded(t) /
- (double) torrent_get_downloaded(t), sizeOfBuf);
+ (double) torrent_get_downloaded(t));
gtk_label_set_text(GTK_LABEL(priv->gen_ratio_label), buf);
statusString = torrent_get_status_string(torrent_get_status(t));
gtk_label_set_text(GTK_LABEL(priv->gen_status_label), statusString);
g_free(statusString);
- tr_strlpercent(buf, torrent_get_percent_done(t), sizeOfBuf);
+ trg_strlpercent(buf, torrent_get_percent_done(t));
gtk_label_set_text(GTK_LABEL(priv->gen_completed_label), buf);
gtk_label_set_text(GTK_LABEL(priv->gen_name_label),
@@ -153,13 +152,14 @@ static GtkLabel *trg_general_panel_add_label(TrgGeneralPanel * fixed,
keyMarkup = g_markup_printf_escaped("<b>%s</b>", key);
gtk_label_set_markup(GTK_LABEL(keyLabel), keyMarkup);
g_free(keyMarkup);
- gtk_fixed_put(GTK_FIXED(fixed), keyLabel, 10 + (col * 300),
- 10 + (row * 24));
+ gtk_fixed_put(GTK_FIXED(fixed), keyLabel, 10 + (col * 280),
+ 10 + (row * 22));
value = gtk_label_new(NULL);
gtk_label_set_selectable(GTK_LABEL(value), TRUE);
- gtk_fixed_put(GTK_FIXED(fixed), value, 140 + (col * 320),
- 10 + (row * 24));
+ gtk_fixed_put(GTK_FIXED(fixed), value, 140 + (col * 300),
+ 10 + (row * 22));
+ g_object_set_data(G_OBJECT(value), "key-label", keyLabel);
return GTK_LABEL(value);
}
@@ -170,27 +170,31 @@ static void trg_general_panel_init(TrgGeneralPanel * self)
priv->gen_name_label =
trg_general_panel_add_label(self, "Name:", 0, 0);
+
priv->gen_size_label =
trg_general_panel_add_label(self, "Size:", 0, 1);
+ priv->gen_eta_label = trg_general_panel_add_label(self, "ETA:", 1, 1);
priv->gen_completed_label =
- trg_general_panel_add_label(self, "Completed:", 0, 2);
+ trg_general_panel_add_label(self, "Completed:", 2, 1);
+
priv->gen_seeders_label =
- trg_general_panel_add_label(self, "Seeders:", 0, 3);
- priv->gen_leechers_label =
- trg_general_panel_add_label(self, "Leechers:", 0, 4);
- priv->gen_status_label =
- trg_general_panel_add_label(self, "Status:", 0, 5);
- priv->gen_eta_label = trg_general_panel_add_label(self, "ETA:", 1, 1);
- priv->gen_downloaded_label =
- trg_general_panel_add_label(self, "Downloaded:", 1, 2);
- priv->gen_uploaded_label =
- trg_general_panel_add_label(self, "Uploaded:", 1, 3);
+ trg_general_panel_add_label(self, "Seeders:", 0, 2);
priv->gen_down_rate_label =
- trg_general_panel_add_label(self, "Rate Down:", 1, 4);
+ trg_general_panel_add_label(self, "Rate Down:", 1, 2);
+ priv->gen_downloaded_label =
+ trg_general_panel_add_label(self, "Downloaded:", 2, 2);
+
+ priv->gen_leechers_label =
+ trg_general_panel_add_label(self, "Leechers:", 0, 3);
priv->gen_up_rate_label =
- trg_general_panel_add_label(self, "Rate Up:", 1, 5);
+ trg_general_panel_add_label(self, "Rate Up:", 1, 3);
+ priv->gen_uploaded_label =
+ trg_general_panel_add_label(self, "Uploaded:", 2, 3);
+
+ priv->gen_status_label =
+ trg_general_panel_add_label(self, "Status:", 0, 4);
priv->gen_ratio_label =
- trg_general_panel_add_label(self, "Ratio:", 2, 3);
+ trg_general_panel_add_label(self, "Ratio:", 1, 4);
gtk_widget_set_sensitive(GTK_WIDGET(self), FALSE);
}
diff --git a/src/trg-main-window.c b/src/trg-main-window.c
index 7b73cc2..6ef29c5 100644
--- a/src/trg-main-window.c
+++ b/src/trg-main-window.c
@@ -762,7 +762,7 @@ GtkWidget *trg_main_window_notebook_new(TrgMainWindow * win)
GtkWidget *notebook = gtk_notebook_new();
- gtk_widget_set_size_request(notebook, -1, 200);
+ gtk_widget_set_size_request(notebook, -1, 170);
priv->genDetails = trg_general_panel_new(priv->sortedTorrentModel);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
@@ -771,7 +771,7 @@ GtkWidget *trg_main_window_notebook_new(TrgMainWindow * win)
priv->trackersModel = trg_trackers_model_new();
priv->trackersTreeView =
- trg_trackers_tree_view_new(priv->trackersModel);
+ trg_trackers_tree_view_new(priv->trackersModel, priv->client);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
my_scrolledwin_new(GTK_WIDGET
(priv->trackersTreeView)),
@@ -827,16 +827,15 @@ static void on_session_get(JsonObject * response, int status,
newSession = get_arguments(response);
- if (client->session != NULL) {
- json_object_unref(client->session);
- } else {
+ if (client->session == NULL) {
trg_status_bar_connect(priv->statusBar, newSession);
trg_main_window_conn_changed(win, TRUE);
dispatch_async(client, torrent_get(), on_torrent_get_first, data);
}
- client->session = newSession;
+ trg_client_set_session(client, newSession);
+ trg_trackers_tree_view_new_connection(priv->trackersTreeView, client);
gdk_threads_leave();
json_object_ref(newSession);
@@ -878,10 +877,7 @@ trg_main_window_update_notebook_displays(TrgMainWindow * win,
client = priv->client;
trg_general_panel_update(priv->genDetails, t, iter);
-
- if (first == TRUE)
- trg_trackers_model_update(priv->trackersModel, t);
-
+ trg_trackers_model_update(priv->trackersModel, client->updateSerial, t, first);
trg_files_model_update(priv->filesModel, client->updateSerial,
t, first);
trg_peers_model_update(priv->peersModel, client->updateSerial,
@@ -1021,7 +1017,7 @@ static void
on_torrent_get_multipurpose(JsonObject * response, gboolean first,
int status, gpointer data)
{
- TrgTorrentModelClassUpdateStats stats;
+ trg_torrent_model_update_stats stats;
TrgMainWindowPrivate *priv;
trg_client *client;
diff --git a/src/trg-menu-bar.c b/src/trg-menu-bar.c
index ddd2626..e55a2c3 100644
--- a/src/trg-menu-bar.c
+++ b/src/trg-menu-bar.c
@@ -179,7 +179,6 @@ trg_menu_bar_install_widget_prop(GObjectClass * class, guint propId,
G_PARAM_STATIC_BLURB));
}
-static
GtkWidget *trg_menu_bar_item_new(GtkMenuShell * shell, char *text,
char *stock_id, gboolean sensitive)
{
diff --git a/src/trg-menu-bar.h b/src/trg-menu-bar.h
index 8820fec..bb98475 100644
--- a/src/trg-menu-bar.h
+++ b/src/trg-menu-bar.h
@@ -48,6 +48,8 @@ typedef struct {
GType trg_menu_bar_get_type(void);
TrgMenuBar *trg_menu_bar_new(TrgMainWindow * win);
+GtkWidget *trg_menu_bar_item_new(GtkMenuShell * shell, char *text,
+ char *stock_id, gboolean sensitive);
G_END_DECLS
void trg_menu_bar_torrent_actions_sensitive(TrgMenuBar * mb,
diff --git a/src/trg-model.c b/src/trg-model.c
index b27c981..2d1ff67 100644
--- a/src/trg-model.c
+++ b/src/trg-model.c
@@ -19,6 +19,7 @@
#include <glib.h>
#include <gtk/gtk.h>
+#include <json-glib/json-glib.h>
struct trg_model_remove_removed_foreachfunc_args {
gint64 currentSerial;
@@ -63,3 +64,42 @@ trg_model_remove_removed(GtkListStore * model, gint serial_column,
g_list_free(args.toRemove);
}
}
+
+struct find_existing_item_foreach_args {
+ gint64 id;
+ gint search_column;
+ GtkTreeIter *iter;
+ gboolean found;
+};
+
+static gboolean
+find_existing_item_foreachfunc(GtkTreeModel * model,
+ GtkTreePath * path G_GNUC_UNUSED,
+ GtkTreeIter * iter, gpointer data)
+{
+ struct find_existing_item_foreach_args *args = (struct find_existing_item_foreach_args *) data;
+ gint64 currentId;
+
+ gtk_tree_model_get(model, iter, args->search_column, &currentId, -1);
+ if (currentId == args->id) {
+ args->iter = iter;
+ return args->found = TRUE;
+ }
+
+ return FALSE;
+}
+
+gboolean
+find_existing_model_item(GtkTreeModel * model, gint search_column, gint64 id,
+ GtkTreeIter * iter)
+{
+ struct find_existing_item_foreach_args args;
+ args.id = id;
+ args.found = FALSE;
+ args.search_column = search_column;
+ gtk_tree_model_foreach(model,
+ find_existing_item_foreachfunc, &args);
+ if (args.found == TRUE)
+ *iter = *(args.iter);
+ return args.found;
+}
diff --git a/src/trg-model.h b/src/trg-model.h
index 427e0bd..e954153 100644
--- a/src/trg-model.h
+++ b/src/trg-model.h
@@ -17,7 +17,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-
#ifndef TRG_MODEL_H_
#define TRG_MODEL_H_
@@ -26,4 +25,8 @@
void trg_model_remove_removed(GtkListStore * model, gint serial_column,
gint64 currentSerial);
+gboolean
+find_existing_model_item(GtkTreeModel * model, gint search_column, gint64 id,
+ GtkTreeIter * iter);
+
#endif /* TRG_MODEL_H_ */
diff --git a/src/trg-peers-model.c b/src/trg-peers-model.c
index 26ac636..0fb3721 100644
--- a/src/trg-peers-model.c
+++ b/src/trg-peers-model.c
@@ -171,7 +171,6 @@ void trg_peers_model_update(TrgPeersModel * model, gint64 updateSerial,
isNew = FALSE;
}
-
flagStr = peer_get_flagstr(peer);
gtk_list_store_set(GTK_LIST_STORE(model), &peerIter,
PEERSCOL_FLAGS, flagStr,
diff --git a/src/trg-stats-dialog.c b/src/trg-stats-dialog.c
index 4674215..4c1d08c 100644
--- a/src/trg-stats-dialog.c
+++ b/src/trg-stats-dialog.c
@@ -199,9 +199,17 @@ static void update_time_stat(JsonObject * args, GtkTreeRowReference * rr,
static void on_stats_reply(JsonObject * response, int status,
gpointer data)
{
- TrgStatsDialogPrivate *priv = TRG_STATS_DIALOG_GET_PRIVATE(data);
+ TrgStatsDialogPrivate *priv;
JsonObject *args;
+ if (!TRG_IS_STATS_DIALOG(data))
+ {
+ response_unref(response);
+ return;
+ }
+
+ priv = TRG_STATS_DIALOG_GET_PRIVATE(data);
+
if (status == CURLE_OK) {
args = get_arguments(response);
diff --git a/src/trg-status-bar.c b/src/trg-status-bar.c
index 499c00c..056bae0 100644
--- a/src/trg-status-bar.c
+++ b/src/trg-status-bar.c
@@ -77,7 +77,7 @@ void trg_status_bar_connect(TrgStatusBar * sb, JsonObject * session)
}
void trg_status_bar_update(TrgStatusBar * sb,
- TrgTorrentModelClassUpdateStats * stats)
+ trg_torrent_model_update_stats * stats)
{
TrgStatusBarPrivate *priv;
gchar *statusBarUpdate;
diff --git a/src/trg-status-bar.h b/src/trg-status-bar.h
index 3baf5bc..90e0133 100644
--- a/src/trg-status-bar.h
+++ b/src/trg-status-bar.h
@@ -52,7 +52,7 @@ TrgStatusBar *trg_status_bar_new();
G_END_DECLS
void trg_status_bar_update(TrgStatusBar * sb,
- TrgTorrentModelClassUpdateStats * stats);
+ trg_torrent_model_update_stats * stats);
void trg_status_bar_connect(TrgStatusBar * sb, JsonObject * session);
void trg_status_bar_push_connection_msg(TrgStatusBar * sb,
const gchar * msg);
diff --git a/src/trg-torrent-model.c b/src/trg-torrent-model.c
index 3d7d85f..3bfe20c 100644
--- a/src/trg-torrent-model.c
+++ b/src/trg-torrent-model.c
@@ -41,21 +41,12 @@ static guint signals[TMODEL_SIGNAL_COUNT] = { 0 };
G_DEFINE_TYPE(TrgTorrentModel, trg_torrent_model, GTK_TYPE_LIST_STORE)
static guint32 torrent_get_flags(JsonObject * t, gint64 status,
- TrgTorrentModelClassUpdateStats * stats);
+ trg_torrent_model_update_stats * stats);
static void
update_torrent_iter(gint64 serial, TrgTorrentModel * model,
GtkTreeIter * iter, JsonObject * t,
- TrgTorrentModelClassUpdateStats * stats);
-
-static gboolean
-find_existing_torrent_item_foreachfunc(GtkTreeModel * model,
- GtkTreePath * path,
- GtkTreeIter * iter, gpointer data);
-
-static gboolean
-find_existing_torrent_item(TrgTorrentModel * model, JsonObject * t,
- GtkTreeIter * iter);
+ trg_torrent_model_update_stats * stats);
static void trg_torrent_model_class_init(TrgTorrentModelClass * klass)
{
@@ -137,7 +128,7 @@ static void trg_torrent_model_init(TrgTorrentModel * self)
}
static guint32 torrent_get_flags(JsonObject * t, gint64 status,
- TrgTorrentModelClassUpdateStats * stats)
+ trg_torrent_model_update_stats * stats)
{
guint32 flags = 0;
switch (status) {
@@ -176,7 +167,7 @@ static guint32 torrent_get_flags(JsonObject * t, gint64 status,
static void
update_torrent_iter(gint64 serial, TrgTorrentModel * model,
GtkTreeIter * iter, JsonObject * t,
- TrgTorrentModelClassUpdateStats * stats)
+ trg_torrent_model_update_stats * stats)
{
guint lastFlags, newFlags;
gchar *statusString, *statusIcon;
@@ -274,42 +265,9 @@ TrgTorrentModel *trg_torrent_model_new(void)
return g_object_new(TRG_TYPE_TORRENT_MODEL, NULL);
}
-static gboolean
-find_existing_torrent_item_foreachfunc(GtkTreeModel * model,
- GtkTreePath * path G_GNUC_UNUSED,
- GtkTreeIter * iter, gpointer data)
-{
- struct idAndIter *ii;
- gint currentId;
-
- ii = (struct idAndIter *) data;
-
- gtk_tree_model_get(model, iter, TORRENT_COLUMN_ID, &currentId, -1);
- if (currentId == ii->id) {
- ii->iter = iter;
- return ii->found = TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-find_existing_torrent_item(TrgTorrentModel * model, JsonObject * t,
- GtkTreeIter * iter)
-{
- struct idAndIter ii;
- ii.id = torrent_get_id(t);
- ii.found = FALSE;
- gtk_tree_model_foreach(GTK_TREE_MODEL(model),
- find_existing_torrent_item_foreachfunc, &ii);
- if (ii.found == TRUE)
- *iter = *(ii.iter);
- return ii.found;
-}
-
void trg_torrent_model_update(TrgTorrentModel * model, trg_client * tc,
JsonObject * response,
- TrgTorrentModelClassUpdateStats * stats,
+ trg_torrent_model_update_stats * stats,
gboolean first)
{
int i;
@@ -325,7 +283,7 @@ void trg_torrent_model_update(TrgTorrentModel * model, trg_client * tc,
t = json_array_get_object_element(newTorrents, i);
if (first == TRUE
- || find_existing_torrent_item(model, t, &iter) == FALSE) {
+ || find_existing_model_item(GTK_TREE_MODEL(model), TORRENT_COLUMN_ID, torrent_get_id(t), &iter) == FALSE) {
gtk_list_store_append(GTK_LIST_STORE(model), &iter);
update_torrent_iter(tc->updateSerial, model, &iter, t, stats);
if (!first)
diff --git a/src/trg-torrent-model.h b/src/trg-torrent-model.h
index 2c11dd0..b486737 100644
--- a/src/trg-torrent-model.h
+++ b/src/trg-torrent-model.h
@@ -59,7 +59,7 @@ typedef struct {
gint down;
gint paused;
gint count;
-} TrgTorrentModelClassUpdateStats;
+} trg_torrent_model_update_stats;
GType trg_torrent_model_get_type(void);
@@ -72,7 +72,7 @@ find_existing_peer_item(GtkListStore * model, JsonObject * p,
void trg_torrent_model_update(TrgTorrentModel * model, trg_client * tc,
JsonObject * response,
- TrgTorrentModelClassUpdateStats * stats,
+ trg_torrent_model_update_stats * stats,
gboolean first);
enum {
@@ -96,10 +96,4 @@ enum {
TORRENT_COLUMN_COLUMNS
};
-struct idAndIter {
- gint id;
- GtkTreeIter *iter;
- gboolean found;
-};
-
#endif /* TRG_TORRENT_MODEL_H_ */
diff --git a/src/trg-trackers-model.c b/src/trg-trackers-model.c
index e2dc7ab..739efd6 100644
--- a/src/trg-trackers-model.c
+++ b/src/trg-trackers-model.c
@@ -23,11 +23,12 @@
#include "config.h"
#include "torrent.h"
+#include "trg-model.h"
#include "trg-trackers-model.h"
G_DEFINE_TYPE(TrgTrackersModel, trg_trackers_model, GTK_TYPE_LIST_STORE)
-void trg_trackers_model_update(TrgTrackersModel * model, JsonObject * t)
+void trg_trackers_model_update(TrgTrackersModel * model, gint64 updateSerial, JsonObject * t, gboolean first)
{
guint j;
JsonArray *trackers;
@@ -42,11 +43,13 @@ void trg_trackers_model_update(TrgTrackersModel * model, JsonObject * t)
GtkTreeIter trackIter;
JsonObject *tracker =
json_node_get_object(json_array_get_element(trackers, j));
+ gint64 trackerId = tracker_get_id(tracker);
announce = tracker_get_announce(tracker);
scrape = tracker_get_scrape(tracker);
- gtk_list_store_append(GTK_LIST_STORE(model), &trackIter);
+ if (first || find_existing_model_item(GTK_TREE_MODEL(model), TRACKERCOL_ID, trackerId, &trackIter) == FALSE)
+ gtk_list_store_append(GTK_LIST_STORE(model), &trackIter);
#ifdef DEBUG
gtk_list_store_set(GTK_LIST_STORE(model), &trackIter,
@@ -57,15 +60,23 @@ void trg_trackers_model_update(TrgTrackersModel * model, JsonObject * t)
TRACKERCOL_ANNOUNCE, announce, -1);
gtk_list_store_set(GTK_LIST_STORE(model), &trackIter,
TRACKERCOL_SCRAPE, scrape, -1);
+ gtk_list_store_set(GTK_LIST_STORE(model), &trackIter, TRACKERCOL_ID, trackerId, -1);
+ gtk_list_store_set(GTK_LIST_STORE(model), &trackIter, TRACKERCOL_UPDATESERIAL, updateSerial, -1);
#else
gtk_list_store_set(GTK_LIST_STORE(model), &trackIter,
TRACKERCOL_ICON, GTK_STOCK_NETWORK,
+ TRACKERCOL_ID, trackerId,
+ TRACKERCOL_UPDATESERIAL, updateSerial,
TRACKERCOL_TIER,
tracker_get_tier(tracker),
TRACKERCOL_ANNOUNCE,
announce, TRACKERCOL_SCRAPE, scrape, -1);
#endif
}
+
+ trg_model_remove_removed(GTK_LIST_STORE(model),
+ TRACKERCOL_UPDATESERIAL,
+ updateSerial);
}
static void
@@ -81,6 +92,8 @@ static void trg_trackers_model_init(TrgTrackersModel * self)
column_types[TRACKERCOL_TIER] = G_TYPE_INT64;
column_types[TRACKERCOL_ANNOUNCE] = G_TYPE_STRING;
column_types[TRACKERCOL_SCRAPE] = G_TYPE_STRING;
+ column_types[TRACKERCOL_ID] = G_TYPE_INT64;
+ column_types[TRACKERCOL_UPDATESERIAL] = G_TYPE_INT64;
gtk_list_store_set_column_types(GTK_LIST_STORE(self),
TRACKERCOL_COLUMNS, column_types);
diff --git a/src/trg-trackers-model.h b/src/trg-trackers-model.h
index 3737371..13e6c56 100644
--- a/src/trg-trackers-model.h
+++ b/src/trg-trackers-model.h
@@ -48,14 +48,16 @@ GType trg_trackers_model_get_type(void);
TrgTrackersModel *trg_trackers_model_new(void);
G_END_DECLS
- void
-trg_trackers_model_update(TrgTrackersModel * model, JsonObject * t);
+
+void trg_trackers_model_update(TrgTrackersModel * model, gint64 updateSerial, JsonObject * t, gboolean first);
enum {
TRACKERCOL_ICON,
TRACKERCOL_TIER,
TRACKERCOL_ANNOUNCE,
TRACKERCOL_SCRAPE,
+ TRACKERCOL_ID,
+ TRACKERCOL_UPDATESERIAL,
TRACKERCOL_COLUMNS
};
diff --git a/src/trg-trackers-tree-view.c b/src/trg-trackers-tree-view.c
index d29a956..ff08a5e 100644
--- a/src/trg-trackers-tree-view.c
+++ b/src/trg-trackers-tree-view.c
@@ -21,32 +21,168 @@
#include "trg-trackers-tree-view.h"
#include "trg-tree-view.h"
+#include "trg-client.h"
+#include "trg-menu-bar.h"
G_DEFINE_TYPE(TrgTrackersTreeView, trg_trackers_tree_view,
TRG_TYPE_TREE_VIEW)
+#define TRG_TRACKERS_TREE_VIEW_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRG_TYPE_TRACKERS_TREE_VIEW, TrgTrackersTreeViewPrivate))
+
+typedef struct _TrgTrackersTreeViewPrivate TrgTrackersTreeViewPrivate;
+
+struct _TrgTrackersTreeViewPrivate {
+ trg_client *client;
+ GtkCellRenderer *announceRenderer;
+};
static void
trg_trackers_tree_view_class_init(TrgTrackersTreeViewClass *
klass G_GNUC_UNUSED)
{
+ g_type_class_add_private(klass, sizeof(TrgTrackersTreeViewPrivate));
+}
+
+void trg_trackers_tree_view_new_connection(TrgTrackersTreeView *tv, trg_client *tc)
+{
+ TrgTrackersTreeViewPrivate *priv = TRG_TRACKERS_TREE_VIEW_GET_PRIVATE(tv);
+ gboolean editable = tc->version >= 2.10;
+
+ g_object_set(priv->announceRenderer, "editable", editable, NULL);
+ g_object_set(priv->announceRenderer, "mode", editable ? GTK_CELL_RENDERER_MODE_EDITABLE : GTK_CELL_RENDERER_MODE_INERT, NULL);
+}
+
+static void trg_tracker_announce_edited(GtkCellRendererText *renderer,
+ gchar *path,
+ gchar *new_text,
+ gpointer user_data)
+{
+ GtkTreeView *tv = GTK_TREE_VIEW(user_data);
+ GtkTreeModel *model = gtk_tree_view_get_model(tv);
+ GtkTreeIter iter;
+
+ gtk_tree_model_get_iter_from_string(model, &iter, path);
+ gtk_list_store_set(GTK_LIST_STORE(model), &iter, TRACKERCOL_ANNOUNCE, new_text, -1);
}
static void trg_trackers_tree_view_init(TrgTrackersTreeView * self)
{
+ TrgTrackersTreeViewPrivate *priv = TRG_TRACKERS_TREE_VIEW_GET_PRIVATE(self);
+
trg_tree_view_add_pixbuf_text_column(TRG_TREE_VIEW(self),
TRACKERCOL_ICON,
TRACKERCOL_TIER, "Tier", -1);
- trg_tree_view_add_column(TRG_TREE_VIEW(self), "Announce URL",
+
+ priv->announceRenderer = trg_tree_view_add_column(TRG_TREE_VIEW(self), "Announce URL",
TRACKERCOL_ANNOUNCE);
+ g_signal_connect(priv->announceRenderer, "edited", G_CALLBACK(trg_tracker_announce_edited), self);
+
trg_tree_view_add_column(TRG_TREE_VIEW(self), "Scrape URL",
TRACKERCOL_SCRAPE);
}
-TrgTrackersTreeView *trg_trackers_tree_view_new(TrgTrackersModel * model)
+static void add_tracker(GtkWidget *w, gpointer data)
+{
+
+}
+
+static void delete_tracker(GtkWidget *w, gpointer data)
+{
+
+}
+
+static void
+view_popup_menu_add_only(GtkWidget * treeview, GdkEventButton * event,
+ gpointer data G_GNUC_UNUSED)
+{
+ GtkWidget *menu, *menuitem;
+
+ menu = gtk_menu_new();
+
+ menuitem = trg_menu_bar_item_new(GTK_MENU_SHELL(menu), "Add", GTK_STOCK_ADD, TRUE);
+ g_signal_connect(menuitem, "activate", G_CALLBACK(add_tracker), treeview);
+
+ 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
+view_popup_menu(GtkWidget * treeview, GdkEventButton * event,
+ gpointer data G_GNUC_UNUSED)
+{
+ GtkWidget *menu, *menuitem;
+
+ menu = gtk_menu_new();
+
+ menuitem = trg_menu_bar_item_new(GTK_MENU_SHELL(menu), "Delete", GTK_STOCK_DELETE, TRUE);
+ g_signal_connect(menuitem, "activate", G_CALLBACK(delete_tracker), treeview);
+
+ menuitem = trg_menu_bar_item_new(GTK_MENU_SHELL(menu), "Add", GTK_STOCK_ADD, TRUE);
+ g_signal_connect(menuitem, "activate", G_CALLBACK(add_tracker), treeview);
+
+ 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 gboolean
+view_onButtonPressed(GtkWidget * treeview, GdkEventButton * event,
+ gpointer userdata)
+{
+ TrgTrackersTreeViewPrivate *priv = TRG_TRACKERS_TREE_VIEW_GET_PRIVATE(treeview);
+ GtkTreeSelection *selection;
+ GtkTreePath *path;
+
+ if (priv->client->version < 2.10)
+ return FALSE;
+
+ 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;
+ } else {
+ view_popup_menu_add_only(treeview, event, userdata);
+ }
+ }
+
+ return FALSE;
+}
+
+static gboolean view_onPopupMenu(GtkWidget * treeview, gpointer userdata)
+{
+ view_popup_menu(treeview, NULL, userdata);
+ return TRUE;
+}
+
+TrgTrackersTreeView *trg_trackers_tree_view_new(TrgTrackersModel * model, trg_client *client)
{
GObject *obj = g_object_new(TRG_TYPE_TRACKERS_TREE_VIEW, NULL);
+ TrgTrackersTreeViewPrivate *priv = TRG_TRACKERS_TREE_VIEW_GET_PRIVATE(obj);
+
+ g_signal_connect(obj, "button-press-event",
+ G_CALLBACK(view_onButtonPressed), NULL);
+ g_signal_connect(obj, "popup-menu", G_CALLBACK(view_onPopupMenu),
+ NULL);
+
gtk_tree_view_set_model(GTK_TREE_VIEW(obj), GTK_TREE_MODEL(model));
+ priv->client = client;
return TRG_TRACKERS_TREE_VIEW(obj);
}
diff --git a/src/trg-trackers-tree-view.h b/src/trg-trackers-tree-view.h
index 0728e43..2b58c2a 100644
--- a/src/trg-trackers-tree-view.h
+++ b/src/trg-trackers-tree-view.h
@@ -25,6 +25,7 @@
#include "trg-trackers-model.h"
#include "trg-tree-view.h"
+#include "trg-client.h"
G_BEGIN_DECLS
#define TRG_TYPE_TRACKERS_TREE_VIEW trg_trackers_tree_view_get_type()
@@ -48,7 +49,8 @@ typedef struct {
GType trg_trackers_tree_view_get_type(void);
-TrgTrackersTreeView *trg_trackers_tree_view_new(TrgTrackersModel * model);
+TrgTrackersTreeView *trg_trackers_tree_view_new(TrgTrackersModel * model, trg_client *client);
+void trg_trackers_tree_view_new_connection(TrgTrackersTreeView *tv, trg_client *tc);
G_END_DECLS
#endif /* TRG_TRACKERS_TREE_VIEW_H_ */
diff --git a/src/trg-tree-view.c b/src/trg-tree-view.c
index ca196cd..e92bdbc 100644
--- a/src/trg-tree-view.c
+++ b/src/trg-tree-view.c
@@ -133,7 +133,7 @@ void trg_tree_view_add_ratio_column(TrgTreeView * tv, char *title,
gtk_tree_view_append_column(GTK_TREE_VIEW(tv), column);
}
-void trg_tree_view_add_column_fixed_width(TrgTreeView * tv, char *title,
+GtkCellRenderer *trg_tree_view_add_column_fixed_width(TrgTreeView * tv, char *title,
int index, int width)
{
GtkCellRenderer *renderer;
@@ -145,6 +145,8 @@ void trg_tree_view_add_column_fixed_width(TrgTreeView * tv, char *title,
trg_tree_view_std_column_setup(column, index, width);
gtk_tree_view_append_column(GTK_TREE_VIEW(tv), column);
+
+ return renderer;
}
void
diff --git a/src/trg-tree-view.h b/src/trg-tree-view.h
index 1abea47..fe225fe 100644
--- a/src/trg-tree-view.h
+++ b/src/trg-tree-view.h
@@ -48,7 +48,7 @@ GtkWidget *trg_tree_view_new(void);
G_END_DECLS
#define trg_tree_view_add_column(tv, title, index) trg_tree_view_add_column_fixed_width(tv, title, index, -1)
-void trg_tree_view_add_column_fixed_width(TrgTreeView * treeview,
+GtkCellRenderer *trg_tree_view_add_column_fixed_width(TrgTreeView * treeview,
char *title, int index,
int width);