diff options
| author | Joel Klinghed <the_jk@yahoo.com> | 2011-11-12 11:34:07 +0100 |
|---|---|---|
| committer | Joel Klinghed <the_jk@yahoo.com> | 2011-11-12 11:34:07 +0100 |
| commit | 3411ddd3e6f9ee43e4eaa0c74935f1af8f36ee9d (patch) | |
| tree | 5c4b1e34b8f7268096282c6376baaef1f2b966f6 /src | |
Initial commit
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile | 28 | ||||
| -rw-r--r-- | src/common.h | 10 | ||||
| -rw-r--r-- | src/customcellrendererleft.c | 127 | ||||
| -rw-r--r-- | src/customcellrendererleft.h | 46 | ||||
| -rw-r--r-- | src/customcellrendererprogress.c | 139 | ||||
| -rw-r--r-- | src/customcellrendererprogress.h | 47 | ||||
| -rw-r--r-- | src/customcellrendererrate.c | 129 | ||||
| -rw-r--r-- | src/customcellrendererrate.h | 46 | ||||
| -rw-r--r-- | src/customcellrendererstate.c | 120 | ||||
| -rw-r--r-- | src/customcellrendererstate.h | 53 | ||||
| -rw-r--r-- | src/main.c | 166 |
11 files changed, 911 insertions, 0 deletions
diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..ab842f8 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,28 @@ +CC=gcc +CFLAGS=-Wall -Wextra -DDEBUG -DHAVE_CONFIG_H -g -I.. -DDATAROOTDIR='"/sw/share/"' +GTK_CFLAGS=`pkg-config gtk+-2.0 --cflags` +LDFLAGS= +GTK_LDFLAGS=`pkg-config gtk+-2.0 --libs` + +all: viewtorrents + +clean: + rm -f *.o viewtorrents + +viewtorrents: main.o customcellrendererstate.o customcellrendererprogress.o customcellrendererrate.o customcellrendererleft.o + $(CC) $(CFLAGS) $(GTK_CFLAGS) -o $@ $^ $(LDFLAGS) $(GTK_LDFLAGS) + +main.o: main.c customcellrendererstate.h customcellrendererprogress.h customcellrendererrate.h customcellrendererleft.h common.h + $(CC) -c $(CFLAGS) $(GTK_CFLAGS) -o $@ $< + +customcellrendererstate.o: customcellrendererstate.c customcellrendererstate.h common.h + $(CC) -c $(CFLAGS) $(GTK_CFLAGS) -o $@ $< + +customcellrendererprogress.o: customcellrendererprogress.c customcellrendererprogress.h common.h + $(CC) -c $(CFLAGS) $(GTK_CFLAGS) -o $@ $< + +customcellrendererrate.o: customcellrendererrate.c customcellrendererrate.h common.h + $(CC) -c $(CFLAGS) $(GTK_CFLAGS) -o $@ $< + +customcellrendererleft.o: customcellrendererleft.c customcellrendererleft.h common.h + $(CC) -c $(CFLAGS) $(GTK_CFLAGS) -o $@ $< diff --git a/src/common.h b/src/common.h new file mode 100644 index 0000000..b5819ac --- /dev/null +++ b/src/common.h @@ -0,0 +1,10 @@ +#ifndef COMMON_H +#define COMMON_H + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdlib.h> + +#endif /* COMMON_H */ diff --git a/src/customcellrendererleft.c b/src/customcellrendererleft.c new file mode 100644 index 0000000..89184e5 --- /dev/null +++ b/src/customcellrendererleft.c @@ -0,0 +1,127 @@ +#include "common.h" + +#include "customcellrendererleft.h" + +static void custom_cell_renderer_left_get_property(GObject* object, + guint param_id, + GValue* value, + GParamSpec* pspec); +static void custom_cell_renderer_left_set_property(GObject* object, + guint param_id, + const GValue* value, + GParamSpec* pspec); + +static void convert_left_to_string(gchar* str, guint size, gint64 left); + +enum { + PROP_0, + PROP_LEFT, +}; + +G_DEFINE_TYPE(CustomCellRendererLeft, custom_cell_renderer_left, GTK_TYPE_CELL_RENDERER_TEXT) + +static void custom_cell_renderer_left_init(CustomCellRendererLeft* cell_left) +{ + convert_left_to_string(cell_left->buffer, sizeof(cell_left->buffer), + cell_left->left); + g_object_set(cell_left, "text", cell_left->buffer, NULL); +} + +static void custom_cell_renderer_left_class_init(CustomCellRendererLeftClass *cell_left_class) +{ + GObjectClass *object_class; + /* GtkCellRendererClass *cell_renderer_class; */ + + object_class = G_OBJECT_CLASS(cell_left_class); + /* cell_renderer_class = GTK_CELL_RENDERER_CLASS(cell_left_class); */ + + object_class->set_property = custom_cell_renderer_left_set_property; + object_class->get_property = custom_cell_renderer_left_get_property; + + g_object_class_install_property(object_class, + PROP_LEFT, + g_param_spec_int64("left", + "Time left", + "The time left for the transfer in seconds or -1 if unknown", + -1, + G_MAXINT64, + 0, + G_PARAM_READABLE | G_PARAM_WRITABLE)); +} + +GtkCellRenderer* custom_cell_renderer_left_new(void) +{ + return g_object_new(CUSTOM_TYPE_CELL_RENDERER_LEFT, NULL); +} + +void custom_cell_renderer_left_get_property(GObject* object, + guint param_id, + GValue* value, + GParamSpec* pspec) +{ + CustomCellRendererLeft* left = CUSTOM_CELL_RENDERER_LEFT(object); + + switch (param_id) + { + case PROP_LEFT: + g_value_set_int64(value, left->left); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); + } +} + +void custom_cell_renderer_left_set_property(GObject* object, + guint param_id, + const GValue* value, + GParamSpec* pspec) +{ + CustomCellRendererLeft* left = CUSTOM_CELL_RENDERER_LEFT(object); + gboolean changed = FALSE; + + switch (param_id) + { + case PROP_LEFT: + { + gint64 left_value = g_value_get_int64(value); + + if (left->left != left_value) + { + left->left = left_value; + changed = TRUE; + } + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); + } + + if (changed) + { + convert_left_to_string(left->buffer, sizeof(left->buffer), left->left); + g_object_set(left, "text", left->buffer, NULL); + } +} + +void convert_left_to_string(gchar* str, guint size, gint64 left) +{ + if (left < 0) + { + *str = '\0'; + } + else if (left < 60) + { + g_snprintf(str, size, "%02" G_GINT64_FORMAT "s", left); + } + else if (left < 60 * 60) + { + g_snprintf(str, size, "%02" G_GINT64_FORMAT "m%02" G_GINT64_FORMAT "s", + left / 60, left % 60); + } + else + { + left /= 60; + g_snprintf(str, size, "%" G_GINT64_FORMAT "h%02" G_GINT64_FORMAT "m", + left / 60, left % 60); + } +} diff --git a/src/customcellrendererleft.h b/src/customcellrendererleft.h new file mode 100644 index 0000000..6e18ebd --- /dev/null +++ b/src/customcellrendererleft.h @@ -0,0 +1,46 @@ +#ifndef CUSTOMCELLRENDERERLEFT_H +#define CUSTOMCELLRENDERERLEFT_H + +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +#define CUSTOM_TYPE_CELL_RENDERER_LEFT \ + (custom_cell_renderer_left_get_type()) +#define CUSTOM_CELL_RENDERER_LEFT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), CUSTOM_TYPE_CELL_RENDERER_LEFT, \ + CustomCellRendererLeft)) +#define CUSTOM_CELL_RENDERER_LEFT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), CUSTOM_TYPE_CELL_RENDERER_LEFT, \ + CustomCellRendererLeftClass)) +#define CUSTOM_IS_CELL_RENDERER_LEFT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), CUSTOM_TYPE_CELL_RENDERER_LEFT)) +#define CUSTOM_IS_CELL_RENDERER_LEFT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), CUSTOM_TYPE_CELL_RENDERER_LEFT)) +#define CUSTOM_CELL_RENDERER_LEFT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), CUSTOM_TYPE_CELL_RENDERER_LEFT, \ + CustomCellRendererLeftClass)) + +typedef struct _CustomCellRendererLeft CustomCellRendererLeft; +typedef struct _CustomCellRendererLeftClass CustomCellRendererLeftClass; + +struct _CustomCellRendererLeft +{ + GtkCellRendererText parent; + + /*< private >*/ + gint64 GSEAL (left); + gchar GSEAL (buffer[20]); +}; + +struct _CustomCellRendererLeftClass +{ + GtkCellRendererTextClass parent_class; +}; + +GType custom_cell_renderer_left_get_type(void) G_GNUC_CONST; +GtkCellRenderer* custom_cell_renderer_left_new(void); + +G_END_DECLS + +#endif /* CUSTOMCELLRENDERERLEFT_H */ diff --git a/src/customcellrendererprogress.c b/src/customcellrendererprogress.c new file mode 100644 index 0000000..04912e7 --- /dev/null +++ b/src/customcellrendererprogress.c @@ -0,0 +1,139 @@ +#include "common.h" + +#include "customcellrendererprogress.h" + +static void custom_cell_renderer_progress_get_property(GObject* object, + guint param_id, + GValue* value, + GParamSpec* pspec); +static void custom_cell_renderer_progress_set_property(GObject* object, + guint param_id, + const GValue* value, + GParamSpec* pspec); + +static void update_progress(CustomCellRendererProgress* cell_progress, + gfloat downloaded, gfloat seeded); + +enum { + PROP_0, + PROP_DOWNLOADED, + PROP_SEEDED, +}; + +G_DEFINE_TYPE(CustomCellRendererProgress, custom_cell_renderer_progress, GTK_TYPE_CELL_RENDERER_PROGRESS) + +static void custom_cell_renderer_progress_init(CustomCellRendererProgress* cell_progress) +{ + update_progress(cell_progress, + cell_progress->downloaded, cell_progress->seeded); +} + +static void custom_cell_renderer_progress_class_init(CustomCellRendererProgressClass *cell_progress_class) +{ + GObjectClass *object_class; + /* GtkCellRendererClass *cell_renderer_class; */ + + object_class = G_OBJECT_CLASS(cell_progress_class); + /* cell_renderer_class = GTK_CELL_RENDERER_CLASS(cell_progress_class); */ + + object_class->set_property = custom_cell_renderer_progress_set_property; + object_class->get_property = custom_cell_renderer_progress_get_property; + + g_object_class_install_property(object_class, + PROP_DOWNLOADED, + g_param_spec_float("downloaded", + "Percent downloaded", + "Percent of torrent that has been downloaded", + 0.0, + 100.0, + 0, + G_PARAM_READABLE | G_PARAM_WRITABLE)); + + g_object_class_install_property(object_class, + PROP_SEEDED, + g_param_spec_float("seeded", + "Seeded ratio", + "Seeded ratio", + 0.0, + G_MAXFLOAT, + 0, + G_PARAM_READABLE | G_PARAM_WRITABLE)); +} + +GtkCellRenderer* custom_cell_renderer_progress_new(void) +{ + return g_object_new(CUSTOM_TYPE_CELL_RENDERER_PROGRESS, NULL); +} + +void custom_cell_renderer_progress_get_property(GObject* object, + guint param_id, + GValue* value, + GParamSpec* pspec) +{ + CustomCellRendererProgress* progress = CUSTOM_CELL_RENDERER_PROGRESS(object); + + switch (param_id) + { + case PROP_DOWNLOADED: + g_value_set_float(value, progress->downloaded); + break; + case PROP_SEEDED: + g_value_set_float(value, progress->seeded); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); + } +} + +void custom_cell_renderer_progress_set_property(GObject* object, + guint param_id, + const GValue* value, + GParamSpec* pspec) +{ + CustomCellRendererProgress* progress = CUSTOM_CELL_RENDERER_PROGRESS(object); + gboolean changed = FALSE; + + switch (param_id) + { + case PROP_DOWNLOADED: + { + gfloat downloaded = g_value_get_float(value); + + if (progress->downloaded != downloaded) + { + progress->downloaded = downloaded; + changed = TRUE; + } + break; + } + case PROP_SEEDED: + { + gfloat seeded = g_value_get_float(value); + + if (progress->seeded != seeded) + { + progress->seeded = seeded; + changed = TRUE; + } + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); + } + + if (changed) + { + update_progress(progress, progress->downloaded, progress->seeded); + } +} + +void update_progress(CustomCellRendererProgress* cell_progress, + gfloat downloaded, gfloat seeded) +{ + g_snprintf(cell_progress->buffer, sizeof(cell_progress->buffer), + "%2.2f", seeded); + g_object_set(cell_progress, + "value", (gint)downloaded, + "text", cell_progress->buffer, + NULL); +} diff --git a/src/customcellrendererprogress.h b/src/customcellrendererprogress.h new file mode 100644 index 0000000..7e3a7ba --- /dev/null +++ b/src/customcellrendererprogress.h @@ -0,0 +1,47 @@ +#ifndef CUSTOMCELLRENDERERPROGRESS_H +#define CUSTOMCELLRENDERERPROGRESS_H + +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +#define CUSTOM_TYPE_CELL_RENDERER_PROGRESS \ + (custom_cell_renderer_progress_get_type()) +#define CUSTOM_CELL_RENDERER_PROGRESS(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), CUSTOM_TYPE_CELL_RENDERER_PROGRESS, \ + CustomCellRendererProgress)) +#define CUSTOM_CELL_RENDERER_PROGRESS_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), CUSTOM_TYPE_CELL_RENDERER_PROGRESS, \ + CustomCellRendererProgressClass)) +#define CUSTOM_IS_CELL_RENDERER_PROGRESS(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), CUSTOM_TYPE_CELL_RENDERER_PROGRESS)) +#define CUSTOM_IS_CELL_RENDERER_PROGRESS_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), CUSTOM_TYPE_CELL_RENDERER_PROGRESS)) +#define CUSTOM_CELL_RENDERER_PROGRESS_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), CUSTOM_TYPE_CELL_RENDERER_PROGRESS, \ + CustomCellRendererProgressClass)) + +typedef struct _CustomCellRendererProgress CustomCellRendererProgress; +typedef struct _CustomCellRendererProgressClass CustomCellRendererProgressClass; + +struct _CustomCellRendererProgress +{ + GtkCellRendererProgress parent; + + /*< private >*/ + gfloat GSEAL (downloaded); + gfloat GSEAL (seeded); + gchar GSEAL (buffer[10]); +}; + +struct _CustomCellRendererProgressClass +{ + GtkCellRendererProgressClass parent_class; +}; + +GType custom_cell_renderer_progress_get_type(void) G_GNUC_CONST; +GtkCellRenderer* custom_cell_renderer_progress_new(void); + +G_END_DECLS + +#endif /* CUSTOMCELLRENDERERPROGRESS_H */ diff --git a/src/customcellrendererrate.c b/src/customcellrendererrate.c new file mode 100644 index 0000000..4b7b9bf --- /dev/null +++ b/src/customcellrendererrate.c @@ -0,0 +1,129 @@ +#include "common.h" + +#include "customcellrendererrate.h" + +static void custom_cell_renderer_rate_get_property(GObject* object, + guint param_id, + GValue* value, + GParamSpec* pspec); +static void custom_cell_renderer_rate_set_property(GObject* object, + guint param_id, + const GValue* value, + GParamSpec* pspec); + +static void convert_rate_to_string(gchar* str, guint size, gfloat rate); + +enum { + PROP_0, + PROP_RATE, +}; + +G_DEFINE_TYPE(CustomCellRendererRate, custom_cell_renderer_rate, GTK_TYPE_CELL_RENDERER_TEXT) + +static void custom_cell_renderer_rate_init(CustomCellRendererRate* cell_rate) +{ + convert_rate_to_string(cell_rate->buffer, sizeof(cell_rate->buffer), + cell_rate->rate); + g_object_set(cell_rate, "text", cell_rate->buffer, NULL); +} + +static void custom_cell_renderer_rate_class_init(CustomCellRendererRateClass *cell_rate_class) +{ + GObjectClass *object_class; + /* GtkCellRendererClass *cell_renderer_class; */ + + object_class = G_OBJECT_CLASS(cell_rate_class); + /* cell_renderer_class = GTK_CELL_RENDERER_CLASS(cell_rate_class); */ + + object_class->set_property = custom_cell_renderer_rate_set_property; + object_class->get_property = custom_cell_renderer_rate_get_property; + + g_object_class_install_property(object_class, + PROP_RATE, + g_param_spec_float("rate", + "Rate", + "The transfer rate in kilo (1000) byte per second", + 0.0, + G_MAXFLOAT, + 0, + G_PARAM_READABLE | G_PARAM_WRITABLE)); +} + +GtkCellRenderer* custom_cell_renderer_rate_new(void) +{ + return g_object_new(CUSTOM_TYPE_CELL_RENDERER_RATE, NULL); +} + +void custom_cell_renderer_rate_get_property(GObject* object, + guint param_id, + GValue* value, + GParamSpec* pspec) +{ + CustomCellRendererRate* rate = CUSTOM_CELL_RENDERER_RATE(object); + + switch (param_id) + { + case PROP_RATE: + g_value_set_float(value, rate->rate); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); + } +} + +void custom_cell_renderer_rate_set_property(GObject* object, + guint param_id, + const GValue* value, + GParamSpec* pspec) +{ + CustomCellRendererRate* rate = CUSTOM_CELL_RENDERER_RATE(object); + gboolean changed = FALSE; + + switch (param_id) + { + case PROP_RATE: + { + gfloat rate_value = g_value_get_float(value); + + if (rate->rate != rate_value) + { + rate->rate = rate_value; + changed = TRUE; + } + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); + } + + if (changed) + { + convert_rate_to_string(rate->buffer, sizeof(rate->buffer), rate->rate); + g_object_set(rate, "text", rate->buffer, NULL); + } +} + +void convert_rate_to_string(gchar* str, guint size, gfloat rate) +{ + if (rate <= 0.0f) + { + g_assert(size >= 1); + *str = '\0'; + } + else if (rate < 0.9f) + { + g_snprintf(str, size, "%3fB", rate * 1000.0f); + } + else if (rate <= 900.0f) + { + g_snprintf(str, size, "%3.2fkB", rate); + } + else if (rate <= 900000.0f) + { + g_snprintf(str, size, "%3.2fMB", rate / 1000.0f); + } + else + { + g_snprintf(str, size, "%3.2fGB", rate / 1000000.0f); + } +} diff --git a/src/customcellrendererrate.h b/src/customcellrendererrate.h new file mode 100644 index 0000000..48105d3 --- /dev/null +++ b/src/customcellrendererrate.h @@ -0,0 +1,46 @@ +#ifndef CUSTOMCELLRENDERERRATE_H +#define CUSTOMCELLRENDERERRATE_H + +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +#define CUSTOM_TYPE_CELL_RENDERER_RATE \ + (custom_cell_renderer_rate_get_type()) +#define CUSTOM_CELL_RENDERER_RATE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), CUSTOM_TYPE_CELL_RENDERER_RATE, \ + CustomCellRendererRate)) +#define CUSTOM_CELL_RENDERER_RATE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), CUSTOM_TYPE_CELL_RENDERER_RATE, \ + CustomCellRendererRateClass)) +#define CUSTOM_IS_CELL_RENDERER_RATE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), CUSTOM_TYPE_CELL_RENDERER_RATE)) +#define CUSTOM_IS_CELL_RENDERER_RATE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), CUSTOM_TYPE_CELL_RENDERER_RATE)) +#define CUSTOM_CELL_RENDERER_RATE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), CUSTOM_TYPE_CELL_RENDERER_RATE, \ + CustomCellRendererRateClass)) + +typedef struct _CustomCellRendererRate CustomCellRendererRate; +typedef struct _CustomCellRendererRateClass CustomCellRendererRateClass; + +struct _CustomCellRendererRate +{ + GtkCellRendererText parent; + + /*< private >*/ + gfloat GSEAL (rate); + gchar GSEAL (buffer[10]); +}; + +struct _CustomCellRendererRateClass +{ + GtkCellRendererTextClass parent_class; +}; + +GType custom_cell_renderer_rate_get_type(void) G_GNUC_CONST; +GtkCellRenderer* custom_cell_renderer_rate_new(void); + +G_END_DECLS + +#endif /* CUSTOMCELLRENDERERRATE_H */ diff --git a/src/customcellrendererstate.c b/src/customcellrendererstate.c new file mode 100644 index 0000000..1f0a7f8 --- /dev/null +++ b/src/customcellrendererstate.c @@ -0,0 +1,120 @@ +#include "common.h" + +#include "customcellrendererstate.h" + +static void custom_cell_renderer_state_get_property(GObject* object, + guint param_id, + GValue* value, + GParamSpec* pspec); +static void custom_cell_renderer_state_set_property(GObject* object, + guint param_id, + const GValue* value, + GParamSpec* pspec); + +static void update_state(CustomCellRendererState* cell_state, gint state); + +enum { + PROP_0, + PROP_STATE, +}; + +G_DEFINE_TYPE(CustomCellRendererState, custom_cell_renderer_state, GTK_TYPE_CELL_RENDERER_PIXBUF) + +static void custom_cell_renderer_state_init(CustomCellRendererState* cell_state) +{ + update_state(cell_state, cell_state->state); +} + +static void custom_cell_renderer_state_class_init(CustomCellRendererStateClass *cell_state_class) +{ + GObjectClass *object_class; + /* GtkCellRendererClass *cell_renderer_class; */ + + object_class = G_OBJECT_CLASS(cell_state_class); + /* cell_renderer_class = GTK_CELL_RENDERER_CLASS(cell_state_class); */ + + object_class->set_property = custom_cell_renderer_state_set_property; + object_class->get_property = custom_cell_renderer_state_get_property; + + g_object_class_install_property(object_class, + PROP_STATE, + g_param_spec_int("state", + "Torrent state", + "Torrent state", + STATE_DEAD, + STATE_REHASH, + 0, + G_PARAM_READABLE | G_PARAM_WRITABLE)); +} + +GtkCellRenderer* custom_cell_renderer_state_new(void) +{ + return g_object_new(CUSTOM_TYPE_CELL_RENDERER_STATE, NULL); +} + +void custom_cell_renderer_state_get_property(GObject* object, + guint param_id, + GValue* value, + GParamSpec* pspec) +{ + CustomCellRendererState* state = CUSTOM_CELL_RENDERER_STATE(object); + + switch (param_id) + { + case PROP_STATE: + g_value_set_int(value, state->state); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); + } +} + +void custom_cell_renderer_state_set_property(GObject* object, + guint param_id, + const GValue* value, + GParamSpec* pspec) +{ + CustomCellRendererState* state = CUSTOM_CELL_RENDERER_STATE(object); + gboolean changed = FALSE; + + switch (param_id) + { + case PROP_STATE: + { + gint state_value = g_value_get_int(value); + + if (state->state != state_value) + { + state->state = state_value; + changed = TRUE; + } + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); + } + + if (changed) + { + update_state(state, state->state); + } +} + +void update_state(CustomCellRendererState* cell_state, gint state) +{ + switch ((state_t)state) + { + case STATE_DEAD: + g_object_set(cell_state, "stock-id", GTK_STOCK_CLOSE, NULL); + break; + case STATE_ACTIVE: + g_object_set(cell_state, "stock-id", GTK_STOCK_YES, NULL); + break; + case STATE_REHASH: + g_object_set(cell_state, "stock-id", GTK_STOCK_REFRESH, NULL); + break; + default: + g_assert(FALSE); + break; + } +} diff --git a/src/customcellrendererstate.h b/src/customcellrendererstate.h new file mode 100644 index 0000000..3ad16e2 --- /dev/null +++ b/src/customcellrendererstate.h @@ -0,0 +1,53 @@ +#ifndef CUSTOMCELLRENDERERSTATE_H +#define CUSTOMCELLRENDERERSTATE_H + +#include <gtk/gtk.h> + +typedef enum +{ + STATE_DEAD, /* Not active (downloaded >= 100.0 ? closed : paused) */ + STATE_ACTIVE, /* Active (downloaded >= 100.0 ? seeding : downloading) */ + STATE_REHASH, /* Hashing */ +} state_t; + +G_BEGIN_DECLS + +#define CUSTOM_TYPE_CELL_RENDERER_STATE \ + (custom_cell_renderer_state_get_type()) +#define CUSTOM_CELL_RENDERER_STATE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), CUSTOM_TYPE_CELL_RENDERER_STATE, \ + CustomCellRendererState)) +#define CUSTOM_CELL_RENDERER_STATE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), CUSTOM_TYPE_CELL_RENDERER_STATE, \ + CustomCellRendererStateClass)) +#define CUSTOM_IS_CELL_RENDERER_STATE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), CUSTOM_TYPE_CELL_RENDERER_STATE)) +#define CUSTOM_IS_CELL_RENDERER_STATE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), CUSTOM_TYPE_CELL_RENDERER_STATE)) +#define CUSTOM_CELL_RENDERER_STATE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), CUSTOM_TYPE_CELL_RENDERER_STATE, \ + CustomCellRendererStateClass)) + +typedef struct _CustomCellRendererState CustomCellRendererState; +typedef struct _CustomCellRendererStateClass CustomCellRendererStateClass; + +struct _CustomCellRendererState +{ + GtkCellRendererPixbuf parent; + + /*< private >*/ + gint GSEAL (state); + GdkPixbuf* GSEAL (buffer[3]); +}; + +struct _CustomCellRendererStateClass +{ + GtkCellRendererPixbufClass parent_class; +}; + +GType custom_cell_renderer_state_get_type(void) G_GNUC_CONST; +GtkCellRenderer* custom_cell_renderer_state_new(void); + +G_END_DECLS + +#endif /* CUSTOMCELLRENDERERSTATE_H */ diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..3dd9704 --- /dev/null +++ b/src/main.c @@ -0,0 +1,166 @@ +#include "common.h" + +#include <gtk/gtk.h> +#include "customcellrendererstate.h" +#include "customcellrendererprogress.h" +#include "customcellrendererrate.h" +#include "customcellrendererleft.h" +#include <string.h> + +typedef enum +{ + COLUMN_STATE, + COLUMN_TITLE, + COLUMN_DOWNLOADED, + COLUMN_SEEDED, + COLUMN_UP, + COLUMN_DOWN, + COLUMN_LEFT, + COLUMN_PROGRESSSORT, +} column_t; + +typedef struct +{ + state_t state; + gchar* title; + gfloat downloaded; /* percent */ + gfloat seeded; /* ratio */ + gfloat down, up; /* kilo (1000) byte per second */ + guint64 size; /* bytes */ + gint64 left; /* seconds left until done, < 0 means unknown */ +} torrent_t; + +static void torrent_update(torrent_t* torrent, + GtkListStore* store, GtkTreeIter* iter); + +int main(int argc, char** argv) +{ + const gchar* gladefile; + GtkBuilder* builder; + GError* error = NULL; + guint ret; + GtkWidget* top; + GtkWidget* listview; + GtkListStore* liststore; + GtkTreeIter iter; + GtkCellRenderer* cell; + GtkTreeViewColumn* column; + + g_thread_init(NULL); + + gtk_init(&argc, &argv); + + builder = gtk_builder_new(); + gladefile = DATAROOTDIR "viewtorrents/viewtorrents.glade"; + ret = gtk_builder_add_from_file(builder, gladefile, &error); +#ifdef DEBUG + if (ret == 0) + { + g_clear_error(&error); + gladefile = "gui/viewtorrents.glade"; + ret = gtk_builder_add_from_file(builder, gladefile, &error); + } +#endif + if (ret == 0) + { + fprintf(stderr, "Unable to load %s: %s\n", gladefile, error->message); + g_clear_error(&error); + return EXIT_FAILURE; + } + + top = GTK_WIDGET(gtk_builder_get_object(builder, "main")); + + g_signal_connect(top, "delete-event", G_CALLBACK(gtk_main_quit), NULL); + g_signal_connect(gtk_builder_get_object(builder, "quitmenuitem"), + "activate", G_CALLBACK(gtk_main_quit), NULL); + + listview = GTK_WIDGET(gtk_builder_get_object(builder, "treeview")); + liststore = GTK_LIST_STORE(gtk_builder_get_object(builder, "liststore")); + + cell = custom_cell_renderer_state_new(); + column = GTK_TREE_VIEW_COLUMN(gtk_builder_get_object(builder, "statecolumn")); + gtk_tree_view_column_pack_start(column, cell, TRUE); + gtk_tree_view_column_add_attribute(column, cell, "state", COLUMN_STATE); + + cell = custom_cell_renderer_progress_new(); + column = GTK_TREE_VIEW_COLUMN(gtk_builder_get_object(builder, "progresscolumn")); + gtk_tree_view_column_pack_start(column, cell, TRUE); + gtk_tree_view_column_add_attribute(column, cell, "downloaded", COLUMN_DOWNLOADED); + gtk_tree_view_column_add_attribute(column, cell, "seeded", COLUMN_SEEDED); + + cell = custom_cell_renderer_rate_new(); + column = GTK_TREE_VIEW_COLUMN(gtk_builder_get_object(builder, "upcolumn")); + gtk_tree_view_column_pack_start(column, cell, TRUE); + gtk_tree_view_column_add_attribute(column, cell, "rate", COLUMN_UP); + + column = GTK_TREE_VIEW_COLUMN(gtk_builder_get_object(builder, "downcolumn")); + gtk_tree_view_column_pack_start(column, cell, TRUE); + gtk_tree_view_column_add_attribute(column, cell, "rate", COLUMN_DOWN); + + cell = custom_cell_renderer_left_new(); + column = GTK_TREE_VIEW_COLUMN(gtk_builder_get_object(builder, "leftcolumn")); + gtk_tree_view_column_pack_start(column, cell, TRUE); + gtk_tree_view_column_add_attribute(column, cell, "left", COLUMN_LEFT); + + { + torrent_t torrent; + torrent.state = STATE_DEAD; + torrent.title = "The.Tree.of.Life.2011.720p.BluRay.x264.DTS-HDxT"; + torrent.seeded = 3.0; + torrent.downloaded = 100.0; + torrent.up = 0.0; + torrent.down = 0.0; + torrent.left = -1; + + gtk_list_store_append(liststore, &iter); + torrent_update(&torrent, liststore, &iter); + } + { + torrent_t torrent; + torrent.state = STATE_ACTIVE; + torrent.title = "Burn.Notice.S05E14.720p.HDTV.x264-AVS.mkv"; + torrent.seeded = 2.79; + torrent.downloaded = 100.0; + torrent.up = 72.5; + torrent.down = 0.0; + torrent.left = -1; + + gtk_list_store_append(liststore, &iter); + torrent_update(&torrent, liststore, &iter); + } + { + torrent_t torrent; + torrent.state = STATE_ACTIVE; + torrent.title = "CSI.S12E07.720p.HDTV.X264-DIMENSION.mkv"; + torrent.seeded = 1.5; + torrent.downloaded = 73.45; + torrent.up = 37.3; + torrent.down = 994.8; + torrent.left = 24340; + + gtk_list_store_append(liststore, &iter); + torrent_update(&torrent, liststore, &iter); + } + + gtk_widget_show_all(top); + + gtk_main(); + + return EXIT_SUCCESS; +} + +void torrent_update(torrent_t* torrent, GtkListStore* store, GtkTreeIter* iter) +{ + gtk_list_store_set(store, iter, + COLUMN_STATE, torrent->state, + COLUMN_TITLE, torrent->title, + COLUMN_DOWNLOADED, torrent->downloaded, + COLUMN_SEEDED, torrent->seeded, + COLUMN_UP, torrent->up, + COLUMN_DOWN, torrent->down, + COLUMN_LEFT, torrent->left, + COLUMN_PROGRESSSORT, + torrent->downloaded < 100.0f ? torrent->downloaded : + torrent->seeded + 1000.0f, + -1); +} |
