summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alan Fitton <ajf@eth0.org.uk>2011-12-23 11:10:49 +0000
committerGravatar Alan Fitton <ajf@eth0.org.uk>2011-12-23 11:10:49 +0000
commit408179693ea842150b469cf2f88eea9434d19698 (patch)
treef8583ccb507aeefbc2fd2735564309c3983caec7
parent268d1f5297c5b243f3045e8d1aae0feef3df13a7 (diff)
"turtle" mode in the status bar. for easy activation of alternative speed limits.
-rw-r--r--src/Makefile.am1
-rw-r--r--src/icon-turtle.h78
-rw-r--r--src/session-get.c5
-rw-r--r--src/session-get.h1
-rw-r--r--src/trg-icons.c72
-rw-r--r--src/trg-icons.h26
-rw-r--r--src/trg-main-window.c4
-rw-r--r--src/trg-status-bar.c126
8 files changed, 263 insertions, 50 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index a2243b6..c978ea5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -70,6 +70,7 @@ transmission_remote_gtk_SOURCES = main.c \
trg-state-selector.c \
trg-general-panel.c \
trg-toolbar.c \
+ trg-icons.c \
trg-menu-bar.c \
trg-status-bar.c \
trg-trackers-tree-view.c \
diff --git a/src/icon-turtle.h b/src/icon-turtle.h
new file mode 100644
index 0000000..f36566a
--- /dev/null
+++ b/src/icon-turtle.h
@@ -0,0 +1,78 @@
+/* GdkPixbuf RGBA C-Source image dump 1-byte-run-length-encoded */
+
+#ifdef __SUNPRO_C
+#pragma align 4 (blue_turtle)
+#endif
+#ifdef __GNUC__
+static const guint8 blue_turtle[] __attribute__ ((__aligned__ (4))) =
+#else
+static const guint8 blue_turtle[] =
+#endif
+{ ""
+ /* Pixbuf magic (0x47646b50) */
+ "GdkP"
+ /* length: header (24) + pixel_data (315) */
+ "\0\0\1S"
+ /* pixdata_type (0x2010002) */
+ "\2\1\0\2"
+ /* rowstride (80) */
+ "\0\0\0P"
+ /* width (20) */
+ "\0\0\0\24"
+ /* height (14) */
+ "\0\0\0\16"
+ /* pixel_data: */
+ "\304\377\377\377\0\3""66\377@77\377p55\3770\205\377\377\377\0\1\0\0\0"
+ "\0\211\377\377\377\0\2""66\3770<<\377\317\202\77\77\377\377\2>>\377\377"
+ "::\377\237\204\377\377\377\0\1\0\0\0\0\210\377\377\377\0\14""66\3770"
+ "BB\377\360FF\377\377II\377\377JJ\377\377HH\377\377DD\377\377==\377\237"
+ "\377\377\377\0""99\377`\77\77\377\377;;\377\237\207\377\377\377\0\4""5"
+ "5\377\20FF\377\360KK\377\377OO\377\377\202QQ\377\377\7PP\377\377NN\377"
+ "\377II\377\377EE\377\377FF\377\377II\377\377[[\377\267\207\377\377\377"
+ "\0\3EE\377\261NN\377\377TT\377\377\204VV\377\377\3UU\377\377ee\377\331"
+ "\252\252\377\214\202\377\377\377f\1\377\377\377@\207\377\377\377\0\3"
+ "\377\377\377F\224\224\377\240YY\377\377\204ZZ\377\377\3XX\377\377kk\377"
+ "\274\377\377\377\31\202\377\377\377\0\1\0\0\0\0\210\377\377\377\0\2m"
+ "m\377wvv\377\305\204\377\377\377f\3\230\230\377\237TT\377\377FF\377\237"
+ "\202\377\377\377\0\1\0\0\0\0\323\377\377\377\0"};
+
+
+/* GdkPixbuf RGBA C-Source image dump 1-byte-run-length-encoded */
+
+#ifdef __SUNPRO_C
+#pragma align 4 (grey_turtle)
+#endif
+#ifdef __GNUC__
+static const guint8 grey_turtle[] __attribute__ ((__aligned__ (4))) =
+#else
+static const guint8 grey_turtle[] =
+#endif
+{ ""
+ /* Pixbuf magic (0x47646b50) */
+ "GdkP"
+ /* length: header (24) + pixel_data (315) */
+ "\0\0\1S"
+ /* pixdata_type (0x2010002) */
+ "\2\1\0\2"
+ /* rowstride (80) */
+ "\0\0\0P"
+ /* width (20) */
+ "\0\0\0\24"
+ /* height (14) */
+ "\0\0\0\16"
+ /* pixel_data: */
+ "\304\377\377\377\0\3\3\3\3@\5\5\5p\2\2\2""0\205\377\377\377\0\1\0\0\0"
+ "\0\211\377\377\377\0\2\3\3\3""0\13\13\13\317\202\17\17\17\377\2\16\16"
+ "\16\377\11\11\11\237\204\377\377\377\0\1\0\0\0\0\210\377\377\377\0\14"
+ "\4\4\4""0\23\23\23\360\27\27\27\377\33\33\33\377\34\34\34\377\32\32\32"
+ "\377\25\25\25\377\14\14\14\237\377\377\377\0\7\7\7`\17\17\17\377\12\12"
+ "\12\237\207\377\377\377\0\4\2\2\2\20\27\27\27\360\36\36\36\377###\377"
+ "\202%%%\377\7$$$\377!!!\377\33\33\33\377\26\26\26\377\30\30\30\377\33"
+ "\33\33\377222\267\207\377\377\377\0\3\26\26\26\261\"\"\"\377)))\377\204"
+ "+++\377\3***\377\77\77\77\331\225\225\225\214\202\377\377\377f\1\377"
+ "\377\377@\207\377\377\377\0\3\377\377\377Fyyy\240///\377\204000\377\3"
+ "...\377FFF\274\377\377\377\31\202\377\377\377\0\1\0\0\0\0\210\377\377"
+ "\377\0\2HHHwTTT\305\204\377\377\377f\3~~~\237)))\377\27\27\27\237\202"
+ "\377\377\377\0\1\0\0\0\0\323\377\377\377\0"};
+
+
diff --git a/src/session-get.c b/src/session-get.c
index a6e033b..5ae0db1 100644
--- a/src/session-get.c
+++ b/src/session-get.c
@@ -115,6 +115,11 @@ gboolean session_get_incomplete_dir_enabled(JsonObject * s)
return json_object_get_boolean_member(s, SGET_INCOMPLETE_DIR_ENABLED);
}
+gboolean session_get_alt_speed_enabled(JsonObject * s)
+{
+ return json_object_get_boolean_member(s, SGET_ALT_SPEED_ENABLED);
+}
+
gboolean session_get_seed_ratio_limited(JsonObject * s)
{
return json_object_get_boolean_member(s, SGET_SEED_RATIO_LIMITED);
diff --git a/src/session-get.h b/src/session-get.h
index ea1318e..df154a1 100644
--- a/src/session-get.h
+++ b/src/session-get.h
@@ -107,5 +107,6 @@ gint64 session_get_seed_queue_size(JsonObject * s);
gint64 session_get_rpc_version(JsonObject * s);
gint64 session_get_download_dir_free_space(JsonObject * s);
gboolean session_get_dht_enabled(JsonObject * s);
+gboolean session_get_alt_speed_enabled(JsonObject * s);
#endif /* SESSION_GET_H_ */
diff --git a/src/trg-icons.c b/src/trg-icons.c
new file mode 100644
index 0000000..4cd2bae
--- /dev/null
+++ b/src/trg-icons.c
@@ -0,0 +1,72 @@
+/*
+ * 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 <gtk/gtk.h>
+
+#include "icon-turtle.h"
+
+typedef struct
+{
+ const guint8* raw;
+ const char * name;
+}
+BuiltinIconInfo;
+
+static const BuiltinIconInfo my_fallback_icons[] =
+{
+ { blue_turtle, "alt-speed-on" },
+ { grey_turtle, "alt-speed-off" }
+};
+
+void
+register_my_icons( GtkIconTheme *theme )
+{
+ int i;
+ const int n = G_N_ELEMENTS( my_fallback_icons );
+ GtkIconFactory * factory = gtk_icon_factory_new( );
+
+ gtk_icon_factory_add_default( factory );
+
+ for( i = 0; i < n; ++i )
+ {
+ const char * name = my_fallback_icons[i].name;
+
+ if( !gtk_icon_theme_has_icon( theme, name ) )
+ {
+ int width;
+ GdkPixbuf * p;
+ GtkIconSet * icon_set;
+
+ p =
+ gdk_pixbuf_new_from_inline( -1, my_fallback_icons[i].raw,
+ FALSE,
+ NULL );
+ width = gdk_pixbuf_get_width( p );
+ icon_set = gtk_icon_set_new_from_pixbuf( p );
+ gtk_icon_theme_add_builtin_icon( name, width, p );
+ gtk_icon_factory_add( factory, name, icon_set );
+
+ g_object_unref( p );
+ gtk_icon_set_unref( icon_set );
+ }
+ }
+
+ g_object_unref ( G_OBJECT ( factory ) );
+}
+
diff --git a/src/trg-icons.h b/src/trg-icons.h
new file mode 100644
index 0000000..9b7a714
--- /dev/null
+++ b/src/trg-icons.h
@@ -0,0 +1,26 @@
+/*
+ * 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_ICONS_H_
+#define TRG_ICONS_H_
+
+void
+register_my_icons( GtkIconTheme *theme );
+
+#endif /* TRG_ICONS_H_ */
diff --git a/src/trg-main-window.c b/src/trg-main-window.c
index 6db4e19..2e45d52 100644
--- a/src/trg-main-window.c
+++ b/src/trg-main-window.c
@@ -52,6 +52,7 @@
#include "remote-exec.h"
#include "trg-main-window.h"
+#include "trg-icons.h"
#include "trg-about-window.h"
#include "trg-tree-view.h"
#include "trg-prefs.h"
@@ -2345,6 +2346,7 @@ static GObject *trg_main_window_constructor(GType type,
prefs = trg_client_get_prefs(priv->client);
theme = gtk_icon_theme_get_default();
+ register_my_icons(theme);
priv->icon = gtk_icon_theme_load_icon(theme, PACKAGE_NAME, 48,
GTK_ICON_LOOKUP_USE_BUILTIN,
NULL);
@@ -2458,7 +2460,7 @@ static GObject *trg_main_window_constructor(GType type,
else
trg_main_window_remove_status_icon(self);
- priv->statusBar = trg_status_bar_new();
+ priv->statusBar = trg_status_bar_new(self, priv->client);
g_signal_connect(priv->client, "session-updated",
G_CALLBACK(trg_client_session_updated_cb), self);
diff --git a/src/trg-status-bar.c b/src/trg-status-bar.c
index 4f1ed64..86ffb01 100644
--- a/src/trg-status-bar.c
+++ b/src/trg-status-bar.c
@@ -21,9 +21,12 @@
#include <glib/gprintf.h>
#include <gtk/gtk.h>
+#include "trg-main-window.h"
#include "trg-status-bar.h"
#include "trg-torrent-model.h"
#include "session-get.h"
+#include "requests.h"
+#include "json.h"
#include "util.h"
/* A subclass of GtkHBox which contains a status label on the left.
@@ -44,37 +47,64 @@ typedef struct _TrgStatusBarPrivate TrgStatusBarPrivate;
struct _TrgStatusBarPrivate {
GtkWidget *speed_lbl;
+ GtkWidget *turtleImage, *turtleEventBox;
GtkWidget *free_lbl;
GtkWidget *info_lbl;
+ TrgClient *client;
+ TrgMainWindow *win;
};
-static void trg_status_bar_class_init(TrgStatusBarClass * klass)
-{
+static void trg_status_bar_class_init(TrgStatusBarClass * klass) {
g_type_class_add_private(klass, sizeof(TrgStatusBarPrivate));
}
-void trg_status_bar_clear_indicators(TrgStatusBar * sb)
-{
+void trg_status_bar_clear_indicators(TrgStatusBar * sb) {
TrgStatusBarPrivate *priv = TRG_STATUS_BAR_GET_PRIVATE(sb);
gtk_label_set_text(GTK_LABEL(priv->free_lbl), "");
gtk_label_set_text(GTK_LABEL(priv->speed_lbl), "");
}
-void trg_status_bar_reset(TrgStatusBar * sb)
-{
+void trg_status_bar_reset(TrgStatusBar * sb) {
TrgStatusBarPrivate *priv = TRG_STATUS_BAR_GET_PRIVATE(sb);
trg_status_bar_clear_indicators(sb);
gtk_label_set_text(GTK_LABEL(priv->info_lbl), _("Disconnected"));
+ gtk_widget_set_visible(priv->turtleImage, FALSE);
}
-static void trg_status_bar_init(TrgStatusBar * self)
-{
+static void turtle_toggle(GtkWidget *w, GdkEventButton * event, gpointer data) {
+ TrgStatusBarPrivate *priv = TRG_STATUS_BAR_GET_PRIVATE(data);
+ JsonNode *req = session_set();
+ JsonObject *args = node_get_arguments(req);
+ gchar *stockName;
+ gboolean altSpeedOn;
+
+ gtk_image_get_stock(GTK_IMAGE(priv->turtleImage), &stockName, NULL);
+ altSpeedOn = g_strcmp0(stockName, "alt-speed-on") == 0;
+
+ gtk_image_set_from_stock(GTK_IMAGE(priv->turtleImage),
+ altSpeedOn ? "alt-speed-off" : "alt-speed-on",
+ GTK_ICON_SIZE_SMALL_TOOLBAR);
+ json_object_set_boolean_member(args, SGET_ALT_SPEED_ENABLED, !altSpeedOn);
+
+ dispatch_async(priv->client, req, on_session_set, priv->win);
+}
+
+static void trg_status_bar_init(TrgStatusBar * self) {
TrgStatusBarPrivate *priv = TRG_STATUS_BAR_GET_PRIVATE(self);
gtk_container_set_border_width(GTK_CONTAINER(self), 2);
priv->info_lbl = gtk_label_new(_("Disconnected"));
gtk_box_pack_start(GTK_BOX(self), priv->info_lbl, FALSE, TRUE, 0);
+ priv->turtleImage = gtk_image_new();
+
+ priv->turtleEventBox = gtk_event_box_new();
+ g_signal_connect(priv->turtleEventBox, "button-press-event",
+ G_CALLBACK(turtle_toggle), self);
+ gtk_widget_set_visible(priv->turtleEventBox, FALSE);
+ gtk_container_add(GTK_CONTAINER(priv->turtleEventBox), priv->turtleImage);
+ gtk_box_pack_end(GTK_BOX(self), priv->turtleEventBox, FALSE, TRUE, 5);
+
priv->speed_lbl = gtk_label_new(NULL);
gtk_box_pack_end(GTK_BOX(self), priv->speed_lbl, FALSE, TRUE, 10);
@@ -82,30 +112,25 @@ static void trg_status_bar_init(TrgStatusBar * self)
gtk_box_pack_end(GTK_BOX(self), priv->free_lbl, FALSE, TRUE, 30);
}
-void trg_status_bar_push_connection_msg(TrgStatusBar * sb,
- const gchar * msg)
-{
+void trg_status_bar_push_connection_msg(TrgStatusBar * sb, const gchar * msg) {
TrgStatusBarPrivate *priv = TRG_STATUS_BAR_GET_PRIVATE(sb);
-
gtk_label_set_text(GTK_LABEL(priv->info_lbl), msg);
}
-void trg_status_bar_connect(TrgStatusBar * sb, JsonObject * session)
-{
+void trg_status_bar_connect(TrgStatusBar * sb, JsonObject * session) {
gchar *statusMsg;
float version;
session_get_version(session, &version);
- statusMsg =
- g_strdup_printf
- (_("Connected to Transmission %g, getting torrents..."), version);
+ statusMsg = g_strdup_printf(
+ _("Connected to Transmission %g, getting torrents..."),
+ version);
g_message("%s", statusMsg);
trg_status_bar_push_connection_msg(sb, statusMsg);
g_free(statusMsg);
}
-void trg_status_bar_session_update(TrgStatusBar * sb, JsonObject * session)
-{
+void trg_status_bar_session_update(TrgStatusBar * sb, JsonObject * session) {
TrgStatusBarPrivate *priv = TRG_STATUS_BAR_GET_PRIVATE(sb);
gint64 free = session_get_download_dir_free_space(session);
gchar freeSpace[64];
@@ -119,12 +144,16 @@ void trg_status_bar_session_update(TrgStatusBar * sb, JsonObject * session)
} else {
gtk_label_set_text(GTK_LABEL(priv->free_lbl), "");
}
+
+ gtk_image_set_from_stock(
+ GTK_IMAGE(priv->turtleImage),
+ session_get_alt_speed_enabled(session) ? "alt-speed-on" :
+ "alt-speed-off", GTK_ICON_SIZE_SMALL_TOOLBAR);
+ gtk_widget_set_visible(priv->turtleEventBox, TRUE);
}
void trg_status_bar_update(TrgStatusBar * sb,
- trg_torrent_model_update_stats * stats,
- TrgClient * client)
-{
+ trg_torrent_model_update_stats * stats, TrgClient * client) {
TrgStatusBarPrivate *priv;
JsonObject *session;
gchar *speedText, *infoText;
@@ -137,45 +166,42 @@ void trg_status_bar_update(TrgStatusBar * sb,
// The session should always exist otherwise this function wouldn't be called
downlimitraw =
- json_object_get_boolean_member(session,
- SGET_SPEED_LIMIT_DOWN_ENABLED) ?
- json_object_get_int_member(session, SGET_SPEED_LIMIT_DOWN) : -1;
+ json_object_get_boolean_member(session,
+ SGET_SPEED_LIMIT_DOWN_ENABLED) ? json_object_get_int_member(
+ session, SGET_SPEED_LIMIT_DOWN) :
+ -1;
uplimitraw =
- json_object_get_boolean_member(session,
- SGET_SPEED_LIMIT_UP_ENABLED) ?
- json_object_get_int_member(session, SGET_SPEED_LIMIT_UP) : -1;
+ json_object_get_boolean_member(session,
+ SGET_SPEED_LIMIT_UP_ENABLED) ? json_object_get_int_member(
+ session, SGET_SPEED_LIMIT_UP) :
+ -1;
- trg_strlspeed(downRateTotalString,
- stats->downRateTotal / KILOBYTE_FACTOR);
+ trg_strlspeed(downRateTotalString, stats->downRateTotal / KILOBYTE_FACTOR);
trg_strlspeed(upRateTotalString, stats->upRateTotal / KILOBYTE_FACTOR);
if (uplimitraw >= 0) {
gchar uplimitstring[32];
trg_strlspeed(uplimitstring, uplimitraw);
- g_snprintf(uplimit, sizeof(uplimit), _(" (Limit: %s)"),
- uplimitstring);
+ g_snprintf(uplimit, sizeof(uplimit), _(" (Limit: %s)"), uplimitstring);
}
if (downlimitraw >= 0) {
gchar downlimitstring[32];
trg_strlspeed(downlimitstring, downlimitraw);
g_snprintf(downlimit, sizeof(downlimit), _(" (Limit: %s)"),
- downlimitstring);
+ downlimitstring);
}
- speedText =
- g_strdup_printf(_("Down: %s%s, Up: %s%s"), downRateTotalString,
- downlimitraw >= 0 ? downlimit : "",
- upRateTotalString, uplimitraw >= 0 ? uplimit : "");
+ speedText = g_strdup_printf(_("Down: %s%s, Up: %s%s"), downRateTotalString,
+ downlimitraw >= 0 ? downlimit : "", upRateTotalString,
+ uplimitraw >= 0 ? uplimit : "");
- infoText =
- g_strdup_printf
- (ngettext
- ("%d torrent: %d seeding, %d downloading, %d paused",
- "%d torrents: %d seeding, %d downloading, %d paused",
- stats->count), stats->count, stats->seeding, stats->down,
- stats->paused);
+ infoText = g_strdup_printf(ngettext
+ ("%d torrent: %d seeding, %d downloading, %d paused",
+ "%d torrents: %d seeding, %d downloading, %d paused",
+ stats->count), stats->count, stats->seeding, stats->down,
+ stats->paused);
gtk_label_set_text(GTK_LABEL(priv->info_lbl), infoText);
gtk_label_set_text(GTK_LABEL(priv->speed_lbl), speedText);
@@ -184,13 +210,15 @@ void trg_status_bar_update(TrgStatusBar * sb,
g_free(infoText);
}
-const gchar *trg_status_bar_get_speed_text(TrgStatusBar * s)
-{
+const gchar *trg_status_bar_get_speed_text(TrgStatusBar * s) {
TrgStatusBarPrivate *priv = TRG_STATUS_BAR_GET_PRIVATE(s);
return gtk_label_get_text(GTK_LABEL(priv->speed_lbl));
}
-TrgStatusBar *trg_status_bar_new()
-{
- return TRG_STATUS_BAR(g_object_new(TRG_TYPE_STATUS_BAR, NULL));
+TrgStatusBar *trg_status_bar_new(TrgMainWindow *win, TrgClient *client) {
+ TrgStatusBar *sb = g_object_new(TRG_TYPE_STATUS_BAR, NULL);
+ TrgStatusBarPrivate *priv = TRG_STATUS_BAR_GET_PRIVATE(sb);
+ priv->client = client;
+ priv->win = win;
+ return sb;
}