summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac2
-rw-r--r--freebsd/Makefile2
-rw-r--r--redhat/transmission-remote-gtk.spec10
-rw-r--r--src/main.c8
-rw-r--r--src/torrent.c11
-rw-r--r--src/torrent.h4
-rw-r--r--src/transmission-remote-gtk.schemas13
-rw-r--r--src/trg-general-panel.c47
-rw-r--r--src/trg-main-window.c111
-rw-r--r--src/trg-main-window.h1
-rw-r--r--src/trg-model.h2
-rw-r--r--src/trg-preferences-dialog.c32
-rw-r--r--src/trg-preferences.h10
-rw-r--r--src/trg-state-selector.c251
-rw-r--r--src/trg-state-selector.h16
-rw-r--r--src/trg-torrent-model.c7
-rw-r--r--src/trg-torrent-model.h8
-rw-r--r--src/trg-torrent-props-dialog.c6
-rw-r--r--src/util.c27
-rw-r--r--src/util.h13
-rw-r--r--transmission-remote-gtk.pot (renamed from po/transmission-remote-gtk.pot)164
21 files changed, 498 insertions, 247 deletions
diff --git a/configure.ac b/configure.ac
index 1d545fb..0228e6e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
AC_PREREQ(2.63)
-AC_INIT(transmission-remote-gtk, 0.2.2, alan@eth0.org.uk)
+AC_INIT(transmission-remote-gtk, 0.3, alan@eth0.org.uk)
AC_CONFIG_SRCDIR(src)
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
AM_INIT_AUTOMAKE([foreign])
diff --git a/freebsd/Makefile b/freebsd/Makefile
index b58e986..ea9e40a 100644
--- a/freebsd/Makefile
+++ b/freebsd/Makefile
@@ -6,7 +6,7 @@
#
PORTNAME= transmission-remote-gtk
-PORTVERSION= 0.2.2
+PORTVERSION= 0.3
CATEGORIES= net-p2p
MASTER_SITES= ${MASTER_SITE_GOOGLE_CODE}
diff --git a/redhat/transmission-remote-gtk.spec b/redhat/transmission-remote-gtk.spec
index 65cb503..3296824 100644
--- a/redhat/transmission-remote-gtk.spec
+++ b/redhat/transmission-remote-gtk.spec
@@ -1,5 +1,5 @@
Name: transmission-remote-gtk
-Version: 0.2.2
+Version: 0.3
Release: 1%{?dist:%{dist}}
Summary: Remote control client for Transmission BitTorrent
@@ -91,7 +91,12 @@ fi
%{_datadir}/icons/hicolor/48x48/apps/transmission-remote-gtk.png
%changelog
-* Sun Feb 27 2011 Alan Fitton <alan@eth0.org.uk> - 0.2.2
+* Sat Mar 11 2011 Alan Fitton <alan@eth0.org.uk> - 0.3
+- Case insensitive text filtering.
+- Speed graph.
+- i18n support (currently German and Korean).
+- Use table layout instead of fixed for general panel.
+- libproxy support.
- Fix torrent bandwidth priority setting.
- Better suspending of tracker/files update until ack.
- Put versions in some spec/configure deps.
@@ -100,6 +105,7 @@ fi
- Remove 5px window border (much better on some dark themes).
- Fix hardcoded path to Transmission icon in about dialog.
- Fix a leak from gtk_tree_selection_get_selected_rows().
+- TRG_NOUNIQUE env variable to start multiple instances.
* Mon Feb 21 2011 Alan Fitton <alan@eth0.org.uk> - 0.2.1
- Fix crash in update-blocklist/port-test callbacks.
diff --git a/src/main.c b/src/main.c
index 0335b87..a1044eb 100644
--- a/src/main.c
+++ b/src/main.c
@@ -88,10 +88,10 @@ int main(int argc, char *argv[])
gdk_threads_init();
gtk_init(&argc, &argv);
- setlocale( LC_ALL, "" );
- bindtextdomain( GETTEXT_PACKAGE, TRGLOCALEDIR );
- bind_textdomain_codeset( GETTEXT_PACKAGE, "UTF-8" );
- textdomain( GETTEXT_PACKAGE );
+ setlocale(LC_ALL, "");
+ bindtextdomain(GETTEXT_PACKAGE, TRGLOCALEDIR);
+ bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
+ textdomain(GETTEXT_PACKAGE);
textdomain(PACKAGE_NAME);
diff --git a/src/torrent.c b/src/torrent.c
index c132949..f56c2bc 100644
--- a/src/torrent.c
+++ b/src/torrent.c
@@ -210,7 +210,7 @@ gchar *torrent_get_status_string(gint64 value)
}
}
-gboolean torrent_has_tracker(JsonObject *t, GRegex *rx, gchar *search)
+gboolean torrent_has_tracker(JsonObject * t, GRegex * rx, gchar * search)
{
JsonArray *trackers = torrent_get_trackers(t);
int i;
@@ -218,7 +218,8 @@ gboolean torrent_has_tracker(JsonObject *t, GRegex *rx, gchar *search)
for (i = 0; i < json_array_get_length(trackers); i++) {
JsonObject *tracker = json_array_get_object_element(trackers, i);
const gchar *trackerAnnounce = tracker_get_announce(tracker);
- gchar *trackerAnnounceHost = trg_uri_host_extract(rx, trackerAnnounce);
+ gchar *trackerAnnounceHost =
+ trg_gregex_get_first(rx, trackerAnnounce);
int cmpResult = g_strcmp0(trackerAnnounceHost, search);
g_free(trackerAnnounceHost);
if (cmpResult == 0)
@@ -238,6 +239,12 @@ gint64 tracker_get_tier(JsonObject * t)
return json_object_get_int_member(t, FIELD_TIER);
}
+gchar *torrent_get_download_dir_short(JsonObject * t, GRegex * rx)
+{
+ const gchar *dir = torrent_get_download_dir(t);
+ return trg_gregex_get_first(rx, dir);
+}
+
gint64 torrent_get_left_until_done(JsonObject * t)
{
return json_object_get_int_member(t, FIELD_LEFTUNTILDONE);
diff --git a/src/torrent.h b/src/torrent.h
index 226cd4e..f8f7d47 100644
--- a/src/torrent.h
+++ b/src/torrent.h
@@ -31,6 +31,7 @@
#define TORRENT_FLAG_DOWNLOADING (1 << 6) /* 0x32 */
#define TORRENT_FLAG_PAUSED (1 << 7) /* 0x64 */
#define FILTER_FLAG_TRACKER (1 << 8) /* 0x128 */
+#define FILTER_FLAG_DIR (1 << 9) /* 0x256 */
gint64 torrent_get_size(JsonObject * t);
const gchar *torrent_get_name(JsonObject * t);
@@ -41,6 +42,7 @@ gint64 torrent_get_uploaded(JsonObject * t);
gint64 torrent_get_downloaded(JsonObject * t);
const gchar *torrent_get_errorstr(JsonObject * t);
const gchar *torrent_get_download_dir(JsonObject * t);
+gchar *torrent_get_download_dir_short(JsonObject * t, GRegex * rx);
gint64 torrent_get_have_unchecked(JsonObject * t);
gint64 torrent_get_have_valid(JsonObject * t);
gint64 torrent_get_status(JsonObject * t);
@@ -68,7 +70,7 @@ gboolean torrent_get_download_limited(JsonObject * t);
gdouble torrent_get_seed_ratio_limit(JsonObject * t);
gint64 torrent_get_seed_ratio_mode(JsonObject * t);
gint64 torrent_get_peer_limit(JsonObject * t);
-gboolean torrent_has_tracker(JsonObject *t, GRegex *rx, gchar *search);
+gboolean torrent_has_tracker(JsonObject * t, GRegex * rx, gchar * search);
JsonArray *get_torrents(JsonObject * response);
diff --git a/src/transmission-remote-gtk.schemas b/src/transmission-remote-gtk.schemas
index def8fe2..6e8f784 100644
--- a/src/transmission-remote-gtk.schemas
+++ b/src/transmission-remote-gtk.schemas
@@ -28,19 +28,6 @@
</schema>
<schema>
- <key>/schemas/apps/transmission-remote-gtk/show-graph</key>
- <applyto>/apps/transmission-remote-gtk/show-graph</applyto>
- <owner>transmission-remote-gtk</owner>
- <type>bool</type>
- <default>1</default>
-
- <locale name="C">
- <short>Show graph</short>
- <long>Show graph</long>
- </locale>
- </schema>
-
- <schema>
<key>/schemas/apps/transmission-remote-gtk/ssl</key>
<applyto>/apps/transmission-remote-gtk/ssl</applyto>
<owner>transmission-remote-gtk</owner>
diff --git a/src/trg-general-panel.c b/src/trg-general-panel.c
index 3c3b5a2..2e6ed83 100644
--- a/src/trg-general-panel.c
+++ b/src/trg-general-panel.c
@@ -37,7 +37,8 @@
static void gtk_label_clear(GtkLabel * l);
static GtkLabel *gen_panel_label_get_key_label(GtkLabel * l);
static GtkLabel *trg_general_panel_add_label(TrgGeneralPanel * gp,
- char *key, guint col, guint row);
+ char *key, guint col,
+ guint row);
G_DEFINE_TYPE(TrgGeneralPanel, trg_general_panel, GTK_TYPE_TABLE)
#define TRG_GENERAL_PANEL_GET_PRIVATE(o) \
@@ -186,36 +187,48 @@ void trg_general_panel_update(TrgGeneralPanel * panel, JsonObject * t,
gtk_label_set_text(GTK_LABEL(priv->gen_leechers_label), buf);
}
-static GtkLabel *trg_general_panel_add_label_with_width(TrgGeneralPanel *gp,
- char *key, guint col, guint row, gint width)
+static GtkLabel *trg_general_panel_add_label_with_width(TrgGeneralPanel *
+ gp, char *key,
+ guint col,
+ guint row,
+ gint width)
{
GtkWidget *value, *keyLabel, *alignment;
- int startCol = (col == 0) ? 0 : col*2;
+ int startCol = (col == 0) ? 0 : col * 2;
alignment = gtk_alignment_new(0, 0, 0, 0);
keyLabel = gtk_label_new(NULL);
if (strlen(key) > 0) {
gchar *keyMarkup =
- g_markup_printf_escaped(strlen(key) > 0 ? "<b>%s:</b>" : "", key);
+ g_markup_printf_escaped(strlen(key) > 0 ? "<b>%s:</b>" : "",
+ key);
gtk_label_set_markup(GTK_LABEL(keyLabel), keyMarkup);
g_free(keyMarkup);
}
gtk_container_add(GTK_CONTAINER(alignment), keyLabel);
- gtk_table_attach(GTK_TABLE(gp), alignment, startCol, startCol+1, row, row+1, GTK_FILL, 0, TRG_GENERAL_PANEL_SPACING_X, TRG_GENERAL_PANEL_SPACING_Y);
+ gtk_table_attach(GTK_TABLE(gp), alignment, startCol, startCol + 1, row,
+ row + 1, GTK_FILL, 0, TRG_GENERAL_PANEL_SPACING_X,
+ TRG_GENERAL_PANEL_SPACING_Y);
alignment = gtk_alignment_new(0, 0, 0, 0);
value = gtk_label_new(NULL);
g_object_set_data(G_OBJECT(value), "key-label", keyLabel);
gtk_label_set_selectable(GTK_LABEL(value), TRUE);
gtk_container_add(GTK_CONTAINER(alignment), value);
- gtk_table_attach(GTK_TABLE(gp), alignment, startCol+1, width < 0 ? TRG_GENERAL_PANEL_COLUMNS_TOTAL-1 : startCol+1+width, row, row+1, GTK_FILL | GTK_SHRINK, 0, TRG_GENERAL_PANEL_SPACING_X, TRG_GENERAL_PANEL_SPACING_Y);
+ gtk_table_attach(GTK_TABLE(gp), alignment, startCol + 1,
+ width <
+ 0 ? TRG_GENERAL_PANEL_COLUMNS_TOTAL - 1 : startCol +
+ 1 + width, row, row + 1, GTK_FILL | GTK_SHRINK, 0,
+ TRG_GENERAL_PANEL_SPACING_X,
+ TRG_GENERAL_PANEL_SPACING_Y);
return GTK_LABEL(value);
}
-static GtkLabel *trg_general_panel_add_label(TrgGeneralPanel *gp,
- char *key, guint col, guint row)
+static GtkLabel *trg_general_panel_add_label(TrgGeneralPanel * gp,
+ char *key, guint col,
+ guint row)
{
return trg_general_panel_add_label_with_width(gp, key, col, row, 1);
}
@@ -225,9 +238,8 @@ static void trg_general_panel_init(TrgGeneralPanel * self)
TrgGeneralPanelPrivate *priv = TRG_GENERAL_PANEL_GET_PRIVATE(self);
int i;
- g_object_set(G_OBJECT(self), "n-columns", TRG_GENERAL_PANEL_COLUMNS_TOTAL,
- "n-rows", 7,
- NULL);
+ g_object_set(G_OBJECT(self), "n-columns",
+ TRG_GENERAL_PANEL_COLUMNS_TOTAL, "n-rows", 7, NULL);
priv->gen_name_label =
trg_general_panel_add_label_with_width(self, _("Name"), 0, 0, -1);
@@ -259,12 +271,17 @@ static void trg_general_panel_init(TrgGeneralPanel * self)
trg_general_panel_add_label(self, _("Ratio"), 1, 4);
priv->gen_downloaddir_label =
- trg_general_panel_add_label_with_width(self, _("Location"), 0, 5, -1);
+ trg_general_panel_add_label_with_width(self, _("Location"), 0, 5,
+ -1);
- priv->gen_error_label = trg_general_panel_add_label_with_width(self, "", 0, 6, -1);
+ priv->gen_error_label =
+ trg_general_panel_add_label_with_width(self, "", 0, 6, -1);
for (i = 0; i < TRG_GENERAL_PANEL_COLUMNS_TOTAL; i++)
- gtk_table_set_col_spacing(GTK_TABLE(self), i, i % 2 == 0 ? TRG_GENERAL_PANEL_WIDTH_FROM_KEY : TRG_GENERAL_PANEL_WIDTH_FROM_VALUE);
+ gtk_table_set_col_spacing(GTK_TABLE(self), i,
+ i % 2 ==
+ 0 ? TRG_GENERAL_PANEL_WIDTH_FROM_KEY :
+ TRG_GENERAL_PANEL_WIDTH_FROM_VALUE);
gtk_widget_set_sensitive(GTK_WIDGET(self), FALSE);
}
diff --git a/src/trg-main-window.c b/src/trg-main-window.c
index 1b67687..821f267 100644
--- a/src/trg-main-window.c
+++ b/src/trg-main-window.c
@@ -72,8 +72,7 @@ static gboolean update_selected_torrent_notebook(TrgMainWindow * win,
static void torrent_event_notification(TrgTorrentModel * model,
gchar * icon, gchar * desc,
gint tmout, gchar * prefKey,
- GtkTreeIter * iter,
- gpointer data);
+ GtkTreeIter * iter, gpointer data);
static void on_torrent_completed(TrgTorrentModel * model,
GtkTreeIter * iter, gpointer data);
static void on_torrent_added(TrgTorrentModel * model, GtkTreeIter * iter,
@@ -309,21 +308,23 @@ static void on_torrent_completed(TrgTorrentModel * model,
GtkTreeIter * iter, gpointer data)
{
torrent_event_notification(model, GTK_STOCK_APPLY,
- "This torrent has completed.", TORRENT_COMPLETE_NOTIFY_TMOUT,
+ _("This torrent has completed."),
+ TORRENT_COMPLETE_NOTIFY_TMOUT,
TRG_GCONF_KEY_COMPLETE_NOTIFY, iter, data);
}
-static void on_torrent_addremove(TrgTorrentModel *model, gpointer data)
+static void on_torrent_addremove(TrgTorrentModel * model, gpointer data)
{
TrgMainWindowPrivate *priv = TRG_MAIN_WINDOW_GET_PRIVATE(data);
- trg_state_selector_update_trackers(priv->stateSelector, priv->client->torrents, priv->client->updateSerial);
+ trg_state_selector_update(priv->stateSelector);
}
static void on_torrent_added(TrgTorrentModel * model,
GtkTreeIter * iter, gpointer data)
{
torrent_event_notification(model, GTK_STOCK_ADD,
- "This torrent has been added.", TORRENT_ADD_NOTIFY_TMOUT,
+ _("This torrent has been added."),
+ TORRENT_ADD_NOTIFY_TMOUT,
TRG_GCONF_KEY_ADD_NOTIFY, iter, data);
}
@@ -902,14 +903,12 @@ static void on_session_get(JsonObject * response, int status,
static void
on_torrent_get(JsonObject * response, int mode, int status, gpointer data)
{
+ TrgMainWindowPrivate *priv = TRG_MAIN_WINDOW_GET_PRIVATE(data);
+
+ trg_client *client = priv->client;
trg_torrent_model_update_stats stats;
- TrgMainWindowPrivate *priv;
- trg_client *client;
gboolean first;
- priv = TRG_MAIN_WINDOW_GET_PRIVATE(data);
- client = priv->client;
-
/* Disconnected between request and response callback */
if (client->session == NULL) {
response_unref(response);
@@ -1011,11 +1010,8 @@ trg_main_window_update_notebook_displays(TrgMainWindow * win,
GtkTreeIter * iter,
gboolean first)
{
- TrgMainWindowPrivate *priv;
- trg_client *client;
-
- priv = TRG_MAIN_WINDOW_GET_PRIVATE(win);
- client = priv->client;
+ TrgMainWindowPrivate *priv = TRG_MAIN_WINDOW_GET_PRIVATE(win);
+ trg_client *client = priv->client;
trg_general_panel_update(priv->genDetails, t, iter);
trg_trackers_model_update(priv->trackersModel, client->updateSerial, t,
@@ -1039,46 +1035,57 @@ trg_torrent_tree_view_visible_func(GtkTreeModel * model,
GtkTreeIter * iter, gpointer data)
{
guint flags;
- gchar *name = NULL;
- gboolean visible = TRUE;
+ gboolean visible;
+ gchar *name;
+ const gchar *filterText;
TrgMainWindowPrivate *priv = TRG_MAIN_WINDOW_GET_PRIVATE(data);
guint32 criteria = trg_state_selector_get_flag(priv->stateSelector);
- gtk_tree_model_get(model, iter,
- TORRENT_COLUMN_FLAGS, &flags,
- TORRENT_COLUMN_NAME, &name, -1);
+ gtk_tree_model_get(model, iter, TORRENT_COLUMN_FLAGS, &flags, -1);
if (criteria != 0) {
if (criteria & FILTER_FLAG_TRACKER) {
- gchar *text = trg_state_selector_get_selected_text(priv->stateSelector);
+ gchar *text =
+ trg_state_selector_get_selected_text(priv->stateSelector);
JsonObject *json = NULL;
- gtk_tree_model_get(model, iter, TORRENT_COLUMN_JSON, &json, -1);
-
- if (!torrent_has_tracker(json, trg_state_selector_get_url_host_regex(priv->stateSelector), text))
- visible = FALSE;
+ gtk_tree_model_get(model, iter, TORRENT_COLUMN_JSON, &json,
+ -1);
+
+ if (!torrent_has_tracker
+ (json,
+ trg_state_selector_get_url_host_regex
+ (priv->stateSelector), text))
+ return FALSE;
+ } else if (criteria & FILTER_FLAG_DIR) {
+ gchar *text =
+ trg_state_selector_get_selected_text(priv->stateSelector);
+ JsonObject *json = NULL;
+ gtk_tree_model_get(model, iter, TORRENT_COLUMN_JSON, &json,
+ -1);
+ if (g_strcmp0(text, torrent_get_download_dir(json)))
+ return FALSE;
} else if (!(flags & criteria)) {
- visible = FALSE;
+ return FALSE;
}
}
- if (visible && name != NULL) {
- const gchar *filterText =
- gtk_entry_get_text(GTK_ENTRY(priv->filterEntry));
- if (strlen(filterText) > 0) {
- gchar *filterCmp = g_utf8_casefold(filterText, -1);
- gchar *nameCmp = g_utf8_casefold(name, -1);
+ visible = TRUE;
+ name = NULL;
- if (!strstr(nameCmp, filterCmp))
- visible = FALSE;
+ gtk_tree_model_get(model, iter, TORRENT_COLUMN_NAME, &name, -1);
+ filterText = gtk_entry_get_text(GTK_ENTRY(priv->filterEntry));
+ if (strlen(filterText) > 0) {
+ gchar *filterCmp = g_utf8_casefold(filterText, -1);
+ gchar *nameCmp = g_utf8_casefold(name, -1);
- g_free(filterCmp);
- g_free(nameCmp);
- }
+ if (!strstr(nameCmp, filterCmp))
+ visible = FALSE;
+ g_free(filterCmp);
+ g_free(nameCmp);
}
-
g_free(name);
return visible;
@@ -1226,13 +1233,14 @@ void trg_main_window_conn_changed(TrgMainWindow * win, gboolean connected)
connected);
gtk_widget_set_sensitive(GTK_WIDGET(priv->genDetails), connected);;
- if (connected == FALSE) {
+ if (!connected) {
json_object_unref(tc->session);
tc->session = NULL;
gtk_list_store_clear(GTK_LIST_STORE(priv->torrentModel));
trg_main_window_torrent_scrub(win);
trg_torrent_graph_set_nothing(priv->graph);
+ trg_state_selector_disconnect(priv->stateSelector);
}
}
@@ -1736,6 +1744,12 @@ void trg_main_window_add_status_icon(TrgMainWindow * win)
G_CALLBACK(trg_status_icon_popup_menu_cb), win);
}
+TrgStateSelector *trg_main_window_get_state_selector(TrgMainWindow * win)
+{
+ TrgMainWindowPrivate *priv = TRG_MAIN_WINDOW_GET_PRIVATE(win);
+ return priv->stateSelector;
+}
+
static GObject *trg_main_window_constructor(GType type,
guint
n_construct_properties,
@@ -1749,7 +1763,6 @@ static GObject *trg_main_window_constructor(GType type,
GtkWidget *toolbarHbox;
GtkIconTheme *theme;
gint width, height;
- GError *error = NULL;
gboolean tray;
self = TRG_MAIN_WINDOW(G_OBJECT_CLASS
@@ -1781,7 +1794,7 @@ static GObject *trg_main_window_constructor(GType type,
g_signal_connect(priv->torrentModel, "torrent-added",
G_CALLBACK(on_torrent_added), self);
g_signal_connect(priv->torrentModel, "torrent-addremove",
- G_CALLBACK(on_torrent_addremove), self);
+ G_CALLBACK(on_torrent_addremove), self);
priv->filteredTorrentModel =
gtk_tree_model_filter_new(GTK_TREE_MODEL(priv->torrentModel),
@@ -1856,9 +1869,10 @@ static GObject *trg_main_window_constructor(GType type,
gtk_box_pack_start(GTK_BOX(outerVbox), priv->vpaned, TRUE, TRUE, 0);
gtk_paned_pack1(GTK_PANED(priv->vpaned), priv->hpaned, TRUE, TRUE);
- priv->stateSelector = trg_state_selector_new();
+ priv->stateSelector = trg_state_selector_new(priv->client);
gtk_paned_pack1(GTK_PANED(priv->hpaned),
- GTK_WIDGET(priv->stateSelector), FALSE, FALSE);
+ my_scrolledwin_new(GTK_WIDGET(priv->stateSelector)),
+ FALSE, FALSE);
gtk_paned_pack2(GTK_PANED(priv->hpaned),
my_scrolledwin_new(GTK_WIDGET
@@ -1874,13 +1888,8 @@ static GObject *trg_main_window_constructor(GType type,
gtk_paned_pack2(GTK_PANED(priv->vpaned), priv->notebook, FALSE, FALSE);
tray =
- gconf_client_get_bool(priv->client->gconf,
- TRG_GCONF_KEY_SYSTEM_TRAY, &error);
- if (error) {
- g_error_free(error);
- tray = TRUE;
- }
-
+ gconf_client_get_bool_or_true(priv->client->gconf,
+ TRG_GCONF_KEY_SYSTEM_TRAY);
if (tray) {
trg_main_window_add_status_icon(self);
} else {
diff --git a/src/trg-main-window.h b/src/trg-main-window.h
index cdba421..09a2439 100644
--- a/src/trg-main-window.h
+++ b/src/trg-main-window.h
@@ -71,6 +71,7 @@ void trg_main_window_add_status_icon(TrgMainWindow * win);
void trg_main_window_remove_status_icon(TrgMainWindow * win);
void trg_main_window_add_graph(TrgMainWindow * win, gboolean show);
void trg_main_window_remove_graph(TrgMainWindow * win);
+TrgStateSelector *trg_main_window_get_state_selector(TrgMainWindow * win);
G_END_DECLS
#endif /* MAIN_WINDOW_H_ */
diff --git a/src/trg-model.h b/src/trg-model.h
index 987cfca..9059303 100644
--- a/src/trg-model.h
+++ b/src/trg-model.h
@@ -23,7 +23,7 @@
#include <gtk/gtk.h>
guint trg_model_remove_removed(GtkListStore * model, gint serial_column,
- gint64 currentSerial);
+ gint64 currentSerial);
gboolean
find_existing_model_item(GtkTreeModel * model, gint search_column,
diff --git a/src/trg-preferences-dialog.c b/src/trg-preferences-dialog.c
index b4546fa..c20c2cf 100644
--- a/src/trg-preferences-dialog.c
+++ b/src/trg-preferences-dialog.c
@@ -208,7 +208,23 @@ static GtkWidget *new_entry(GConfClient * gconf, const char *key)
return w;
}
-static void toggle_show_graph(GtkToggleButton * w, gpointer win)
+static void toggle_filter_trackers(GtkToggleButton * w, gpointer win)
+{
+ TrgStateSelector *selector =
+ trg_main_window_get_state_selector(TRG_MAIN_WINDOW(win));
+ trg_state_selector_set_show_trackers(selector,
+ gtk_toggle_button_get_active(w));
+}
+
+static void toggle_filter_dirs(GtkToggleButton * w, gpointer win)
+{
+ TrgStateSelector *selector =
+ trg_main_window_get_state_selector(TRG_MAIN_WINDOW(win));
+ trg_state_selector_set_show_dirs(selector,
+ gtk_toggle_button_get_active(w));
+}
+
+static void toggle_graph(GtkToggleButton * w, gpointer win)
{
if (gtk_toggle_button_get_active(w))
trg_main_window_add_graph(TRG_MAIN_WINDOW(win), TRUE);
@@ -234,9 +250,21 @@ static GtkWidget *trg_prefs_desktopPage(GConfClient * gconf,
hig_workarea_add_section_title(t, &row, _("Features"));
+ w = new_check_button(gconf, _("Directory filters"),
+ TRG_GCONF_KEY_FILTER_DIRS);
+ g_signal_connect(G_OBJECT(w), "toggled",
+ G_CALLBACK(toggle_filter_dirs), win);
+ hig_workarea_add_wide_control(t, &row, w);
+
+ w = new_check_button(gconf, _("Tracker filters"),
+ TRG_GCONF_KEY_FILTER_TRACKERS);
+ g_signal_connect(G_OBJECT(w), "toggled",
+ G_CALLBACK(toggle_filter_trackers), win);
+ hig_workarea_add_wide_control(t, &row, w);
+
w = new_check_button(gconf, _("Show graph"), TRG_GCONF_KEY_SHOW_GRAPH);
g_signal_connect(G_OBJECT(w), "toggled",
- G_CALLBACK(toggle_show_graph), win);
+ G_CALLBACK(toggle_graph), win);
hig_workarea_add_wide_control(t, &row, w);
hig_workarea_add_section_title(t, &row, _("System Tray"));
diff --git a/src/trg-preferences.h b/src/trg-preferences.h
index c2c43b4..6702de0 100644
--- a/src/trg-preferences.h
+++ b/src/trg-preferences.h
@@ -28,11 +28,13 @@
#define TRG_GCONF_KEY_SSL "/apps/transmission-remote-gtk/ssl"
#define TRG_GCONF_KEY_UPDATE_INTERVAL "/apps/transmission-remote-gtk/update-interval"
#define TRG_GCONF_KEY_COMPLETE_NOTIFY "/apps/transmission-remote-gtk/complete-notify"
-#define TRG_GCONF_KEY_ADD_NOTIFY "/apps/transmission-remote-gtk/add-notify"
+#define TRG_GCONF_KEY_ADD_NOTIFY "/apps/transmission-remote-gtk/add-notify"
#define TRG_GCONF_KEY_WINDOW_WIDTH "/apps/transmission-remote-gtk/window-width"
-#define TRG_GCONF_KEY_WINDOW_HEIGHT "/apps/transmission-remote-gtk/window-height"
-#define TRG_GCONF_KEY_SYSTEM_TRAY "/apps/transmission-remote-gtk/system-tray"
-#define TRG_GCONF_KEY_SHOW_GRAPH "/apps/transmission-remote-gtk/show-graph"
+#define TRG_GCONF_KEY_WINDOW_HEIGHT "/apps/transmission-remote-gtk/window-height"
+#define TRG_GCONF_KEY_SYSTEM_TRAY "/apps/transmission-remote-gtk/system-tray"
+#define TRG_GCONF_KEY_SHOW_GRAPH "/apps/transmission-remote-gtk/show-graph"
#define TRG_GCONF_KEY_SYSTEM_TRAY_MINIMISE "/apps/transmission-remote-gtk/system-tray-minimise"
+#define TRG_GCONF_KEY_FILTER_TRACKERS "/apps/transmission-remote-gtk/filter-trackers"
+#define TRG_GCONF_KEY_FILTER_DIRS "/apps/transmission-remote-gtk/filter-dirs"
#endif /* TRG_PREFERENCES_H_ */
diff --git a/src/trg-state-selector.c b/src/trg-state-selector.c
index f20a407..b6447ee 100644
--- a/src/trg-state-selector.c
+++ b/src/trg-state-selector.c
@@ -25,6 +25,8 @@
#include "torrent.h"
#include "trg-state-selector.h"
#include "util.h"
+#include "trg-preferences.h"
+#include "trg-client.h"
enum {
SELECTOR_STATE_CHANGED,
@@ -40,11 +42,15 @@ typedef struct _TrgStateSelectorPrivate TrgStateSelectorPrivate;
struct _TrgStateSelectorPrivate {
guint flag;
+ gboolean showDirs;
+ gboolean showTrackers;
+ trg_client *client;
GHashTable *trackers;
+ GHashTable *directories;
GRegex *urlHostRegex;
};
-GRegex *trg_state_selector_get_url_host_regex(TrgStateSelector *s)
+GRegex *trg_state_selector_get_url_host_regex(TrgStateSelector * s)
{
TrgStateSelectorPrivate *priv = TRG_STATE_SELECTOR_GET_PRIVATE(s);
return priv->urlHostRegex;
@@ -95,7 +101,8 @@ static void state_selection_changed(GtkTreeSelection * selection,
signals[SELECTOR_STATE_CHANGED], 0, priv->flag);
}
-static GtkTreeRowReference *quick_tree_ref_new(GtkTreeModel *model, GtkTreeIter *iter)
+static GtkTreeRowReference *quick_tree_ref_new(GtkTreeModel * model,
+ GtkTreeIter * iter)
{
GtkTreePath *path = gtk_tree_model_get_path(model, iter);
GtkTreeRowReference *rr = gtk_tree_row_reference_new(model, path);
@@ -108,10 +115,12 @@ struct cruft_remove_args {
gint64 serial;
};
-static gboolean trg_state_selector_remove_cruft(gpointer key, gpointer value, gpointer data)
+static gboolean trg_state_selector_remove_cruft(gpointer key,
+ gpointer value,
+ gpointer data)
{
- struct cruft_remove_args *args = (struct cruft_remove_args*)data;
- GtkTreeRowReference *rr = (GtkTreeRowReference*)value;
+ struct cruft_remove_args *args = (struct cruft_remove_args *) data;
+ GtkTreeRowReference *rr = (GtkTreeRowReference *) value;
GtkTreeModel *model = gtk_tree_row_reference_get_model(rr);
GtkTreePath *path = gtk_tree_row_reference_get_path(rr);
gboolean remove;
@@ -120,7 +129,8 @@ static gboolean trg_state_selector_remove_cruft(gpointer key, gpointer value, gp
gint64 currentSerial;
gtk_tree_model_get_iter(model, &iter, path);
- gtk_tree_model_get(model, &iter, STATE_SELECTOR_SERIAL, &currentSerial, -1);
+ gtk_tree_model_get(model, &iter, STATE_SELECTOR_SERIAL, &currentSerial,
+ -1);
remove = (args->serial != currentSerial);
@@ -129,7 +139,7 @@ static gboolean trg_state_selector_remove_cruft(gpointer key, gpointer value, gp
return remove;
}
-gchar *trg_state_selector_get_selected_text(TrgStateSelector *s)
+gchar *trg_state_selector_get_selected_text(TrgStateSelector * s)
{
GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(s));
GtkTreeModel *model;
@@ -142,55 +152,177 @@ gchar *trg_state_selector_get_selected_text(TrgStateSelector *s)
return name;
}
-void trg_state_selector_update_trackers(TrgStateSelector *s, JsonArray *torrents, gint64 serial)
+static void trg_state_selector_update_serial(GtkTreeModel * model,
+ GtkTreeRowReference * rr,
+ gint64 serial)
{
- TrgStateSelectorPrivate *priv = TRG_STATE_SELECTOR_GET_PRIVATE(s);
- GtkTreeModel *model;
GtkTreeIter iter;
- int i, j;
- struct cruft_remove_args cruft;
+ GtkTreePath *path = gtk_tree_row_reference_get_path(rr);
+ gtk_tree_model_get_iter(model, &iter, path);
+ gtk_list_store_set(GTK_LIST_STORE(model), &iter,
+ STATE_SELECTOR_SERIAL, serial, -1);
+ gtk_tree_path_free(path);
+}
- model = gtk_tree_view_get_model(GTK_TREE_VIEW(s));
+static void refresh_statelist_cb(GtkWidget * w, gpointer data)
+{
+ trg_state_selector_update(TRG_STATE_SELECTOR(data));
+}
- for (i = 0; i < json_array_get_length(torrents); i++) {
- JsonObject *t = json_array_get_object_element(torrents, i);
- JsonArray *trackers = torrent_get_trackers(t);
+static void
+view_popup_menu(GtkWidget * treeview, GdkEventButton * event,
+ gpointer data G_GNUC_UNUSED)
+{
+ GtkWidget *menu, *item;
- for (j = 0; j < json_array_get_length(trackers); j++) {
- JsonObject *tracker = json_array_get_object_element(trackers, j);
- const gchar *announceUrl = tracker_get_announce(tracker);
- gchar *announceHost = trg_uri_host_extract(priv->urlHostRegex, announceUrl);
- gpointer result;
+ menu = gtk_menu_new();
- if (!announceHost)
- continue;
+ item = gtk_image_menu_item_new_with_label(GTK_STOCK_REFRESH);
+ gtk_image_menu_item_set_use_stock(GTK_IMAGE_MENU_ITEM(item), TRUE);
+ gtk_image_menu_item_set_always_show_image(GTK_IMAGE_MENU_ITEM
+ (item), TRUE);
+ g_signal_connect(item, "activate", G_CALLBACK(refresh_statelist_cb),
+ treeview);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
- result = g_hash_table_lookup(priv->trackers, announceHost);
+ gtk_widget_show_all(menu);
- if (result)
- {
- GtkTreeRowReference *rr = (GtkTreeRowReference*)result;
- GtkTreePath *path = gtk_tree_row_reference_get_path(rr);
- gtk_tree_model_get_iter(model, &iter, path);
- gtk_list_store_set(GTK_LIST_STORE(model), &iter,
- STATE_SELECTOR_SERIAL, serial, -1);
- gtk_tree_path_free(path);
+ gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
+ (event != NULL) ? event->button : 0,
+ gdk_event_get_time((GdkEvent *) event));
+}
+
+static gboolean view_onPopupMenu(GtkWidget * treeview, gpointer userdata)
+{
+ view_popup_menu(treeview, NULL, userdata);
+ return TRUE;
+}
+
+static gboolean
+view_onButtonPressed(GtkWidget * treeview, GdkEventButton * event,
+ gpointer userdata)
+{
+ if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
+ view_popup_menu(treeview, event, userdata);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void trg_state_selector_update(TrgStateSelector * s)
+{
+ TrgStateSelectorPrivate *priv = TRG_STATE_SELECTOR_GET_PRIVATE(s);
+ GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(s));
+ trg_client *client = priv->client;
+ GtkTreeIter iter;
+ int i, j;
+ struct cruft_remove_args cruft;
+
+ for (i = 0; i < json_array_get_length(client->torrents); i++) {
+ JsonObject *t = json_array_get_object_element(client->torrents, i);
+ gpointer result;
+
+ if (priv->showTrackers) {
+ JsonArray *trackers = torrent_get_trackers(t);
+
+ for (j = 0; j < json_array_get_length(trackers); j++) {
+ JsonObject *tracker =
+ json_array_get_object_element(trackers, j);
+ const gchar *announceUrl = tracker_get_announce(tracker);
+ gchar *announceHost =
+ trg_gregex_get_first(priv->urlHostRegex, announceUrl);
+
+ if (!announceHost)
+ continue;
+
+ result = g_hash_table_lookup(priv->trackers, announceHost);
+
+ if (result) {
+ trg_state_selector_update_serial(model,
+ (GtkTreeRowReference
+ *)
+ result,
+ client->updateSerial);
+ } else {
+ gtk_list_store_insert(GTK_LIST_STORE(model), &iter,
+ 9 +
+ g_hash_table_size(priv->
+ trackers));
+ gtk_list_store_set(GTK_LIST_STORE(model), &iter,
+ STATE_SELECTOR_ICON,
+ GTK_STOCK_NETWORK,
+ STATE_SELECTOR_NAME, announceHost,
+ STATE_SELECTOR_SERIAL,
+ client->updateSerial,
+ STATE_SELECTOR_BIT,
+ FILTER_FLAG_TRACKER, -1);
+ g_hash_table_insert(priv->trackers, announceHost,
+ quick_tree_ref_new(model, &iter));
+ }
+ }
+ }
+
+ if (priv->showDirs) {
+ const gchar *dir = torrent_get_download_dir(t);
+ result = g_hash_table_lookup(priv->directories, dir);
+ if (result) {
+ trg_state_selector_update_serial(model,
+ (GtkTreeRowReference *)
+ result,
+ client->updateSerial);
} else {
gtk_list_store_append(GTK_LIST_STORE(model), &iter);
gtk_list_store_set(GTK_LIST_STORE(model), &iter,
- STATE_SELECTOR_ICON, GTK_STOCK_NETWORK,
- STATE_SELECTOR_NAME, announceHost,
- STATE_SELECTOR_SERIAL, serial,
- STATE_SELECTOR_BIT, FILTER_FLAG_TRACKER, -1);
- g_hash_table_insert(priv->trackers, announceHost, quick_tree_ref_new(model, &iter));
+ STATE_SELECTOR_ICON,
+ GTK_STOCK_DIRECTORY,
+ STATE_SELECTOR_NAME, dir,
+ STATE_SELECTOR_SERIAL,
+ client->updateSerial,
+ STATE_SELECTOR_BIT, FILTER_FLAG_DIR,
+ -1);
+ g_hash_table_insert(priv->directories, g_strdup(dir),
+ quick_tree_ref_new(model, &iter));
}
}
}
- cruft.serial = serial;
- cruft.table = priv->trackers;
+ cruft.serial = client->updateSerial;
+
+ if (priv->showTrackers) {
+ cruft.table = priv->trackers;
+ g_hash_table_foreach_remove(priv->trackers,
+ trg_state_selector_remove_cruft,
+ &cruft);
+ }
+
+ if (priv->showDirs) {
+ cruft.table = priv->directories;
+ g_hash_table_foreach_remove(priv->directories,
+ trg_state_selector_remove_cruft,
+ &cruft);
+ }
+}
+
+void trg_state_selector_set_show_dirs(TrgStateSelector * s, gboolean show)
+{
+ TrgStateSelectorPrivate *priv = TRG_STATE_SELECTOR_GET_PRIVATE(s);
+ priv->showDirs = show;
+ if (!show)
+ g_hash_table_remove_all(priv->directories);
+ else
+ trg_state_selector_update(s);
+}
- g_hash_table_foreach_remove(priv->trackers, trg_state_selector_remove_cruft, &cruft);
+void trg_state_selector_set_show_trackers(TrgStateSelector * s,
+ gboolean show)
+{
+ TrgStateSelectorPrivate *priv = TRG_STATE_SELECTOR_GET_PRIVATE(s);
+ priv->showTrackers = show;
+ if (!show)
+ g_hash_table_remove_all(priv->trackers);
+ else
+ trg_state_selector_update(s);
}
static void trg_state_selector_add_state(GtkListStore * model,
@@ -204,7 +336,7 @@ static void trg_state_selector_add_state(GtkListStore * model,
STATE_SELECTOR_BIT, flag, -1);
}
-static void remove_row_ref_and_free(GtkTreeRowReference *rr)
+static void remove_row_ref_and_free(GtkTreeRowReference * rr)
{
GtkTreeModel *model = gtk_tree_row_reference_get_model(rr);
GtkTreePath *path = gtk_tree_row_reference_get_path(rr);
@@ -216,6 +348,14 @@ static void remove_row_ref_and_free(GtkTreeRowReference *rr)
gtk_tree_row_reference_free(rr);
}
+void trg_state_selector_disconnect(TrgStateSelector * s)
+{
+ TrgStateSelectorPrivate *priv = TRG_STATE_SELECTOR_GET_PRIVATE(s);
+
+ g_hash_table_remove_all(priv->trackers);
+ g_hash_table_remove_all(priv->directories);
+}
+
static void trg_state_selector_init(TrgStateSelector * self)
{
TrgStateSelectorPrivate *priv;
@@ -229,7 +369,12 @@ static void trg_state_selector_init(TrgStateSelector * self)
priv->flag = 0;
priv->urlHostRegex = trg_uri_host_regex_new();
- priv->trackers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)remove_row_ref_and_free);
+ priv->trackers =
+ g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
+ (GDestroyNotify) remove_row_ref_and_free);
+ priv->directories =
+ g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
+ (GDestroyNotify) remove_row_ref_and_free);
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(self), FALSE);
@@ -268,8 +413,7 @@ static void trg_state_selector_init(TrgStateSelector * self)
_("Seeding"), TORRENT_FLAG_SEEDING);
trg_state_selector_add_state(store, &iter, GTK_STOCK_DIALOG_WARNING,
_("Error"), TORRENT_FLAG_ERROR);
- trg_state_selector_add_state(store, &iter, NULL,
- NULL, 0);
+ trg_state_selector_add_state(store, &iter, NULL, NULL, 0);
gtk_tree_view_set_model(GTK_TREE_VIEW(self), GTK_TREE_MODEL(store));
gtk_tree_view_set_rubber_banding(GTK_TREE_VIEW(self), TRUE);
@@ -280,9 +424,24 @@ static void trg_state_selector_init(TrgStateSelector * self)
g_signal_connect(G_OBJECT(selection), "changed",
G_CALLBACK(state_selection_changed), self);
+ g_signal_connect(self, "button-press-event",
+ G_CALLBACK(view_onButtonPressed), NULL);
+ g_signal_connect(self, "popup-menu", G_CALLBACK(view_onPopupMenu),
+ NULL);
}
-TrgStateSelector *trg_state_selector_new(void)
+TrgStateSelector *trg_state_selector_new(trg_client * client)
{
- return g_object_new(TRG_TYPE_STATE_SELECTOR, NULL);
+ GObject *obj = g_object_new(TRG_TYPE_STATE_SELECTOR, NULL);
+ TrgStateSelectorPrivate *priv = TRG_STATE_SELECTOR_GET_PRIVATE(obj);
+
+ priv->client = client;
+ priv->showDirs =
+ gconf_client_get_bool_or_true(client->gconf,
+ TRG_GCONF_KEY_FILTER_DIRS);
+ priv->showTrackers =
+ gconf_client_get_bool_or_true(client->gconf,
+ TRG_GCONF_KEY_FILTER_TRACKERS);
+
+ return TRG_STATE_SELECTOR(obj);
}
diff --git a/src/trg-state-selector.h b/src/trg-state-selector.h
index d09d76a..30a1455 100644
--- a/src/trg-state-selector.h
+++ b/src/trg-state-selector.h
@@ -24,6 +24,8 @@
#include <glib-object.h>
#include <json-glib/json-glib.h>
+#include "trg-client.h"
+
enum {
STATE_SELECTOR_ICON,
STATE_SELECTOR_NAME,
@@ -52,16 +54,20 @@ typedef struct {
GtkTreeViewClass parent_class;
void (*torrent_state_changed) (TrgStateSelector * selector,
- guint flag, gpointer data);
+ guint flag, gpointer data);
} TrgStateSelectorClass;
GType trg_state_selector_get_type(void);
-TrgStateSelector *trg_state_selector_new(void);
+TrgStateSelector *trg_state_selector_new(trg_client * client);
G_END_DECLS guint32 trg_state_selector_get_flag(TrgStateSelector * s);
-void trg_state_selector_update_trackers(TrgStateSelector *s, JsonArray *torrents, gint64 serial);
-gchar *trg_state_selector_get_selected_text(TrgStateSelector *s);
-GRegex *trg_state_selector_get_url_host_regex(TrgStateSelector *s);
+void trg_state_selector_update(TrgStateSelector * s);
+gchar *trg_state_selector_get_selected_text(TrgStateSelector * s);
+GRegex *trg_state_selector_get_url_host_regex(TrgStateSelector * s);
+void trg_state_selector_disconnect(TrgStateSelector * s);
+void trg_state_selector_set_show_trackers(TrgStateSelector * s,
+ gboolean show);
+void trg_state_selector_set_show_dirs(TrgStateSelector * s, gboolean show);
#endif /* TRG_STATE_LIST_H_ */
diff --git a/src/trg-torrent-model.c b/src/trg-torrent-model.c
index 7fa82ae..1753619 100644
--- a/src/trg-torrent-model.c
+++ b/src/trg-torrent-model.c
@@ -77,8 +77,7 @@ static void trg_torrent_model_class_init(TrgTorrentModelClass * klass)
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET(TrgTorrentModelClass,
torrent_removed), NULL,
- NULL, g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
}
@@ -319,7 +318,7 @@ void trg_torrent_model_update(TrgTorrentModel * model, trg_client * tc,
tc->torrents = newTorrents;
if (trg_model_remove_removed(GTK_LIST_STORE(model),
- TORRENT_COLUMN_UPDATESERIAL,
- tc->updateSerial) > 0 || added)
+ TORRENT_COLUMN_UPDATESERIAL,
+ tc->updateSerial) > 0 || added)
g_signal_emit(model, signals[TMODEL_TORRENT_ADDREMOVE], 0);
}
diff --git a/src/trg-torrent-model.h b/src/trg-torrent-model.h
index ee064d2..03ee64f 100644
--- a/src/trg-torrent-model.h
+++ b/src/trg-torrent-model.h
@@ -45,13 +45,11 @@ G_BEGIN_DECLS
typedef struct {
GtkListStoreClass parent_class;
void (*torrent_completed) (TrgTorrentModel * model,
- GtkTreeIter * iter,
- gpointer data);
+ GtkTreeIter * iter, gpointer data);
void (*torrent_added) (TrgTorrentModel * model,
- GtkTreeIter * iter,
- gpointer data);
+ GtkTreeIter * iter, gpointer data);
- void (*torrent_removed) (TrgTorrentModel *model, gpointer data);
+ void (*torrent_removed) (TrgTorrentModel * model, gpointer data);
} TrgTorrentModelClass;
typedef struct {
diff --git a/src/trg-torrent-props-dialog.c b/src/trg-torrent-props-dialog.c
index 2851b7c..bf9f096 100644
--- a/src/trg-torrent-props-dialog.c
+++ b/src/trg-torrent-props-dialog.c
@@ -138,12 +138,10 @@ trg_torrent_props_response_cb(GtkDialog * dlg, gint res_id,
(priv->seedRatioLimit), args);
json_object_set_int_member(args, FIELD_SEED_RATIO_MODE,
gtk_combo_box_get_active(GTK_COMBO_BOX
- (priv->
- seedRatioMode)));
+ (priv->seedRatioMode)));
json_object_set_int_member(args, FIELD_BANDWIDTH_PRIORITY,
gtk_combo_box_get_active(GTK_COMBO_BOX
- (priv->
- bandwidthPriorityCombo))
+ (priv->bandwidthPriorityCombo))
- 1);
gtk_spin_button_json_int_out(GTK_SPIN_BUTTON
diff --git a/src/util.c b/src/util.c
index bd20d14..6cb6e11 100644
--- a/src/util.c
+++ b/src/util.c
@@ -23,6 +23,7 @@
#include <math.h>
#include <string.h>
+#include <gconf/gconf-client.h>
#include <glib/gi18n.h>
#include <glib-object.h>
#include <curl/curl.h>
@@ -36,19 +37,20 @@
GRegex *trg_uri_host_regex_new(void)
{
- return g_regex_new("^[^:/?#]+:?//([^/?#]*)", 0, 0, NULL);
+ return g_regex_new("^[^:/?#]+:?//([^/?#]*)", G_REGEX_OPTIMIZE, 0,
+ NULL);
}
-gchar *trg_uri_host_extract(GRegex *rx, const gchar *uri)
+gchar *trg_gregex_get_first(GRegex * rx, const gchar * src)
{
GMatchInfo *mi = NULL;
- gchar *host = NULL;
- g_regex_match (rx, uri, 0, &mi);
+ gchar *dst = NULL;
+ g_regex_match(rx, src, 0, &mi);
if (mi) {
- host = g_match_info_fetch(mi, 1);
- g_match_info_free (mi);
+ dst = g_match_info_fetch(mi, 1);
+ g_match_info_free(mi);
}
- return host;
+ return dst;
}
void trg_error_dialog(GtkWindow * parent, int status,
@@ -66,6 +68,17 @@ void trg_error_dialog(GtkWindow * parent, int status,
g_free((gpointer) msg);
}
+gboolean gconf_client_get_bool_or_true(GConfClient * gconf, gchar * key)
+{
+ GError *error = NULL;
+ gboolean value = gconf_client_get_bool(gconf, key, &error);
+ if (error) {
+ g_error_free(error);
+ return TRUE;
+ }
+ return value;
+}
+
const gchar *make_error_message(JsonObject * response, int status)
{
if (status == FAIL_JSON_DECODE) {
diff --git a/src/util.h b/src/util.h
index 6d9e62c..a3b2053 100644
--- a/src/util.h
+++ b/src/util.h
@@ -22,6 +22,7 @@
#ifndef UTIL_H_
#define UTIL_H_
+#include <gconf/gconf-client.h>
#include <glib-object.h>
#include <json-glib/json-glib.h>
@@ -37,7 +38,13 @@
#define GIGABYTE_FACTOR ( 1024.0 * 1024.0 * 1024.0 )
GRegex *trg_uri_host_regex_new(void);
-gchar *trg_uri_host_extract(GRegex *rx, const gchar *uri);
+gchar *trg_gregex_get_first(GRegex * rx, const gchar * uri);
+gboolean gconf_client_get_bool_or_true(GConfClient * gconf, gchar * key);
+
+void response_unref(JsonObject * response);
+const gchar *make_error_message(JsonObject * response, int status);
+void trg_error_dialog(GtkWindow * parent, int status,
+ JsonObject * response);
char *tr_strltime_long(char *buf, gint64 seconds, size_t buflen);
char *tr_strltime_short(char *buf, gint64 seconds, size_t buflen);
@@ -56,9 +63,5 @@ size_t tr_strlcpy(char *dst, const void *src, size_t siz);
double tr_truncd(double x, int decimal_places);
int evutil_vsnprintf(char *buf, size_t buflen, const char *format,
va_list ap);
-void response_unref(JsonObject * response);
-const gchar *make_error_message(JsonObject * response, int status);
-void trg_error_dialog(GtkWindow * parent, int status,
- JsonObject * response);
#endif /* UTIL_H_ */
diff --git a/po/transmission-remote-gtk.pot b/transmission-remote-gtk.pot
index eaf0edb..3c0e50a 100644
--- a/po/transmission-remote-gtk.pot
+++ b/transmission-remote-gtk.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2011-03-10 15:46+0000\n"
+"POT-Creation-Date: 2011-03-11 22:11+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -30,20 +30,20 @@ msgstr ""
msgid "No"
msgstr ""
-#: src/torrent.c:199 src/trg-state-selector.c:257
+#: src/torrent.c:199 src/trg-state-selector.c:389
msgid "Downloading"
msgstr ""
-#: src/torrent.c:201 src/trg-state-selector.c:260
+#: src/torrent.c:201 src/trg-state-selector.c:392
msgid "Paused"
msgstr ""
#: src/torrent.c:203 src/trg-remote-prefs-dialog.c:257
-#: src/trg-state-selector.c:268 src/trg-torrent-props-dialog.c:219
+#: src/trg-state-selector.c:400 src/trg-torrent-props-dialog.c:219
msgid "Seeding"
msgstr ""
-#: src/torrent.c:205 src/trg-state-selector.c:262
+#: src/torrent.c:205 src/trg-state-selector.c:394
msgid "Checking"
msgstr ""
@@ -97,7 +97,7 @@ msgstr ""
msgid "Priority"
msgstr ""
-#: src/trg-general-panel.c:162 src/trg-state-selector.c:270 src/util.c:63
+#: src/trg-general-panel.c:162 src/trg-state-selector.c:402 src/util.c:65
msgid "Error"
msgstr ""
@@ -149,132 +149,140 @@ msgstr ""
msgid "Location"
msgstr ""
-#: src/trg-main-window.c:434
+#: src/trg-main-window.c:311
+msgid "This torrent has completed."
+msgstr ""
+
+#: src/trg-main-window.c:326
+msgid "This torrent has been added."
+msgstr ""
+
+#: src/trg-main-window.c:435
msgid "BitTorrent Metadata"
msgstr ""
-#: src/trg-main-window.c:520
+#: src/trg-main-window.c:521
msgid ""
"Unable to retrieve connection settings from GConf. Schema not installed?"
msgstr ""
-#: src/trg-main-window.c:523
+#: src/trg-main-window.c:524
msgid "No hostname set"
msgstr ""
-#: src/trg-main-window.c:526
+#: src/trg-main-window.c:527
msgid "Unknown error getting settings"
msgstr ""
-#: src/trg-main-window.c:544
+#: src/trg-main-window.c:545
msgid "Connecting..."
msgstr ""
-#: src/trg-main-window.c:715
+#: src/trg-main-window.c:716
#, c-format
msgid "<big><b>Remove torrent \"%s\"?</b></big>"
msgstr ""
-#: src/trg-main-window.c:716
+#: src/trg-main-window.c:717
#, c-format
msgid "<big><b>Remove %d torrents?</b></big>"
msgstr ""
-#: src/trg-main-window.c:740
+#: src/trg-main-window.c:741
#, c-format
msgid "<big><b>Remove and delete torrent \"%s\"?</b></big>"
msgstr ""
-#: src/trg-main-window.c:741
+#: src/trg-main-window.c:742
#, c-format
msgid "<big><b>Remove and delete %d torrents?</b></big>"
msgstr ""
-#: src/trg-main-window.c:811 src/trg-remote-prefs-dialog.c:612
+#: src/trg-main-window.c:812 src/trg-remote-prefs-dialog.c:612
msgid "General"
msgstr ""
-#: src/trg-main-window.c:819
+#: src/trg-main-window.c:820
msgid "Trackers"
msgstr ""
-#: src/trg-main-window.c:827
+#: src/trg-main-window.c:828
msgid "Files"
msgstr ""
-#: src/trg-main-window.c:834 src/trg-remote-prefs-dialog.c:277
+#: src/trg-main-window.c:835 src/trg-remote-prefs-dialog.c:277
#: src/trg-torrent-props-dialog.c:242
msgid "Peers"
msgstr ""
-#: src/trg-main-window.c:936
+#: src/trg-main-window.c:935
#, c-format
msgid "Request %d/%d failed: %s"
msgstr ""
-#: src/trg-main-window.c:1460
+#: src/trg-main-window.c:1469
msgid "No Limit"
msgstr ""
-#: src/trg-main-window.c:1497 src/trg-toolbar.c:238
+#: src/trg-main-window.c:1506 src/trg-toolbar.c:238
msgid "Properties"
msgstr ""
-#: src/trg-main-window.c:1500 src/trg-toolbar.c:231
+#: src/trg-main-window.c:1509 src/trg-toolbar.c:231
msgid "Resume"
msgstr ""
-#: src/trg-main-window.c:1503 src/trg-toolbar.c:234
+#: src/trg-main-window.c:1512 src/trg-toolbar.c:234
msgid "Pause"
msgstr ""
-#: src/trg-main-window.c:1506
+#: src/trg-main-window.c:1515
msgid "Verify"
msgstr ""
-#: src/trg-main-window.c:1509
+#: src/trg-main-window.c:1518
msgid "Re-announce"
msgstr ""
-#: src/trg-main-window.c:1512 src/trg-torrent-move-dialog.c:99
+#: src/trg-main-window.c:1521 src/trg-torrent-move-dialog.c:99
#: src/trg-torrent-move-dialog.c:106
msgid "Move"
msgstr ""
-#: src/trg-main-window.c:1515 src/trg-menu-bar.c:307 src/trg-toolbar.c:242
+#: src/trg-main-window.c:1524 src/trg-menu-bar.c:307 src/trg-toolbar.c:242
msgid "Remove"
msgstr ""
-#: src/trg-main-window.c:1518
+#: src/trg-main-window.c:1527
msgid "Remove & Delete"
msgstr ""
-#: src/trg-main-window.c:1524 src/trg-main-window.c:1568
+#: src/trg-main-window.c:1533 src/trg-main-window.c:1577
msgid "Down Limit"
msgstr ""
-#: src/trg-main-window.c:1529 src/trg-main-window.c:1573
+#: src/trg-main-window.c:1538 src/trg-main-window.c:1582
msgid "Up Limit"
msgstr ""
-#: src/trg-main-window.c:1551 src/trg-toolbar.c:215
+#: src/trg-main-window.c:1560 src/trg-toolbar.c:215
msgid "Connect"
msgstr ""
-#: src/trg-main-window.c:1555 src/trg-toolbar.c:218
+#: src/trg-main-window.c:1564 src/trg-toolbar.c:218
msgid "Disconnect"
msgstr ""
-#: src/trg-main-window.c:1559 src/trg-toolbar.c:221
+#: src/trg-main-window.c:1568 src/trg-toolbar.c:221
#: src/trg-trackers-tree-view.c:251 src/trg-trackers-tree-view.c:278
msgid "Add"
msgstr ""
-#: src/trg-main-window.c:1562
+#: src/trg-main-window.c:1571
msgid "Add from URL"
msgstr ""
-#: src/trg-main-window.c:1702
+#: src/trg-main-window.c:1711
msgid "Graph"
msgstr ""
@@ -394,79 +402,87 @@ msgstr ""
msgid "Client"
msgstr ""
-#: src/trg-preferences-dialog.c:235
+#: src/trg-preferences-dialog.c:247
msgid "Features"
msgstr ""
-#: src/trg-preferences-dialog.c:237
+#: src/trg-preferences-dialog.c:249
+msgid "Directory filters"
+msgstr ""
+
+#: src/trg-preferences-dialog.c:254
+msgid "Tracker filters"
+msgstr ""
+
+#: src/trg-preferences-dialog.c:259
msgid "Show graph"
msgstr ""
-#: src/trg-preferences-dialog.c:242
+#: src/trg-preferences-dialog.c:264
msgid "System Tray"
msgstr ""
-#: src/trg-preferences-dialog.c:244
+#: src/trg-preferences-dialog.c:266
msgid "Show in system tray"
msgstr ""
-#: src/trg-preferences-dialog.c:250
+#: src/trg-preferences-dialog.c:272
msgid "Minimise to system tray"
msgstr ""
-#: src/trg-preferences-dialog.c:259
+#: src/trg-preferences-dialog.c:281
msgid "Torrent added notifications"
msgstr ""
-#: src/trg-preferences-dialog.c:268
+#: src/trg-preferences-dialog.c:290
msgid "Torrent complete notifications"
msgstr ""
-#: src/trg-preferences-dialog.c:288
+#: src/trg-preferences-dialog.c:310
msgid "Server"
msgstr ""
-#: src/trg-preferences-dialog.c:291
+#: src/trg-preferences-dialog.c:313
msgid "Host:"
msgstr ""
-#: src/trg-preferences-dialog.c:294
+#: src/trg-preferences-dialog.c:316
msgid "Port:"
msgstr ""
-#: src/trg-preferences-dialog.c:296
+#: src/trg-preferences-dialog.c:318
msgid "Automatically connect"
msgstr ""
-#: src/trg-preferences-dialog.c:300
+#: src/trg-preferences-dialog.c:322
msgid "SSL"
msgstr ""
-#: src/trg-preferences-dialog.c:306
+#: src/trg-preferences-dialog.c:328
msgid "Update interval:"
msgstr ""
-#: src/trg-preferences-dialog.c:309
+#: src/trg-preferences-dialog.c:331
msgid "Authentication"
msgstr ""
-#: src/trg-preferences-dialog.c:312
+#: src/trg-preferences-dialog.c:334
msgid "Username:"
msgstr ""
-#: src/trg-preferences-dialog.c:316
+#: src/trg-preferences-dialog.c:338
msgid "Password:"
msgstr ""
-#: src/trg-preferences-dialog.c:343 src/trg-toolbar.c:257
+#: src/trg-preferences-dialog.c:365 src/trg-toolbar.c:257
msgid "Local Preferences"
msgstr ""
-#: src/trg-preferences-dialog.c:355
+#: src/trg-preferences-dialog.c:377
msgid "Connection"
msgstr ""
-#: src/trg-preferences-dialog.c:359
+#: src/trg-preferences-dialog.c:381
msgid "Desktop"
msgstr ""
@@ -611,15 +627,15 @@ msgstr ""
msgid "Limits"
msgstr ""
-#: src/trg-state-selector.c:254
+#: src/trg-state-selector.c:386
msgid "All"
msgstr ""
-#: src/trg-state-selector.c:264
+#: src/trg-state-selector.c:396
msgid "Complete"
msgstr ""
-#: src/trg-state-selector.c:266
+#: src/trg-state-selector.c:398
msgid "Incomplete"
msgstr ""
@@ -785,87 +801,87 @@ msgstr ""
msgid "Delete"
msgstr ""
-#: src/util.c:72
+#: src/util.c:85
msgid "JSON decoding error."
msgstr ""
-#: src/util.c:77
+#: src/util.c:90
msgid "Server responded, but with no result."
msgstr ""
-#: src/util.c:81
+#: src/util.c:94
#, c-format
msgid "Request failed with HTTP code %d"
msgstr ""
-#: src/util.c:144
+#: src/util.c:157
msgid "None"
msgstr ""
-#: src/util.c:154
+#: src/util.c:167
#, c-format
msgid "%'u byte"
msgid_plural "%'u bytes"
msgstr[0] ""
msgstr[1] ""
-#: src/util.c:160
+#: src/util.c:173
#, c-format
msgid "%'.1f KB"
msgstr ""
-#: src/util.c:163
+#: src/util.c:176
#, c-format
msgid "%'.1f MB"
msgstr ""
-#: src/util.c:166
+#: src/util.c:179
#, c-format
msgid "%'.1f GB"
msgstr ""
-#: src/util.c:178
+#: src/util.c:191
#, c-format
msgid "%.1f KB/s"
msgstr ""
-#: src/util.c:180
+#: src/util.c:193
#, c-format
msgid "%.2f MB/s"
msgstr ""
-#: src/util.c:182
+#: src/util.c:195
#, c-format
msgid "%.1f MB/s"
msgstr ""
-#: src/util.c:184
+#: src/util.c:197
#, c-format
msgid "%.2f GB/s"
msgstr ""
-#: src/util.c:218
+#: src/util.c:231
#, c-format
msgid "%d day"
msgid_plural "%d days"
msgstr[0] ""
msgstr[1] ""
-#: src/util.c:219
+#: src/util.c:232
#, c-format
msgid "%d hour"
msgid_plural "%d hours"
msgstr[0] ""
msgstr[1] ""
-#: src/util.c:221
+#: src/util.c:234
#, c-format
msgid "%d minute"
msgid_plural "%d minutes"
msgstr[0] ""
msgstr[1] ""
-#: src/util.c:224
+#: src/util.c:237
#, c-format
msgid "%ld second"
msgid_plural "%ld seconds"