summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/.gitignore1
-rw-r--r--src/Makefile30
-rw-r--r--src/Makefile.am17
-rw-r--r--src/main.c155
4 files changed, 160 insertions, 43 deletions
diff --git a/src/.gitignore b/src/.gitignore
index c1753e9..0e69789 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -1,2 +1 @@
/viewtorrents
-*.o \ No newline at end of file
diff --git a/src/Makefile b/src/Makefile
deleted file mode 100644
index 022a873..0000000
--- a/src/Makefile
+++ /dev/null
@@ -1,30 +0,0 @@
-CC=gcc
-CFLAGS=-Wall -Wextra -DDEBUG -DHAVE_CONFIG_H -g -I.. -DDATAROOTDIR='"/sw/share/"'
-GTK_CFLAGS=`pkg-config gtk+-2.0 --cflags`
-XMLRPC_CFLAGS=`xmlrpc-c-config client --cflags`
-LDFLAGS=
-GTK_LIBS=`pkg-config gtk+-2.0 --libs`
-XMLRPC_LIBS=`xmlrpc-c-config client --libs`
-
-all: viewtorrents
-
-clean:
- rm -f *.o viewtorrents
-
-viewtorrents: main.o customcellrendererstate.o customcellrendererprogress.o customcellrendererrate.o customcellrendererleft.o
- $(CC) $(CFLAGS) $(GTK_CFLAGS) $(XMLRPC_CFLAGS) -o $@ $^ $(LDFLAGS) $(GTK_LIBS) $(XMLRPC_LIBS)
-
-main.o: main.c customcellrendererstate.h customcellrendererprogress.h customcellrendererrate.h customcellrendererleft.h common.h
- $(CC) -c $(CFLAGS) $(GTK_CFLAGS) $(XMLRPC_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/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..e555a0b
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,17 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+INCLUDES = -I$(top_srcdir)
+
+AM_CFLAGS = @DEFINES@ @GTK_CFLAGS@ @XMLRPC_C_CFLAGS@ -DDATAROOTDIR='"${pkgdatadir}"'
+
+bin_PROGRAMS = viewtorrents
+
+viewtorrents_SOURCES = main.c common.h \
+ customcellrendererstate.c customcellrendererstate.h \
+ customcellrendererprogress.c \
+ customcellrendererprogress.h \
+ customcellrendererrate.c customcellrendererrate.h \
+ customcellrendererleft.c customcellrendererleft.h
+
+viewtorrents_LDADD = @GTK_LIBS@ @XMLRPC_C_LIBS@
+
diff --git a/src/main.c b/src/main.c
index b51f1db..78c98da 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,10 +1,12 @@
#include "common.h"
#include <gtk/gtk.h>
+#include <glib.h>
#include <xmlrpc-c/base.h>
#include <xmlrpc-c/client.h>
#include <string.h>
#include <errno.h>
+#include <math.h>
#include "customcellrendererstate.h"
#include "customcellrendererprogress.h"
@@ -226,13 +228,20 @@ static void status(master_t* master, const char* format, ...);
static void noop_destroy(gpointer value);
static void torrent_destroy(gpointer value);
+static void liststore_sort_column_changed(GtkTreeSortable* sortable,
+ gpointer user_data);
+static gint liststore_default_compare_func(GtkTreeModel* model,
+ GtkTreeIter* a,
+ GtkTreeIter* b,
+ gpointer user_data);
+
int main(int argc, char** argv)
{
const gchar* gladefile;
GtkBuilder* builder;
GError* error = NULL;
guint ret;
- GtkWidget* listview, * pwddlg;
+ GtkWidget* pwddlg;
GtkCellRenderer* cell;
GtkTreeViewColumn* column;
GThread* worker;
@@ -294,10 +303,15 @@ int main(int argc, char** argv)
gtk_widget_set_sensitive(master.disconnectmenuitem, FALSE);
pwddlg = GTK_WIDGET(gtk_builder_get_object(builder, "pwddlg"));
+ gtk_dialog_set_default_response(GTK_DIALOG(pwddlg), GTK_RESPONSE_OK);
- listview = GTK_WIDGET(gtk_builder_get_object(builder, "treeview"));
master.liststore = GTK_LIST_STORE(gtk_builder_get_object(builder,
"liststore"));
+ g_signal_connect(master.liststore, "sort-column-changed",
+ G_CALLBACK(liststore_sort_column_changed), &master);
+ gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(master.liststore),
+ liststore_default_compare_func,
+ &master, NULL);
cell = custom_cell_renderer_state_new();
column = GTK_TREE_VIEW_COLUMN(gtk_builder_get_object(builder, "statecolumn"));
@@ -335,9 +349,30 @@ int main(int argc, char** argv)
G_KEY_FILE_KEEP_TRANSLATIONS,
NULL);
+ {
+ gint column =
+ g_key_file_get_integer(master.config, "view", "sort_column", NULL);
+ gboolean desc =
+ g_key_file_get_boolean(master.config, "view", "sort_desc", NULL);
+ if (column > 0)
+ {
+ gtk_tree_sortable_set_sort_column_id(
+ GTK_TREE_SORTABLE(master.liststore), column,
+ desc ? GTK_SORT_DESCENDING : GTK_SORT_ASCENDING);
+ }
+ else
+ {
+ gtk_tree_sortable_set_sort_column_id(
+ GTK_TREE_SORTABLE(master.liststore),
+ GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
+ }
+ }
+
gtk_widget_show_all(master.top);
master.connectdlg = GTK_WIDGET(gtk_builder_get_object(builder, "connectdlg"));
+ gtk_dialog_set_default_response(GTK_DIALOG(master.connectdlg),
+ GTK_RESPONSE_OK);
master.connectdlg_url = GTK_WIDGET(gtk_builder_get_object(builder, "connectdlg_url"));
master.connectdlg_user = GTK_WIDGET(gtk_builder_get_object(builder, "connectdlg_user"));
master.connectdlg_pwd = GTK_WIDGET(gtk_builder_get_object(builder, "connectdlg_pwd"));
@@ -646,7 +681,7 @@ void do_connect(GtkMenuItem* menuitem, gpointer data)
pass = NULL;
}
- gtk_widget_set_sensitive(master->connectmenuitem, FALSE);
+ gtk_widget_set_sensitive(GTK_WIDGET(menuitem), FALSE);
status(master, "Connecting to %s...", url);
g_key_file_set_string(master->config, "connect", "url", url);
if (user != NULL)
@@ -677,7 +712,7 @@ void do_disconnect(GtkMenuItem* menuitem, gpointer data)
g_source_remove(master->sync_timeout);
master->sync_timeout = 0;
}
- gtk_widget_set_sensitive(master->disconnectmenuitem, FALSE);
+ gtk_widget_set_sensitive(GTK_WIDGET(menuitem), FALSE);
status(master, "Disconnecting...");
g_hash_table_remove_all(master->torrents);
g_async_queue_push(master->queue, msg_disconnect());
@@ -718,7 +753,7 @@ void torrent_update(torrent_t* torrent, torrent_data_t* data)
COLUMN_LEFT, data->left,
COLUMN_PROGRESSSORT,
data->downloaded < 100.0f ? data->downloaded :
- data->seeded + 1000.0f,
+ 1000.0f + data->seeded,
-1);
}
@@ -1008,14 +1043,14 @@ gpointer worker_main(gpointer _data)
break;
}
done = (guint64)tmpi64;
- if (torrent_data.size > 0)
+ if (done >= torrent_data.size)
+ {
+ torrent_data.downloaded = 100.0f;
+ }
+ else if (torrent_data.size > 0)
{
torrent_data.downloaded = ((gfloat)done * 100.0f) /
(gfloat)torrent_data.size;
- if (torrent_data.downloaded > 100.0f)
- {
- torrent_data.downloaded = 100.0f;
- }
}
else
{
@@ -1380,7 +1415,7 @@ void hashlist_free(hashlist_t* hlist)
g_free(hlist->mark);
}
-gboolean hashlist_resize(hashlist_t* hlist, gsize* a, gsize* r)
+gboolean hashlist_resize(hashlist_t* hlist, G_GNUC_UNUSED gsize* a, gsize* r)
{
gsize ns = hlist->size * 2;
gchar** tmp1;
@@ -1530,7 +1565,7 @@ gboolean hashlist_sync(hashlist_t* hlist, xmlrpc_env * const env,
return TRUE;
}
-void noop_destroy(gpointer key)
+void noop_destroy(G_GNUC_UNUSED gpointer key)
{
}
@@ -1614,3 +1649,99 @@ gboolean get_bool_xmlrpc(xmlrpc_env* env, xmlrpc_value* value)
}
}
}
+
+void liststore_sort_column_changed(GtkTreeSortable* sortable,
+ gpointer user_data)
+{
+ master_t* master = user_data;
+ gint column;
+ GtkSortType order;
+ if (gtk_tree_sortable_get_sort_column_id(sortable, &column, &order))
+ {
+ g_key_file_set_integer(master->config, "view", "sort_column",
+ column + 1);
+ g_key_file_set_boolean(master->config, "view", "sort_desc",
+ order == GTK_SORT_DESCENDING);
+ }
+ else
+ {
+ if (!g_key_file_remove_key(master->config,
+ "view", "sort_column", NULL) &&
+ !g_key_file_remove_key(master->config, "view", "sort_desc", NULL))
+ {
+ return;
+ }
+ }
+ save_config(master);
+}
+
+#ifndef G_VALUE_INIT
+# define G_VALUE_INIT { 0 }
+#endif
+
+gint liststore_default_compare_func(GtkTreeModel* model,
+ GtkTreeIter* a,
+ GtkTreeIter* b,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ GValue value = G_VALUE_INIT;
+ gfloat af, bf;
+ gint ai, bi;
+ const gchar* as, * bs;
+ gtk_tree_model_get_value(model, a, COLUMN_DOWN, &value);
+ af = g_value_get_float(&value);
+ g_value_unset(&value);
+ gtk_tree_model_get_value(model, b, COLUMN_DOWN, &value);
+ bf = g_value_get_float(&value);
+ g_value_unset(&value);
+ if (fabs(af - bf) > 1e-4)
+ {
+ return af > bf ? -1 : 1;
+ }
+
+ gtk_tree_model_get_value(model, a, COLUMN_UP, &value);
+ af = g_value_get_float(&value);
+ g_value_unset(&value);
+ gtk_tree_model_get_value(model, b, COLUMN_UP, &value);
+ bf = g_value_get_float(&value);
+ g_value_unset(&value);
+ if (fabs(af - bf) > 1e-4)
+ {
+ return af > bf ? -1 : 1;
+ }
+
+ gtk_tree_model_get_value(model, a, COLUMN_STATE, &value);
+ ai = g_value_get_int(&value);
+ g_value_unset(&value);
+ gtk_tree_model_get_value(model, b, COLUMN_STATE, &value);
+ bi = g_value_get_int(&value);
+ g_value_unset(&value);
+ if (ai != bi)
+ {
+ return ai > bi ? -1 : 1;
+ }
+
+ gtk_tree_model_get_value(model, a, COLUMN_PROGRESSSORT, &value);
+ af = g_value_get_float(&value);
+ g_value_unset(&value);
+ gtk_tree_model_get_value(model, b, COLUMN_PROGRESSSORT, &value);
+ bf = g_value_get_float(&value);
+ g_value_unset(&value);
+ if (fabs(af - bf) > 1e-3)
+ {
+ return af < bf ? -1 : 1;
+ }
+
+ gtk_tree_model_get_value(model, a, COLUMN_TITLE, &value);
+ as = g_value_get_string(&value);
+ {
+ GValue value2 = G_VALUE_INIT;
+ gint ret;
+ gtk_tree_model_get_value(model, b, COLUMN_TITLE, &value2);
+ bs = g_value_get_string(&value2);
+ ret = strcmp(as, bs);
+ g_value_unset(&value);
+ g_value_unset(&value2);
+ return ret;
+ }
+}