From 096eb60b18190d37159bbdddc74053861ae3312a Mon Sep 17 00:00:00 2001 From: Alan Fitton Date: Sun, 6 Mar 2011 18:57:53 +0000 Subject: TRG_NOUNIQUE environment env for starting more than one instance. fix start url paused. stop timers being activated by interactive actions. and... experimental speed graph! --- src/Makefile.am | 1 + src/main.c | 22 +- src/protocol-constants.h | 1 + src/requests.c | 5 +- src/requests.h | 2 +- src/trg-about-window.c | 11 +- src/trg-files-model.c | 3 +- src/trg-files-model.h | 3 +- src/trg-files-tree-view.c | 12 +- src/trg-general-panel.c | 28 +- src/trg-main-window.c | 207 ++++++++------ src/trg-main-window.h | 4 + src/trg-menu-bar.c | 20 +- src/trg-remote-prefs-dialog.c | 66 +++-- src/trg-torrent-graph.c | 622 +++++++++++++++++++++++++++++++++++++++++ src/trg-torrent-graph.c.glg | 106 +++++++ src/trg-torrent-graph.h | 52 ++++ src/trg-torrent-graph.h.glg | 56 ++++ src/trg-torrent-props-dialog.c | 6 +- src/trg-torrent-tree-view.c | 8 +- src/trg-trackers-model.c | 2 +- src/trg-trackers-model.h | 2 +- src/trg-trackers-tree-view.c | 20 +- src/trg-tree-view.c | 4 +- src/trg-tree-view.h | 13 +- src/util.c | 3 +- src/util.h | 3 +- 27 files changed, 1083 insertions(+), 199 deletions(-) create mode 100644 src/trg-torrent-graph.c create mode 100644 src/trg-torrent-graph.c.glg create mode 100644 src/trg-torrent-graph.h create mode 100644 src/trg-torrent-graph.h.glg (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index eb7380a..e726dab 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -68,6 +68,7 @@ transmission_remote_gtk_SOURCES = main.c \ trg-cell-renderer-priority.c \ trg-torrent-move-dialog.c \ trg-stats-dialog.c \ + trg-torrent-graph.c \ $(NULL) transmission_remote_gtk_LDFLAGS = -lcurl $(jsonglib_LIBS) $(gtk_LIBS) $(gthread_LIBS) $(GEOIP_LIBS) $(gconf_LIBS) $(gio_LIBS) $(unique_LIBS) $(notify_LIBS) diff --git a/src/main.c b/src/main.c index 3b8cd4e..21cd33c 100644 --- a/src/main.c +++ b/src/main.c @@ -75,19 +75,21 @@ message_received_cb(UniqueApp * app G_GNUC_UNUSED, int main(int argc, char *argv[]) { int returnValue; - UniqueApp *app; + UniqueApp *app = NULL; TrgMainWindow *window; trg_client *client; + gboolean withUnique; g_type_init(); g_thread_init(NULL); gdk_threads_init(); gtk_init(&argc, &argv); - app = unique_app_new_with_commands("org.eth0.uk.org.trg", NULL, - "add", COMMAND_ADD, NULL); + if ((withUnique = g_getenv("TRG_NOUNIQUE") == NULL)) + app = unique_app_new_with_commands("org.eth0.uk.org.trg", NULL, + "add", COMMAND_ADD, NULL); - if (unique_app_is_running(app)) { + if (withUnique && unique_app_is_running(app)) { UniqueCommand command; UniqueResponse response; UniqueMessageData *message; @@ -115,10 +117,12 @@ int main(int argc, char *argv[]) curl_global_init(CURL_GLOBAL_ALL); window = trg_main_window_new(client); - unique_app_watch_window(app, GTK_WINDOW(window)); - g_signal_connect(app, "message-received", - G_CALLBACK(message_received_cb), window); + if (withUnique) { + unique_app_watch_window(app, GTK_WINDOW(window)); + g_signal_connect(app, "message-received", + G_CALLBACK(message_received_cb), window); + } gtk_widget_show_all(GTK_WIDGET(window)); @@ -128,7 +132,9 @@ int main(int argc, char *argv[]) curl_global_cleanup(); } - g_object_unref(app); + if (withUnique) + g_object_unref(app); + gdk_threads_leave(); return EXIT_SUCCESS; diff --git a/src/protocol-constants.h b/src/protocol-constants.h index 604795b..98d1d72 100644 --- a/src/protocol-constants.h +++ b/src/protocol-constants.h @@ -106,6 +106,7 @@ #define PARAM_FIELDS "fields" #define PARAM_METAINFO "metainfo" #define PARAM_FILENAME "filename" +#define PARAM_PAUSED "paused" #define PARAM_TAG "tag" enum { diff --git a/src/requests.c b/src/requests.c index ceba326..99bdd75 100644 --- a/src/requests.c +++ b/src/requests.c @@ -80,7 +80,7 @@ JsonNode *torrent_pause(JsonArray * array) return generic_request(METHOD_TORRENT_STOP, array); } -JsonNode *torrent_reannounce(JsonArray *array) +JsonNode *torrent_reannounce(JsonArray * array) { return generic_request(METHOD_TORRENT_REANNOUNCE, array); } @@ -155,11 +155,12 @@ JsonNode *torrent_get(void) return root; } -JsonNode *torrent_add_url(const gchar * url, gboolean paused G_GNUC_UNUSED) +JsonNode *torrent_add_url(const gchar * url, gboolean paused) { JsonNode *root = base_request(METHOD_TORRENT_ADD); JsonObject *args = node_get_arguments(root); json_object_set_string_member(args, PARAM_FILENAME, url); + json_object_set_boolean_member(args, PARAM_PAUSED, paused); return root; } diff --git a/src/requests.h b/src/requests.h index 5a1b771..1b53704 100644 --- a/src/requests.h +++ b/src/requests.h @@ -32,7 +32,7 @@ JsonNode *torrent_set(JsonArray * array); JsonNode *torrent_pause(JsonArray * array); JsonNode *torrent_start(JsonArray * array); JsonNode *torrent_verify(JsonArray * array); -JsonNode *torrent_reannounce(JsonArray *array); +JsonNode *torrent_reannounce(JsonArray * array); JsonNode *torrent_remove(JsonArray * array, int removeData); JsonNode *torrent_add(gchar * filename, gboolean paused); JsonNode *torrent_add_url(const gchar * url, gboolean paused); diff --git a/src/trg-about-window.c b/src/trg-about-window.c index 3e9e3af..60aa7d7 100644 --- a/src/trg-about-window.c +++ b/src/trg-about-window.c @@ -28,7 +28,7 @@ #include "trg-about-window.h" #include "util.h" -GtkWidget *trg_about_window_new(GtkWindow *parent) +GtkWidget *trg_about_window_new(GtkWindow * parent) { GtkWidget *dialog; GdkPixbuf *logo; @@ -39,11 +39,12 @@ GtkWidget *trg_about_window_new(GtkWindow *parent) gtk_window_set_transient_for(GTK_WINDOW(dialog), parent); gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE); - logo = gtk_icon_theme_load_icon(gtk_icon_theme_get_default(), PACKAGE_NAME, 48, - GTK_ICON_LOOKUP_USE_BUILTIN, NULL); + logo = + gtk_icon_theme_load_icon(gtk_icon_theme_get_default(), + PACKAGE_NAME, 48, + GTK_ICON_LOOKUP_USE_BUILTIN, NULL); - if (logo != NULL) - { + if (logo != NULL) { gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(dialog), logo); g_object_unref(logo); } diff --git a/src/trg-files-model.c b/src/trg-files-model.c index 3f2458d..3051f55 100644 --- a/src/trg-files-model.c +++ b/src/trg-files-model.c @@ -54,8 +54,7 @@ static void trg_files_model_iter_new(TrgFilesModel * model, FILESCOL_SIZE, size, FILESCOL_ID, id, -1); } -void trg_files_model_set_accept(TrgFilesModel * model, - gboolean accept) +void trg_files_model_set_accept(TrgFilesModel * model, gboolean accept) { TrgFilesModelPrivate *priv = TRG_FILES_MODEL_GET_PRIVATE(model); priv->accept = accept; diff --git a/src/trg-files-model.h b/src/trg-files-model.h index 5871120..c92ddd0 100644 --- a/src/trg-files-model.h +++ b/src/trg-files-model.h @@ -68,7 +68,6 @@ void trg_files_model_update(TrgFilesModel * model, gint64 updateSerial, JsonObject * t, gboolean first); gint64 trg_files_model_get_torrent_id(TrgFilesModel * model); -void trg_files_model_set_accept(TrgFilesModel * model, - gboolean accept); +void trg_files_model_set_accept(TrgFilesModel * model, gboolean accept); #endif /* TRG_FILES_MODEL_H_ */ diff --git a/src/trg-files-tree-view.c b/src/trg-files-tree-view.c index b65c636..9ef4eda 100644 --- a/src/trg-files-tree-view.c +++ b/src/trg-files-tree-view.c @@ -136,14 +136,12 @@ static void remove_array_if_empty(JsonObject * args, gchar * key) } static void -on_files_update(JsonObject * response, int status, - gpointer data) +on_files_update(JsonObject * response, int status, gpointer data) { TrgFilesTreeViewPrivate *priv = TRG_FILES_TREE_VIEW_GET_PRIVATE(data); GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(data)); - trg_files_model_set_accept(TRG_FILES_MODEL(model), - TRUE); + trg_files_model_set_accept(TRG_FILES_MODEL(model), TRUE); on_generic_interactive_action(response, status, priv->win); } @@ -188,11 +186,9 @@ static void send_updated_file_prefs(TrgFilesTreeView * tv) remove_array_if_empty(args, FIELD_FILES_PRIORITY_NORMAL); remove_array_if_empty(args, FIELD_FILES_PRIORITY_LOW); - trg_files_model_set_accept(TRG_FILES_MODEL(model), - FALSE); + trg_files_model_set_accept(TRG_FILES_MODEL(model), FALSE); - dispatch_async(priv->client, req, on_files_update, - tv); + dispatch_async(priv->client, req, on_files_update, tv); } static void set_low(GtkWidget * w G_GNUC_UNUSED, gpointer data) diff --git a/src/trg-general-panel.c b/src/trg-general-panel.c index 448deee..a5139df 100644 --- a/src/trg-general-panel.c +++ b/src/trg-general-panel.c @@ -27,7 +27,7 @@ #include "trg-torrent-model.h" static void gtk_label_clear(GtkLabel * l); -static GtkLabel *gen_panel_label_get_key_label(GtkLabel *l); +static GtkLabel *gen_panel_label_get_key_label(GtkLabel * l); static GtkLabel *trg_general_panel_add_label(TrgGeneralPanel * fixed, char *key, int col, int row); @@ -72,7 +72,8 @@ void trg_general_panel_clear(TrgGeneralPanel * panel) gtk_label_clear(priv->gen_ratio_label); gtk_label_clear(priv->gen_downloaddir_label); gtk_label_clear(priv->gen_error_label); - gtk_label_clear(gen_panel_label_get_key_label(GTK_LABEL(priv->gen_error_label))); + gtk_label_clear(gen_panel_label_get_key_label + (GTK_LABEL(priv->gen_error_label))); } static void gtk_label_clear(GtkLabel * l) @@ -80,7 +81,7 @@ static void gtk_label_clear(GtkLabel * l) gtk_label_set_text(l, ""); } -static GtkLabel *gen_panel_label_get_key_label(GtkLabel *l) +static GtkLabel *gen_panel_label_get_key_label(GtkLabel * l) { return GTK_LABEL(g_object_get_data(G_OBJECT(l), "key-label")); } @@ -136,15 +137,21 @@ void trg_general_panel_update(TrgGeneralPanel * panel, JsonObject * t, gtk_label_set_text(GTK_LABEL(priv->gen_name_label), torrent_get_name(t)); - gtk_label_set_text(GTK_LABEL(priv->gen_downloaddir_label), torrent_get_download_dir(t)); + gtk_label_set_text(GTK_LABEL(priv->gen_downloaddir_label), + torrent_get_download_dir(t)); errorStr = torrent_get_errorstr(t); - keyLabel = gen_panel_label_get_key_label(GTK_LABEL(priv->gen_error_label)); + keyLabel = + gen_panel_label_get_key_label(GTK_LABEL(priv->gen_error_label)); if (strlen(errorStr) > 0) { - gchar *errorValMarkup = g_markup_printf_escaped("%s", errorStr); - gtk_label_set_markup(GTK_LABEL(priv->gen_error_label), errorValMarkup); + gchar *errorValMarkup = + g_markup_printf_escaped("%s", + errorStr); + gtk_label_set_markup(GTK_LABEL(priv->gen_error_label), + errorValMarkup); g_free(errorValMarkup); - gtk_label_set_markup(keyLabel, "Error:"); + gtk_label_set_markup(keyLabel, + "Error:"); } else { gtk_label_clear(GTK_LABEL(priv->gen_error_label)); gtk_label_clear(keyLabel); @@ -185,7 +192,7 @@ static GtkLabel *trg_general_panel_add_label(TrgGeneralPanel * fixed, value = gtk_label_new(NULL); gtk_label_set_selectable(GTK_LABEL(value), TRUE); - gtk_fixed_put(GTK_FIXED(fixed), value, 140 + (col * 300), + gtk_fixed_put(GTK_FIXED(fixed), value, 120 + (col * 300), 10 + (row * 22)); g_object_set_data(G_OBJECT(value), "key-label", keyLabel); @@ -227,8 +234,7 @@ static void trg_general_panel_init(TrgGeneralPanel * self) priv->gen_downloaddir_label = trg_general_panel_add_label(self, "Location:", 0, 5); - priv->gen_error_label = - trg_general_panel_add_label(self, "", 0, 6); + priv->gen_error_label = trg_general_panel_add_label(self, "", 0, 6); gtk_widget_set_sensitive(GTK_WIDGET(self), FALSE); } diff --git a/src/trg-main-window.c b/src/trg-main-window.c index db0db2a..1f24bd4 100644 --- a/src/trg-main-window.c +++ b/src/trg-main-window.c @@ -54,6 +54,7 @@ #include "trg-trackers-tree-view.h" #include "trg-trackers-model.h" #include "trg-state-selector.h" +#include "trg-torrent-graph.h" #include "trg-torrent-move-dialog.h" #include "trg-torrent-props-dialog.h" #include "trg-torrent-add-url-dialog.h" @@ -105,15 +106,20 @@ static gint confirm_action_dialog(GtkWindow * win, gchar * action_stock); static GtkWidget *my_scrolledwin_new(GtkWidget * child); static void view_stats_toggled_cb(GtkWidget * w, gpointer data); -static void trg_widget_set_visible(GtkWidget *w, gboolean visible); +static void trg_widget_set_visible(GtkWidget * w, gboolean visible); static void view_states_toggled_cb(GtkCheckMenuItem * w, gpointer data); static void view_notebook_toggled_cb(GtkCheckMenuItem * w, gpointer data); static GtkWidget *trg_main_window_notebook_new(TrgMainWindow * win); static void on_session_get(JsonObject * response, int status, gpointer data); +static void on_torrent_get(JsonObject * response, + int mode, int status, + gpointer data); static void on_torrent_get_first(JsonObject * response, int status, gpointer data); -static void on_torrent_get(JsonObject * response, int status, +static void on_torrent_get_update(JsonObject * response, int status, + gpointer data); +static void on_torrent_get_interactive(JsonObject * response, int status, gpointer data); static gboolean trg_update_torrents_timerfunc(gpointer data); static void trg_main_window_update_notebook_displays(TrgMainWindow * win, @@ -133,9 +139,6 @@ static gboolean trg_dialog_error_handler(TrgMainWindow * win, int status); static gboolean torrent_selection_changed(GtkWidget * w, gpointer data); static void trg_main_window_torrent_scrub(TrgMainWindow * win); -static void on_torrent_get_multipurpose(JsonObject * response, - gboolean first, int status, - gpointer data); static void entry_filter_changed_cb(GtkWidget * w, gpointer data); static void torrent_state_selection_changed(TrgStateSelector * selector, guint flag, gpointer data); @@ -219,6 +222,8 @@ struct _TrgMainWindowPrivate { TrgPeersModel *peersModel; TrgPeersTreeView *peersTreeView; + TrgTorrentGraph *graph; + GtkWidget *hpaned, *vpaned; GtkWidget *filterEntry, *filterEntryClearButton; }; @@ -594,7 +599,7 @@ static void reannounce_cb(GtkWidget * w G_GNUC_UNUSED, gpointer data) dispatch_async(priv->client, torrent_reannounce(build_json_id_array - (priv->torrentTreeView)), + (priv->torrentTreeView)), on_generic_interactive_action, data); } @@ -638,7 +643,7 @@ static gint confirm_action_dialog(GtkWindow * win, gtk_tree_model_get(GTK_TREE_MODEL (priv->sortedTorrentModel), &firstIter, TORRENT_COLUMN_NAME, &name, -1); - g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL); + g_list_foreach(list, (GFunc) gtk_tree_path_free, NULL); g_list_free(list); dialog = @@ -757,7 +762,7 @@ static void view_stats_toggled_cb(GtkWidget * w, gpointer data) /* gtk_widget_set_sensitive() was introduced in 2.18, we can have a minimum of * 2.16 otherwise. */ -static void trg_widget_set_visible(GtkWidget *w, gboolean visible) +static void trg_widget_set_visible(GtkWidget * w, gboolean visible) { if (visible) gtk_widget_show(w); @@ -816,6 +821,12 @@ GtkWidget *trg_main_window_notebook_new(TrgMainWindow * win) (priv->peersTreeView)), gtk_label_new("Peers")); + priv->graph = trg_torrent_graph_new(gtk_widget_get_style(notebook)); + gtk_notebook_append_page(GTK_NOTEBOOK(notebook), + GTK_WIDGET(priv->graph), + gtk_label_new("Graph")); + trg_torrent_graph_start(priv->graph); + return notebook; } @@ -866,16 +877,96 @@ static void on_session_get(JsonObject * response, int status, response_unref(response); } +static void +on_torrent_get(JsonObject * response, int mode, + int status, gpointer data) +{ + 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); + return; + } + + first = (mode == TORRENT_GET_MODE_FIRST); + + g_mutex_lock(client->updateMutex); + gdk_threads_enter(); + + if (status != CURLE_OK) { + client->failCount++; + if (client->failCount >= 3) { + trg_main_window_conn_changed(TRG_MAIN_WINDOW(data), FALSE); + trg_dialog_error_handler(TRG_MAIN_WINDOW(data), + response, status); + } else { + const gchar *msg; + gchar *statusBarMsg; + + msg = make_error_message(response, status); + statusBarMsg = + g_strdup_printf("Request %d/%d failed: %s", + client->failCount, 3, msg); + trg_status_bar_push_connection_msg(priv->statusBar, + statusBarMsg); + g_free((gpointer) msg); + g_free(statusBarMsg); + g_timeout_add_seconds(client->interval, + trg_update_torrents_timerfunc, data); + } + gdk_threads_leave(); + g_mutex_unlock(client->updateMutex); + response_unref(response); + return; + } + + client->failCount = 0; + stats.downRateTotal = 0; + stats.upRateTotal = 0; + stats.seeding = 0; + stats.down = 0; + stats.paused = 0; + + client->updateSerial++; + + trg_torrent_model_update(priv->torrentModel, priv->client, + response, &stats, first); + + update_selected_torrent_notebook(TRG_MAIN_WINDOW(data), first); + + trg_status_bar_update(priv->statusBar, &stats); + trg_torrent_graph_set_speed(priv->graph, &stats); + + if (mode != TORRENT_GET_MODE_INTERACTION) + g_timeout_add_seconds(client->interval, trg_update_torrents_timerfunc, data); + + gdk_threads_leave(); + g_mutex_unlock(client->updateMutex); + response_unref(response); +} + static void on_torrent_get_first(JsonObject * response, int status, gpointer data) { - on_torrent_get_multipurpose(response, TRUE, status, data); + on_torrent_get(response, TORRENT_GET_MODE_FIRST, status, data); } -static void on_torrent_get(JsonObject * response, int status, +static void on_torrent_get_interactive(JsonObject * response, int status, gpointer data) +{ + on_torrent_get(response, TORRENT_GET_MODE_INTERACTION, status, data); +} + +static void on_torrent_get_update(JsonObject * response, int status, gpointer data) { - on_torrent_get_multipurpose(response, FALSE, status, data); + on_torrent_get(response, TORRENT_GET_MODE_UPDATE, status, data); } static gboolean trg_update_torrents_timerfunc(gpointer data) @@ -883,7 +974,7 @@ static gboolean trg_update_torrents_timerfunc(gpointer data) TrgMainWindowPrivate *priv = TRG_MAIN_WINDOW_GET_PRIVATE(data); if (priv->client->session != NULL) - dispatch_async(priv->client, torrent_get(), on_torrent_get, data); + dispatch_async(priv->client, torrent_get(), on_torrent_get_update, data); return FALSE; } @@ -1026,14 +1117,14 @@ on_generic_interactive_action(JsonObject * response, int status, { TrgMainWindowPrivate *priv = TRG_MAIN_WINDOW_GET_PRIVATE(data); - if (priv->client->session != NULL) - { + if (priv->client->session != NULL) { gdk_threads_enter(); trg_dialog_error_handler(TRG_MAIN_WINDOW(data), response, status); gdk_threads_leave(); if (status == CURLE_OK || status == FAIL_RESPONSE_UNSUCCESSFUL) - dispatch_async(priv->client, torrent_get(), on_torrent_get, data); + dispatch_async(priv->client, torrent_get(), on_torrent_get_interactive, + data); } response_unref(response); @@ -1050,77 +1141,6 @@ void trg_main_window_torrent_scrub(TrgMainWindow * win) trg_general_panel_clear(priv->genDetails); } -static void -on_torrent_get_multipurpose(JsonObject * response, gboolean first, - int status, gpointer data) -{ - trg_torrent_model_update_stats stats; - TrgMainWindowPrivate *priv; - trg_client *client; - - priv = TRG_MAIN_WINDOW_GET_PRIVATE(data); - client = priv->client; - - /* Disconnected between request and response callback */ - if (client->session == NULL) { - response_unref(response); - return; - } - - g_mutex_lock(client->updateMutex); - gdk_threads_enter(); - - if (status != CURLE_OK) { - client->failCount++; - if (client->failCount >= 3) { - trg_main_window_conn_changed(TRG_MAIN_WINDOW(data), FALSE); - trg_dialog_error_handler(TRG_MAIN_WINDOW(data), - response, status); - } else { - const gchar *msg; - gchar *statusBarMsg; - - msg = make_error_message(response, status); - statusBarMsg = - g_strdup_printf("Request %d/%d failed: %s", - client->failCount, 3, msg); - trg_status_bar_push_connection_msg(priv->statusBar, - statusBarMsg); - g_free((gpointer) msg); - g_free(statusBarMsg); - g_timeout_add_seconds(client->interval, - trg_update_torrents_timerfunc, data); - } - gdk_threads_leave(); - g_mutex_unlock(client->updateMutex); - response_unref(response); - return; - } - - client->failCount = 0; - stats.downRateTotal = 0; - stats.upRateTotal = 0; - stats.seeding = 0; - stats.down = 0; - stats.paused = 0; - - client->updateSerial++; - - trg_torrent_model_update(priv->torrentModel, priv->client, - response, &stats, first); - - update_selected_torrent_notebook(TRG_MAIN_WINDOW(data), first); - - trg_status_bar_update(priv->statusBar, &stats); - - g_timeout_add_seconds(client->interval, trg_update_torrents_timerfunc, - data); - - gdk_threads_leave(); - g_mutex_unlock(client->updateMutex); - response_unref(response); -} - static void entry_filter_changed_cb(GtkWidget * w, gpointer data) { TrgMainWindowPrivate *priv = TRG_MAIN_WINDOW_GET_PRIVATE(data); @@ -1158,7 +1178,7 @@ void trg_main_window_conn_changed(TrgMainWindow * win, gboolean connected) gtk_widget_set_sensitive(GTK_WIDGET(priv->filesTreeView), connected); gtk_widget_set_sensitive(GTK_WIDGET(priv->trackersTreeView), connected); - gtk_widget_set_sensitive(GTK_WIDGET(priv->genDetails), connected); + gtk_widget_set_sensitive(GTK_WIDGET(priv->genDetails), connected);; if (connected == FALSE) { json_object_unref(tc->session); @@ -1166,6 +1186,7 @@ void trg_main_window_conn_changed(TrgMainWindow * win, gboolean connected) gtk_list_store_clear(GTK_LIST_STORE(priv->torrentModel)); trg_main_window_torrent_scrub(win); + trg_torrent_graph_set_nothing(priv->graph); } } @@ -1239,7 +1260,8 @@ static TrgMenuBar *trg_main_window_menu_bar_new(TrgMainWindow * win) g_signal_connect(b_resume, "activate", G_CALLBACK(resume_cb), win); g_signal_connect(b_pause, "activate", G_CALLBACK(pause_cb), win); g_signal_connect(b_verify, "activate", G_CALLBACK(verify_cb), win); - g_signal_connect(b_reannounce, "activate", G_CALLBACK(reannounce_cb), win); + g_signal_connect(b_reannounce, "activate", G_CALLBACK(reannounce_cb), + win); g_signal_connect(b_delete, "activate", G_CALLBACK(delete_cb), win); g_signal_connect(b_remove, "activate", G_CALLBACK(remove_cb), win); g_signal_connect(b_move, "activate", G_CALLBACK(move_cb), win); @@ -1439,11 +1461,10 @@ trg_torrent_tv_view_menu(GtkWidget * treeview, GTK_STOCK_REFRESH, TRUE, G_CALLBACK(verify_cb), data); trg_imagemenuitem_new(GTK_MENU_SHELL(menu), "Re-announce", - GTK_STOCK_REFRESH, TRUE, G_CALLBACK(reannounce_cb), - data); - trg_imagemenuitem_new(GTK_MENU_SHELL(menu), "Move", - GTK_STOCK_HARDDISK, TRUE, G_CALLBACK(move_cb), - data); + GTK_STOCK_REFRESH, TRUE, + G_CALLBACK(reannounce_cb), data); + trg_imagemenuitem_new(GTK_MENU_SHELL(menu), "Move", GTK_STOCK_HARDDISK, + TRUE, G_CALLBACK(move_cb), data); trg_imagemenuitem_new(GTK_MENU_SHELL(menu), "Remove", GTK_STOCK_REMOVE, TRUE, G_CALLBACK(remove_cb), data); trg_imagemenuitem_new(GTK_MENU_SHELL(menu), "Remove & Delete", diff --git a/src/trg-main-window.h b/src/trg-main-window.h index b461075..d298b48 100644 --- a/src/trg-main-window.h +++ b/src/trg-main-window.h @@ -53,6 +53,10 @@ typedef struct { GtkWindowClass parent_class; } TrgMainWindowClass; +#define TORRENT_GET_MODE_FIRST 0 +#define TORRENT_GET_MODE_INTERACTION 1 +#define TORRENT_GET_MODE_UPDATE 2 + GType trg_main_window_get_type(void); gboolean trg_add_from_filename(TrgMainWindow * win, gchar * fileName); void on_session_set(JsonObject * response, int status, gpointer data); diff --git a/src/trg-menu-bar.c b/src/trg-menu-bar.c index 70e91a2..adf15e6 100644 --- a/src/trg-menu-bar.c +++ b/src/trg-menu-bar.c @@ -269,8 +269,9 @@ GtkWidget *trg_menu_bar_file_file_menu_new(TrgMenuBarPrivate * priv) trg_menu_bar_item_new(GTK_MENU_SHELL(fileMenu), "Add from _URL", GTK_STOCK_ADD, FALSE); - priv->mb_quit = trg_menu_bar_item_new(GTK_MENU_SHELL(fileMenu), "_Quit", - GTK_STOCK_QUIT, TRUE); + priv->mb_quit = + trg_menu_bar_item_new(GTK_MENU_SHELL(fileMenu), "_Quit", + GTK_STOCK_QUIT, TRUE); return file; } @@ -356,19 +357,18 @@ static void trg_menu_bar_class_init(TrgMenuBarClass * klass) trg_menu_bar_install_widget_prop(object_class, PROP_VERIFY_BUTTON, "verify-button", "Verify Button"); trg_menu_bar_install_widget_prop(object_class, PROP_REANNOUNCE_BUTTON, - "reannounce-button", "Re-announce Button"); + "reannounce-button", + "Re-announce Button"); trg_menu_bar_install_widget_prop(object_class, PROP_PAUSE_BUTTON, "pause-button", "Pause Button"); trg_menu_bar_install_widget_prop(object_class, PROP_PROPS_BUTTON, "props-button", "Props Button"); trg_menu_bar_install_widget_prop(object_class, PROP_ABOUT_BUTTON, "about-button", "About Button"); - trg_menu_bar_install_widget_prop(object_class, - PROP_VIEW_STATS_BUTTON, + trg_menu_bar_install_widget_prop(object_class, PROP_VIEW_STATS_BUTTON, "view-stats-button", "View stats button"); - trg_menu_bar_install_widget_prop(object_class, - PROP_VIEW_STATES_BUTTON, + trg_menu_bar_install_widget_prop(object_class, PROP_VIEW_STATES_BUTTON, "view-states-button", "View states Button"); trg_menu_bar_install_widget_prop(object_class, @@ -379,12 +379,10 @@ static void trg_menu_bar_class_init(TrgMenuBarClass * klass) PROP_REMOTE_PREFS_BUTTON, "remote-prefs-button", "Remote Prefs Button"); - trg_menu_bar_install_widget_prop(object_class, - PROP_LOCAL_PREFS_BUTTON, + trg_menu_bar_install_widget_prop(object_class, PROP_LOCAL_PREFS_BUTTON, "local-prefs-button", "Local Prefs Button"); - trg_menu_bar_install_widget_prop(object_class, - PROP_QUIT, + trg_menu_bar_install_widget_prop(object_class, PROP_QUIT, "quit-button", "Quit Button"); } diff --git a/src/trg-remote-prefs-dialog.c b/src/trg-remote-prefs-dialog.c index 764c4a5..b0ca1c5 100644 --- a/src/trg-remote-prefs-dialog.c +++ b/src/trg-remote-prefs-dialog.c @@ -124,7 +124,7 @@ static void update_session(GtkDialog * dlg) gtk_spin_button_json_int_out(GTK_SPIN_BUTTON(priv->peer_port_spin), args); gtk_toggle_button_json_out(GTK_TOGGLE_BUTTON - (priv->blocklist_check), args); + (priv->blocklist_check), args); if (priv->blocklist_url_entry) gtk_entry_json_output(GTK_ENTRY(priv->blocklist_url_entry), args); @@ -298,30 +298,35 @@ static void on_port_tested(JsonObject * response, int status, gdk_threads_enter(); if (TRG_IS_REMOTE_PREFS_DIALOG(data)) { - TrgRemotePrefsDialogPrivate *priv = TRG_REMOTE_PREFS_DIALOG_GET_PRIVATE(data); + TrgRemotePrefsDialogPrivate *priv = + TRG_REMOTE_PREFS_DIALOG_GET_PRIVATE(data); gtk_button_set_label(GTK_BUTTON(priv->port_test_button), "Retest"); gtk_widget_set_sensitive(priv->port_test_button, TRUE); - if (status == CURLE_OK) - { - gboolean isOpen = json_object_get_boolean_member(get_arguments(response), "port-is-open"); + if (status == CURLE_OK) { + gboolean isOpen = + json_object_get_boolean_member(get_arguments(response), + "port-is-open"); if (isOpen) - gtk_label_set_markup(GTK_LABEL(priv->port_test_label), "Port is open"); + gtk_label_set_markup(GTK_LABEL(priv->port_test_label), + "Port is open"); else - gtk_label_set_markup(GTK_LABEL(priv->port_test_label), "Port is closed"); + gtk_label_set_markup(GTK_LABEL(priv->port_test_label), + "Port is closed"); } else { trg_error_dialog(GTK_WINDOW(data), status, response); } - } + } - gdk_threads_leave(); - response_unref(response); + gdk_threads_leave(); + response_unref(response); } -static void port_test_cb(GtkButton *b, gpointer data) +static void port_test_cb(GtkButton * b, gpointer data) { - TrgRemotePrefsDialogPrivate *priv = TRG_REMOTE_PREFS_DIALOG_GET_PRIVATE(data); + TrgRemotePrefsDialogPrivate *priv = + TRG_REMOTE_PREFS_DIALOG_GET_PRIVATE(data); JsonNode *req = port_test(); gtk_label_set_text(GTK_LABEL(priv->port_test_label), "Port test"); @@ -332,20 +337,26 @@ static void port_test_cb(GtkButton *b, gpointer data) } static void on_blocklist_updated(JsonObject * response, int status, - gpointer data) + gpointer data) { gdk_threads_enter(); if (TRG_IS_REMOTE_PREFS_DIALOG(data)) { - TrgRemotePrefsDialogPrivate *priv = TRG_REMOTE_PREFS_DIALOG_GET_PRIVATE(data); + TrgRemotePrefsDialogPrivate *priv = + TRG_REMOTE_PREFS_DIALOG_GET_PRIVATE(data); gtk_widget_set_sensitive(priv->blocklist_update_button, TRUE); - gtk_button_set_label(GTK_BUTTON(priv->blocklist_update_button), "Update"); + gtk_button_set_label(GTK_BUTTON(priv->blocklist_update_button), + "Update"); if (status == CURLE_OK) { JsonObject *args = get_arguments(response); - gchar *labelText = g_strdup_printf("Blocklist (%ld entries)", json_object_get_int_member(args, SGET_BLOCKLIST_SIZE)); - gtk_button_set_label(GTK_BUTTON(priv->blocklist_check), labelText); + gchar *labelText = + g_strdup_printf("Blocklist (%ld entries)", + json_object_get_int_member(args, + SGET_BLOCKLIST_SIZE)); + gtk_button_set_label(GTK_BUTTON(priv->blocklist_check), + labelText); g_free(labelText); } else { trg_error_dialog(GTK_WINDOW(data), status, response); @@ -357,9 +368,10 @@ static void on_blocklist_updated(JsonObject * response, int status, response_unref(response); } -static void update_blocklist_cb(GtkButton *b, gpointer data) +static void update_blocklist_cb(GtkButton * b, gpointer data) { - TrgRemotePrefsDialogPrivate *priv = TRG_REMOTE_PREFS_DIALOG_GET_PRIVATE(data); + TrgRemotePrefsDialogPrivate *priv = + TRG_REMOTE_PREFS_DIALOG_GET_PRIVATE(data); JsonNode *req = blocklist_update(); gtk_widget_set_sensitive(GTK_WIDGET(b), FALSE); @@ -431,16 +443,20 @@ static GtkWidget *trg_rprefs_connPage(TrgRemotePrefsDialog * win, session_get_lpd_enabled(s)); widget_set_json_key(w, SGET_LPD_ENABLED); - stringValue = g_strdup_printf("Blocklist (%ld entries)", session_get_blocklist_size(s)); + stringValue = + g_strdup_printf("Blocklist (%ld entries)", + session_get_blocklist_size(s)); tb = priv->blocklist_check = gtk_check_button_new_with_mnemonic(stringValue); - g_free((gchar*)stringValue); + g_free((gchar *) stringValue); widget_set_json_key(tb, SGET_BLOCKLIST_ENABLED); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tb), session_get_blocklist_enabled(s)); - w = priv->blocklist_update_button = gtk_button_new_with_label("Update"); - g_signal_connect(G_OBJECT(w), "clicked", G_CALLBACK(update_blocklist_cb), win); + w = priv->blocklist_update_button = + gtk_button_new_with_label("Update"); + g_signal_connect(G_OBJECT(w), "clicked", + G_CALLBACK(update_blocklist_cb), win); hig_workarea_add_row_w(t, &row, tb, w, NULL); @@ -450,8 +466,8 @@ static GtkWidget *trg_rprefs_connPage(TrgRemotePrefsDialog * win, widget_set_json_key(w, SGET_BLOCKLIST_URL); gtk_entry_set_text(GTK_ENTRY(w), session_get_blocklist_url(s)); gtk_widget_set_sensitive(w, - gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON - (tb))); + gtk_toggle_button_get_active + (GTK_TOGGLE_BUTTON(tb))); g_signal_connect(G_OBJECT(tb), "toggled", G_CALLBACK(toggle_active_arg_is_sensitive), w); hig_workarea_add_row(t, &row, "Blocklist URL:", w, NULL); diff --git a/src/trg-torrent-graph.c b/src/trg-torrent-graph.c new file mode 100644 index 0000000..d4f5765 --- /dev/null +++ b/src/trg-torrent-graph.c @@ -0,0 +1,622 @@ +/* + * transmission-remote-gtk - Transmission RPC client for GTK + * 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. + */ + +/* This graph drawing code was taken from gnome-system-monitor (load-graph.cpp) + * Converted the class from C++ to GObject, substituted out some STL (C++) + * functions, and removed the unecessary parts for memory/cpu. + */ + +#include + +#include +#include +#include +#include + +#include "trg-torrent-graph.h" +#include "util.h" + +#define GRAPH_NUM_POINTS 62 +#define GRAPH_MIN_HEIGHT 40 +#define GRAPH_NUM_LINES 2 +#define GRAPH_NUM_DATA_BLOCK_ELEMENTS GRAPH_NUM_POINTS * GRAPH_NUM_LINES +#define GRAPH_OUT_COLOR "#2D7DB3" +#define GRAPH_IN_COLOR "#844798" +#define GRAPH_LINE_WIDTH 3 + +G_DEFINE_TYPE(TrgTorrentGraph, trg_torrent_graph, GTK_TYPE_VBOX) +#define TRG_TORRENT_GRAPH_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRG_TYPE_TORRENT_GRAPH, TrgTorrentGraphPrivate)) +typedef struct _TrgTorrentGraphPrivate TrgTorrentGraphPrivate; + +struct _TrgTorrentGraphPrivate { + + double fontsize; + double rmargin; + double indent; + guint speed; + guint draw_width, draw_height; + guint render_counter; + guint frames_per_unit; + guint graph_dely; + guint real_draw_height; + double graph_delx; + guint graph_buffer_offset; + + GdkColor colors[2]; + + float data_block[GRAPH_NUM_POINTS * GRAPH_NUM_LINES]; + GList *points; + + GtkWidget *disp; + GdkGC *gc; + GdkDrawable *background; + guint timer_index; + gboolean draw; + guint64 out, in; + unsigned int max; + unsigned values[GRAPH_NUM_POINTS]; + size_t cur; + GtkStyle *style; + + GtkWidget *label_in; + GtkWidget *label_out; +}; + +static int trg_torrent_graph_update(gpointer user_data); + +static void +trg_torrent_graph_get_property(GObject * object, guint property_id, + GValue * value, GParamSpec * pspec) +{ + switch (property_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + } +} + +static void +trg_torrent_graph_set_property(GObject * object, guint property_id, + const GValue * value, GParamSpec * pspec) +{ + switch (property_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + } +} + +#define FRAME_WIDTH 4 +void trg_torrent_graph_draw_background(TrgTorrentGraph * g) +{ + TrgTorrentGraphPrivate *priv; + GtkAllocation allocation; + + double dash[2] = { 1.0, 2.0 }; + cairo_t *cr; + guint i; + unsigned num_bars; + char *caption; + cairo_text_extents_t extents; + unsigned rate; + unsigned total_seconds; + + priv = TRG_TORRENT_GRAPH_GET_PRIVATE(g); + + num_bars = trg_torrent_graph_get_num_bars(g); + priv->graph_dely = (priv->draw_height - 15) / num_bars; /* round to int to avoid AA blur */ + priv->real_draw_height = priv->graph_dely * num_bars; + priv->graph_delx = + (priv->draw_width - 2.0 - priv->rmargin - + priv->indent) / (GRAPH_NUM_POINTS - 3); + priv->graph_buffer_offset = + (int) (1.5 * priv->graph_delx) + FRAME_WIDTH; + + gtk_widget_get_allocation(priv->disp, &allocation); + priv->background = + gdk_pixmap_new(GDK_DRAWABLE(gtk_widget_get_window(priv->disp)), + allocation.width, allocation.height, -1); + cr = gdk_cairo_create(priv->background); + + gdk_cairo_set_source_color(cr, &priv->style->bg[GTK_STATE_NORMAL]); + cairo_paint(cr); + cairo_translate(cr, FRAME_WIDTH, FRAME_WIDTH); + cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); + cairo_rectangle(cr, priv->rmargin + priv->indent, 0, + priv->draw_width - priv->rmargin - priv->indent, + priv->real_draw_height); + + cairo_fill(cr); + + cairo_set_line_width(cr, 1.0); + cairo_set_dash(cr, dash, 2, 0); + cairo_set_font_size(cr, priv->fontsize); + + for (i = 0; i <= num_bars; ++i) { + double y; + gchar caption[32]; + + if (i == 0) + y = 0.5 + priv->fontsize / 2.0; + else if (i == num_bars) + y = i * priv->graph_dely + 0.5; + else + y = i * priv->graph_dely + priv->fontsize / 2.0; + + gdk_cairo_set_source_color(cr, &priv->style->fg[GTK_STATE_NORMAL]); + /* operation orders matters so it's 0 if i == num_bars */ + rate = priv->max - (i * priv->max / num_bars); + trg_strlspeed(caption, (gint64) (rate / 1024)); + cairo_text_extents(cr, caption, &extents); + cairo_move_to(cr, priv->indent - extents.width + 20, y); + cairo_show_text(cr, caption); + } + + cairo_stroke(cr); + + cairo_set_dash(cr, dash, 2, 1.5); + + total_seconds = priv->speed * (GRAPH_NUM_POINTS - 2) / 1000; + + for (i = 0; i < 7; i++) { + unsigned seconds; + const char *format; + double x = + (i) * (priv->draw_width - priv->rmargin - priv->indent) / 6; + cairo_set_source_rgba(cr, 0, 0, 0, 0.75); + cairo_move_to(cr, (ceil(x) + 0.5) + priv->rmargin + priv->indent, + 0.5); + cairo_line_to(cr, (ceil(x) + 0.5) + priv->rmargin + priv->indent, + priv->real_draw_height + 4.5); + cairo_stroke(cr); + seconds = total_seconds - i * total_seconds / 6; + if (i == 0) + format = "%u seconds"; + else + format = "%u"; + caption = g_strdup_printf(format, seconds); + cairo_text_extents(cr, caption, &extents); + cairo_move_to(cr, + ((ceil(x) + 0.5) + priv->rmargin + priv->indent) - + (extents.width / 2), priv->draw_height); + gdk_cairo_set_source_color(cr, &priv->style->fg[GTK_STATE_NORMAL]); + cairo_show_text(cr, caption); + g_free(caption); + } + + cairo_stroke(cr); + cairo_destroy(cr); +} + +void trg_torrent_graph_set_nothing(TrgTorrentGraph *g) +{ + TrgTorrentGraphPrivate *priv = TRG_TORRENT_GRAPH_GET_PRIVATE(g); + + priv->in = priv->out = 0; +} + +void trg_torrent_graph_set_speed(TrgTorrentGraph * g, + trg_torrent_model_update_stats * stats) +{ + TrgTorrentGraphPrivate *priv = TRG_TORRENT_GRAPH_GET_PRIVATE(g); + + priv->in = (guint64) stats->downRateTotal; + priv->out = (guint64) stats->upRateTotal; +} + +static gboolean +trg_torrent_graph_configure(GtkWidget * widget, + GdkEventConfigure * event, gpointer data_ptr) +{ + GtkAllocation allocation; + TrgTorrentGraph *g = TRG_TORRENT_GRAPH(data_ptr); + TrgTorrentGraphPrivate *priv = TRG_TORRENT_GRAPH_GET_PRIVATE(data_ptr); + + gtk_widget_get_allocation(widget, &allocation); + priv->draw_width = allocation.width - 2 * FRAME_WIDTH; + priv->draw_height = allocation.height - 2 * FRAME_WIDTH; + + trg_torrent_graph_clear_background(g); + + if (priv->gc == NULL) + priv->gc = gdk_gc_new(GDK_DRAWABLE(gtk_widget_get_window(widget))); + + trg_torrent_graph_draw(g); + + return TRUE; +} + +static gboolean +trg_torrent_graph_expose(GtkWidget * widget, + GdkEventExpose * event, gpointer data_ptr) +{ + TrgTorrentGraph *g = TRG_TORRENT_GRAPH(data_ptr); + TrgTorrentGraphPrivate *priv = TRG_TORRENT_GRAPH_GET_PRIVATE(data_ptr); + + GtkAllocation allocation; + GdkWindow *window; + cairo_t *cr; + + guint i, j; + float *fp; + gdouble sample_width, x_offset; + + if (priv->background == NULL) { + trg_torrent_graph_draw_background(g); + } + + window = gtk_widget_get_window(priv->disp); + gtk_widget_get_allocation(priv->disp, &allocation); + gdk_draw_drawable(window, + priv->gc, + priv->background, + 0, 0, 0, 0, allocation.width, allocation.height); + + sample_width = + (float) (priv->draw_width - priv->rmargin - + priv->indent) / (float) GRAPH_NUM_POINTS; + x_offset = priv->draw_width - priv->rmargin + (sample_width * 2); + x_offset += + priv->rmargin - + ((sample_width / priv->frames_per_unit) * priv->render_counter); + + cr = gdk_cairo_create(window); + + cairo_set_line_width(cr, GRAPH_LINE_WIDTH); + cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); + cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); + cairo_rectangle(cr, priv->rmargin + priv->indent + FRAME_WIDTH + 1, + FRAME_WIDTH - 1, + priv->draw_width - priv->rmargin - priv->indent - 1, + priv->real_draw_height + FRAME_WIDTH - 1); + cairo_clip(cr); + + for (j = 0; j < GRAPH_NUM_LINES; ++j) { + GList *li = priv->points; + fp = (float *) li->data; + cairo_move_to(cr, x_offset, + (1.0f - fp[j]) * priv->real_draw_height); + gdk_cairo_set_source_color(cr, &(priv->colors[j])); + + i = 0; + for (li = g_list_next(li); li != NULL; li = g_list_next(li)) { + GList *lli = g_list_previous(li); + float *lfp = (float *) lli->data; + fp = (float *) li->data; + + i++; + + if (fp[j] == -1.0f) + continue; + + cairo_curve_to(cr, + x_offset - ((i - 0.5f) * priv->graph_delx), + (1.0f - lfp[j]) * priv->real_draw_height + 3.5f, + x_offset - ((i - 0.5f) * priv->graph_delx), + (1.0f - fp[j]) * priv->real_draw_height + 3.5f, + x_offset - (i * priv->graph_delx), + (1.0f - fp[j]) * priv->real_draw_height + 3.5f); + } + cairo_stroke(cr); + } + + cairo_destroy(cr); + + return TRUE; +} + +void trg_torrent_graph_stop(TrgTorrentGraph * g) +{ + TrgTorrentGraphPrivate *priv = TRG_TORRENT_GRAPH_GET_PRIVATE(g); + + priv->draw = FALSE; +} + +static void trg_torrent_graph_dispose(GObject * object) +{ + TrgTorrentGraph *g = TRG_TORRENT_GRAPH(object); + TrgTorrentGraphPrivate *priv = TRG_TORRENT_GRAPH_GET_PRIVATE(g); + + trg_torrent_graph_stop(g); + + if (priv->timer_index) + g_source_remove(priv->timer_index); + + trg_torrent_graph_clear_background(g); + + G_OBJECT_CLASS(trg_torrent_graph_parent_class)->dispose(object); +} + +void trg_torrent_graph_start(TrgTorrentGraph * g) +{ + TrgTorrentGraphPrivate *priv = TRG_TORRENT_GRAPH_GET_PRIVATE(g); + + if (!priv->timer_index) { + trg_torrent_graph_update(g); + + priv->timer_index = + g_timeout_add(priv->speed / priv->frames_per_unit, + trg_torrent_graph_update, g); + } + + priv->draw = TRUE; +} + +static unsigned get_max_value_element(TrgTorrentGraph * g) +{ + TrgTorrentGraphPrivate *priv = TRG_TORRENT_GRAPH_GET_PRIVATE(g); + unsigned r = 0; + int i; + + for (i = 0; i < GRAPH_NUM_POINTS; i++) + if (priv->values[i] > r) + r = priv->values[i]; + + return r; +} + +static void trg_torrent_graph_update_net(TrgTorrentGraph * g) +{ + TrgTorrentGraphPrivate *priv = TRG_TORRENT_GRAPH_GET_PRIVATE(g); + + unsigned max, new_max, bak_max, pow2, base10, coef10, factor10, + num_bars; + + float scale; + char speed[32]; + gchar *labelMarkup; + GList *li; + + float *fp = (float *) (priv->points->data); + + GList *last = g_list_last(priv->points); + float *lastData = last->data; + + priv->points = g_list_delete_link(priv->points, last); + priv->points = g_list_prepend(priv->points, lastData); + + fp[0] = 1.0f * priv->out / priv->max; + fp[1] = 1.0f * priv->in / priv->max; + + trg_strlspeed(speed, (gint64)(priv->out/1024)); + labelMarkup = g_markup_printf_escaped("Outgoing: %s", speed); + gtk_label_set_markup(GTK_LABEL(priv->label_out), labelMarkup); + g_free(labelMarkup); + + trg_strlspeed(speed, (gint64)(priv->in/1024)); + labelMarkup = g_markup_printf_escaped("Incoming: %s", speed); + gtk_label_set_markup(GTK_LABEL(priv->label_in), labelMarkup); + g_free(labelMarkup); + + max = MAX(priv->in, priv->out); + priv->values[priv->cur] = max; + priv->cur = (priv->cur + 1) % GRAPH_NUM_POINTS; + + if (max >= priv->max) + new_max = max; + else + new_max = get_max_value_element(g); + + bak_max = new_max; + new_max = 1.1 * new_max; + new_max = MAX(new_max, 1024U); + pow2 = floor(log2(new_max)); + base10 = pow2 / 10; + coef10 = ceil(new_max / (double) (1UL << (base10 * 10))); + factor10 = pow(10.0, floor(log10(coef10))); + coef10 = ceil(coef10 / (double) (factor10)) * factor10; + + num_bars = trg_torrent_graph_get_num_bars(g); + + if (coef10 % num_bars != 0) + coef10 = coef10 + (num_bars - coef10 % num_bars); + + new_max = coef10 * (1UL << (base10 * 10)); + + if (bak_max > new_max) { + new_max = bak_max; + } + + if ((0.8 * priv->max) < new_max && new_max <= priv->max) + return; + + scale = 1.0f * priv->max / new_max; + + for (li = priv->points; li != NULL; li = g_list_next(li)) { + float *fp = (float *) li->data; + if (fp[0] >= 0.0f) { + fp[0] *= scale; + fp[1] *= scale; + } + } + + priv->max = new_max; + + trg_torrent_graph_clear_background(g); +} + +static GObject *trg_torrent_graph_constructor(GType type, + guint + n_construct_properties, + GObjectConstructParam * + construct_params) +{ + GObject *object; + TrgTorrentGraphPrivate *priv; + GtkWidget *hbox; + int i; + + object = + G_OBJECT_CLASS + (trg_torrent_graph_parent_class)->constructor(type, + n_construct_properties, + construct_params); + priv = TRG_TORRENT_GRAPH_GET_PRIVATE(object); + + priv->draw_width = 0; + priv->draw_height = 0; + priv->render_counter = 0; + priv->graph_dely = 0; + priv->real_draw_height = 0; + priv->graph_delx = 0.0; + priv->graph_buffer_offset = 0; + priv->disp = NULL; + priv->gc = NULL; + priv->background = NULL; + priv->timer_index = 0; + priv->draw = FALSE; + + priv->fontsize = 8.0; + priv->frames_per_unit = 10; + priv->rmargin = 3.5 * priv->fontsize; + priv->indent = 24.0; + priv->out = 0; + priv->in = 0; + priv->cur = 0; + + priv->speed = 1000; + priv->max = 1024; + + hbox = gtk_hbox_new(FALSE, 0); + + priv->label_in = gtk_label_new(NULL); + priv->label_out = gtk_label_new(NULL); + + gtk_box_pack_start(GTK_BOX(hbox), priv->label_in, FALSE, FALSE, 65); + gtk_box_pack_start(GTK_BOX(hbox), priv->label_out, FALSE, FALSE, 0); + + gtk_box_pack_start(GTK_BOX(object), hbox, FALSE, FALSE, 2); + + gdk_color_parse(GRAPH_OUT_COLOR, &priv->colors[0]); + gdk_color_parse(GRAPH_IN_COLOR, &priv->colors[1]); + + priv->timer_index = 0; + priv->render_counter = (priv->frames_per_unit - 1); + priv->draw = FALSE; + + gtk_box_set_homogeneous(GTK_BOX(object), FALSE); + + gtk_widget_set_size_request(GTK_WIDGET(object), -1, GRAPH_MIN_HEIGHT); + + priv->disp = gtk_drawing_area_new(); + g_signal_connect(G_OBJECT(priv->disp), "expose_event", + G_CALLBACK(trg_torrent_graph_expose), object); + g_signal_connect(G_OBJECT(priv->disp), "configure_event", + G_CALLBACK(trg_torrent_graph_configure), object); + + gtk_widget_set_events(priv->disp, GDK_EXPOSURE_MASK); + + gtk_box_pack_start(GTK_BOX(object), priv->disp, TRUE, TRUE, 0); + + priv->points = NULL; + for (i = 0; i < GRAPH_NUM_DATA_BLOCK_ELEMENTS; i++) { + priv->data_block[i] = -1.0f; + if (i % GRAPH_NUM_LINES == 0) + priv->points = g_list_append(priv->points, &priv->data_block[i]); + } + + return object; +} + +static void trg_torrent_graph_class_init(TrgTorrentGraphClass * klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + g_type_class_add_private(klass, sizeof(TrgTorrentGraphPrivate)); + + object_class->get_property = trg_torrent_graph_get_property; + object_class->set_property = trg_torrent_graph_set_property; + object_class->dispose = trg_torrent_graph_dispose; + object_class->constructor = trg_torrent_graph_constructor; +} + +static void trg_torrent_graph_init(TrgTorrentGraph * self) +{ +} + +TrgTorrentGraph *trg_torrent_graph_new(GtkStyle * style) +{ + GObject *obj = g_object_new(TRG_TYPE_TORRENT_GRAPH, NULL); + TrgTorrentGraphPrivate *priv = TRG_TORRENT_GRAPH_GET_PRIVATE(obj); + + priv->style = style; + + return TRG_TORRENT_GRAPH(obj); +} + +void trg_torrent_graph_draw(TrgTorrentGraph * g) +{ + TrgTorrentGraphPrivate *priv = TRG_TORRENT_GRAPH_GET_PRIVATE(g); + + gtk_widget_queue_draw(priv->disp); +} + +void trg_torrent_graph_clear_background(TrgTorrentGraph * g) +{ + TrgTorrentGraphPrivate *priv = TRG_TORRENT_GRAPH_GET_PRIVATE(g); + + if (priv->background) { + g_object_unref(priv->background); + priv->background = NULL; + } +} + + +static gboolean trg_torrent_graph_update(gpointer user_data) +{ + TrgTorrentGraph *g = TRG_TORRENT_GRAPH(user_data); + TrgTorrentGraphPrivate *priv = + TRG_TORRENT_GRAPH_GET_PRIVATE(user_data); + + if (priv->render_counter == priv->frames_per_unit - 1) + trg_torrent_graph_update_net(g); + + if (priv->draw) + trg_torrent_graph_draw(g); + + priv->render_counter++; + + if (priv->render_counter >= priv->frames_per_unit) + priv->render_counter = 0; + + return TRUE; +} + +unsigned trg_torrent_graph_get_num_bars(TrgTorrentGraph * g) +{ + TrgTorrentGraphPrivate *priv = TRG_TORRENT_GRAPH_GET_PRIVATE(g); + unsigned n; + + switch ((int) (priv->draw_height / (priv->fontsize + 14))) { + case 0: + case 1: + n = 1; + break; + case 2: + case 3: + n = 2; + break; + case 4: + n = 4; + break; + default: + n = 5; + } + + return n; +} diff --git a/src/trg-torrent-graph.c.glg b/src/trg-torrent-graph.c.glg new file mode 100644 index 0000000..9479717 --- /dev/null +++ b/src/trg-torrent-graph.c.glg @@ -0,0 +1,106 @@ +/* + * transmission-remote-gtk - Transmission RPC client for GTK + * 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 +#include + +#include "util.h" +#include "glg.h" +#include "trg-torrent-model.h" +#include "trg-torrent-graph.h" + +/*enum { + PROP_0, + PROP_SIZE_VALUE +};*/ + +G_DEFINE_TYPE(TrgTorrentGraph, trg_torrent_graph, + GLG_TYPE_LINE_GRAPH) +#define TRG_TORRENT_GRAPH_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRG_TYPE_TORRENT_GRAPH, TrgTorrentGraphPrivate)) +typedef struct _TrgTorrentGraphPrivate TrgTorrentGraphPrivate; + +struct _TrgTorrentGraphPrivate { + gint global_down_id; + gint global_up_id; +}; + +static void +trg_torrent_graph_class_init(TrgTorrentGraphClass * klass) +{ + /*GObjectClass *object_class = G_OBJECT_CLASS(klass);*/ + g_type_class_add_private(klass, sizeof(TrgTorrentGraphPrivate)); +} + +static void trg_torrent_graph_init(TrgTorrentGraph * self) +{ + +} + +void trg_torrent_graph_update(TrgTorrentGraph *g, trg_torrent_model_update_stats *global) +{ + TrgTorrentGraphPrivate *priv = TRG_TORRENT_GRAPH_GET_PRIVATE(g); + + + glg_line_graph_data_series_add_value (GLG_LINE_GRAPH(g), priv->global_down_id, (gdouble)global->downRateTotal/1024); + glg_line_graph_data_series_add_value (GLG_LINE_GRAPH(g), priv->global_up_id, (gdouble)global->upRateTotal/1024); + + glg_line_graph_redraw (GLG_LINE_GRAPH(g)); +} + +TrgTorrentGraph *trg_torrent_graph_new(void) +{ + TrgTorrentGraphPrivate *priv; + + GObject *glg = g_object_new(TRG_TYPE_TORRENT_GRAPH, + "range-tick-minor-x", 1, + "range-tick-major-x", 120, + "range-scale-minor-x", 0, + "range-scale-major-x", 120, + "range-tick-minor-y", 1, + "range-tick-major-y", 10, + "range-scale-minor-y", 0, + "range-scale-major-y", 10, + NULL); + + priv = TRG_TORRENT_GRAPH_GET_PRIVATE(glg); + + g_object_set (glg, "chart-set-elements", + GLG_GRID_LABELS_Y | GLG_GRID_LINES, NULL); + + g_object_set (glg, "series-line-width", 3, NULL); + + g_object_set (glg, + "graph-title-foreground", "blue", + "graph-scale-foreground", "blue", + "graph-chart-background", "white", + "graph-window-background", "white", + NULL); + + g_object_set (glg, "text-title-yaxis", "Speed", + "text-title-xaxis", "Time", + NULL); + + priv->global_down_id = glg_line_graph_data_series_add (GLG_LINE_GRAPH(glg), "Global Down KB/s", "green"); + priv->global_up_id = glg_line_graph_data_series_add (GLG_LINE_GRAPH(glg), "Global Up KB/s", "red"); + + glg_line_graph_redraw (GLG_LINE_GRAPH(glg)); + + return TRG_TORRENT_GRAPH(glg); +} diff --git a/src/trg-torrent-graph.h b/src/trg-torrent-graph.h new file mode 100644 index 0000000..ec9166a --- /dev/null +++ b/src/trg-torrent-graph.h @@ -0,0 +1,52 @@ +/* trg-torrent-graph.h */ + +#ifndef _TRG_TORRENT_GRAPH +#define _TRG_TORRENT_GRAPH + +#include +#include + +#include "trg-torrent-model.h" + +G_BEGIN_DECLS +#define TRG_TYPE_TORRENT_GRAPH trg_torrent_graph_get_type() +#define TRG_TORRENT_GRAPH(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), TRG_TYPE_TORRENT_GRAPH, TrgTorrentGraph)) +#define TRG_TORRENT_GRAPH_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), TRG_TYPE_TORRENT_GRAPH, TrgTorrentGraphClass)) +#define TRG_IS_TORRENT_GRAPH(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TRG_TYPE_TORRENT_GRAPH)) +#define TRG_IS_TORRENT_GRAPH_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), TRG_TYPE_TORRENT_GRAPH)) +#define TRG_TORRENT_GRAPH_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), TRG_TYPE_TORRENT_GRAPH, TrgTorrentGraphClass)) + typedef struct { + GtkVBox parent; +} TrgTorrentGraph; + +typedef struct { + GtkVBoxClass parent_class; +} TrgTorrentGraphClass; + +GType trg_torrent_graph_get_type(void); + +TrgTorrentGraph *trg_torrent_graph_new(GtkStyle * style); + +unsigned trg_torrent_graph_get_num_bars(TrgTorrentGraph * g); + +void trg_torrent_graph_clear_background(); + +void trg_torrent_graph_draw(TrgTorrentGraph * g); + +void trg_torrent_graph_start(TrgTorrentGraph * g); + +void trg_torrent_graph_stop(TrgTorrentGraph * g); + +void trg_torrent_graph_change_speed(TrgTorrentGraph * g, guint new_speed); + +void trg_torrent_graph_set_speed(TrgTorrentGraph * g, + trg_torrent_model_update_stats * stats); +void trg_torrent_graph_set_nothing(TrgTorrentGraph *g); + +G_END_DECLS +#endif /* _TRG_TORRENT_GRAPH */ diff --git a/src/trg-torrent-graph.h.glg b/src/trg-torrent-graph.h.glg new file mode 100644 index 0000000..a49cf40 --- /dev/null +++ b/src/trg-torrent-graph.h.glg @@ -0,0 +1,56 @@ +/* + * transmission-remote-gtk - Transmission RPC client for GTK + * 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_TORRENT_GRAPH_H_ +#define TRG_TORRENT_GRAPH_H_ + +#include +#include + +#include "glg.h" +#include "trg-torrent-model.h" + +G_BEGIN_DECLS +#define TRG_TYPE_TORRENT_GRAPH trg_torrent_graph_get_type() +#define TRG_TORRENT_GRAPH(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), TRG_TYPE_TORRENT_GRAPH, TrgTorrentGraph)) +#define TRG_TORRENT_GRAPH_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), TRG_TYPE_TORRENT_GRAPH, TrgTorrentGraphClass)) +#define TRG_IS_TORRENT_GRAPH(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TRG_TYPE_TORRENT_GRAPH)) +#define TRG_IS_TORRENT_GRAPH_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), TRG_TYPE_TORRENT_GRAPH)) +#define TRG_TORRENT_GRAPH_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), TRG_TYPE_TORRENT_GRAPH, TrgTorrentGraphClass)) + typedef struct { + GlgLineGraph parent; +} TrgTorrentGraph; + +typedef struct { + GlgLineGraphClass parent_class; +} TrgTorrentGraphClass; + +GType trg_torrent_graph_get_type(void); + +TrgTorrentGraph *trg_torrent_graph_new(void); +void trg_torrent_graph_update(TrgTorrentGraph *g, trg_torrent_model_update_stats *global); + +G_END_DECLS +#endif /* TRG_TORRENT_GRAPH_H_ */ diff --git a/src/trg-torrent-props-dialog.c b/src/trg-torrent-props-dialog.c index ab59120..6c8f19b 100644 --- a/src/trg-torrent-props-dialog.c +++ b/src/trg-torrent-props-dialog.c @@ -137,12 +137,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/trg-torrent-tree-view.c b/src/trg-torrent-tree-view.c index c499804..4e37dd6 100644 --- a/src/trg-torrent-tree-view.c +++ b/src/trg-torrent-tree-view.c @@ -77,9 +77,9 @@ gint get_first_selected(trg_client * client, TrgTorrentTreeView * view, selectionList = gtk_tree_selection_get_selected_rows(selection, NULL); if ((firstNode = g_list_first(selectionList)) != NULL) { - if (gtk_tree_model_get_iter(model, iter, (GtkTreePath*)firstNode->data)) { - gtk_tree_model_get(model, iter, - TORRENT_COLUMN_JSON, json, + if (gtk_tree_model_get_iter + (model, iter, (GtkTreePath *) firstNode->data)) { + gtk_tree_model_get(model, iter, TORRENT_COLUMN_JSON, json, TORRENT_COLUMN_ID, &id, TORRENT_COLUMN_UPDATESERIAL, &updateSerial, -1); @@ -89,7 +89,7 @@ gint get_first_selected(trg_client * client, TrgTorrentTreeView * view, } } - g_list_foreach (selectionList, (GFunc) gtk_tree_path_free, NULL); + g_list_foreach(selectionList, (GFunc) gtk_tree_path_free, NULL); g_list_free(selectionList); return id; diff --git a/src/trg-trackers-model.c b/src/trg-trackers-model.c index b1de3d6..3ea8254 100644 --- a/src/trg-trackers-model.c +++ b/src/trg-trackers-model.c @@ -118,7 +118,7 @@ static void trg_trackers_model_class_init(TrgTrackersModelClass * klass) } void trg_trackers_model_set_accept(TrgTrackersModel * model, - gboolean accept) + gboolean accept) { TrgTrackersModelPrivate *priv = TRG_TRACKERS_MODEL_GET_PRIVATE(model); priv->accept = accept; diff --git a/src/trg-trackers-model.h b/src/trg-trackers-model.h index 763b419..324d270 100644 --- a/src/trg-trackers-model.h +++ b/src/trg-trackers-model.h @@ -52,7 +52,7 @@ G_END_DECLS gint64 updateSerial, JsonObject * t, gboolean first); void trg_trackers_model_set_accept(TrgTrackersModel * model, - gboolean accept); + gboolean accept); gint64 trg_trackers_model_get_torrent_id(TrgTrackersModel * model); void trg_trackers_model_set_no_selection(TrgTrackersModel * model); diff --git a/src/trg-trackers-tree-view.c b/src/trg-trackers-tree-view.c index c7bb101..3621987 100644 --- a/src/trg-trackers-tree-view.c +++ b/src/trg-trackers-tree-view.c @@ -49,14 +49,13 @@ trg_trackers_tree_view_class_init(TrgTrackersTreeViewClass * klass) } static void -on_trackers_update(JsonObject * response, int status, - gpointer data) +on_trackers_update(JsonObject * response, int status, gpointer data) { - TrgTrackersTreeViewPrivate *priv = TRG_TRACKERS_TREE_VIEW_GET_PRIVATE(data); + TrgTrackersTreeViewPrivate *priv = + TRG_TRACKERS_TREE_VIEW_GET_PRIVATE(data); GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(data)); - trg_trackers_model_set_accept(TRG_TRACKERS_MODEL(model), - TRUE); + trg_trackers_model_set_accept(TRG_TRACKERS_MODEL(model), TRUE); on_generic_interactive_action(response, status, priv->win); } @@ -117,8 +116,7 @@ static void trg_tracker_announce_edited(GtkCellRendererText * renderer, g_free(icon); - dispatch_async(priv->client, req, on_trackers_update, - user_data); + dispatch_async(priv->client, req, on_trackers_update, user_data); } static void trg_tracker_announce_editing_started(GtkCellRenderer * @@ -210,13 +208,14 @@ static void delete_tracker(GtkWidget * w, gpointer data) GList *li; for (li = selectionRefs; li != NULL; li = g_list_next(li)) { - GtkTreeRowReference *rr = (GtkTreeRowReference*)li->data; + GtkTreeRowReference *rr = (GtkTreeRowReference *) li->data; GtkTreePath *path = gtk_tree_row_reference_get_path(rr); if (path != NULL) { gint64 trackerId; GtkTreeIter trackerIter; gtk_tree_model_get_iter(model, &trackerIter, path); - gtk_tree_model_get(model, &trackerIter, TRACKERCOL_ID, &trackerId, -1); + gtk_tree_model_get(model, &trackerIter, TRACKERCOL_ID, + &trackerId, -1); json_array_add_int_element(trackerIds, trackerId); gtk_list_store_remove(GTK_LIST_STORE(model), &trackerIter); gtk_tree_path_free(path); @@ -226,7 +225,8 @@ static void delete_tracker(GtkWidget * w, gpointer data) g_list_free(selectionRefs); json_array_add_int_element(torrentIds, - trg_trackers_model_get_torrent_id(TRG_TRACKERS_MODEL(model))); + trg_trackers_model_get_torrent_id + (TRG_TRACKERS_MODEL(model))); req = torrent_set(torrentIds); args = node_get_arguments(req); diff --git a/src/trg-tree-view.c b/src/trg-tree-view.c index 0bc9537..582b1d6 100644 --- a/src/trg-tree-view.c +++ b/src/trg-tree-view.c @@ -27,7 +27,7 @@ G_DEFINE_TYPE(TrgTreeView, trg_tree_view, GTK_TYPE_TREE_VIEW) -GList *trg_tree_view_get_selected_refs_list(GtkTreeView *tv) +GList *trg_tree_view_get_selected_refs_list(GtkTreeView * tv) { GtkTreeModel *model = gtk_tree_view_get_model(tv); GtkTreeSelection *selection = gtk_tree_view_get_selection(tv); @@ -36,7 +36,7 @@ GList *trg_tree_view_get_selected_refs_list(GtkTreeView *tv) selectionList = gtk_tree_selection_get_selected_rows(selection, NULL); for (li = selectionList; li != NULL; li = g_list_next(li)) { - GtkTreePath *path = (GtkTreePath*)li->data; + GtkTreePath *path = (GtkTreePath *) li->data; GtkTreeRowReference *ref = gtk_tree_row_reference_new(model, path); gtk_tree_path_free(path); refList = g_list_append(refList, ref); diff --git a/src/trg-tree-view.h b/src/trg-tree-view.h index 0c64b09..aa984a4 100644 --- a/src/trg-tree-view.h +++ b/src/trg-tree-view.h @@ -48,14 +48,13 @@ GtkWidget *trg_tree_view_new(void); G_END_DECLS #define trg_tree_view_add_column(tv, title, index) trg_tree_view_add_column_fixed_width(tv, title, index, -1) + GList * trg_tree_view_get_selected_refs_list(GtkTreeView * tv); -GList *trg_tree_view_get_selected_refs_list(GtkTreeView *tv); - -GtkCellRenderer * trg_tree_view_add_column_fixed_width(TrgTreeView * - treeview, - char *title, - int index, - int width); +GtkCellRenderer *trg_tree_view_add_column_fixed_width(TrgTreeView * + treeview, + char *title, + int index, + int width); void trg_tree_view_add_pixbuf_text_column(TrgTreeView * treeview, diff --git a/src/util.c b/src/util.c index c2f623f..02bf658 100644 --- a/src/util.c +++ b/src/util.c @@ -33,7 +33,8 @@ #include "util.h" #include "dispatch.h" -void trg_error_dialog(GtkWindow *parent, int status, JsonObject *response) +void trg_error_dialog(GtkWindow * parent, int status, + JsonObject * response) { const gchar *msg = make_error_message(response, status); GtkWidget *dialog = gtk_message_dialog_new(parent, diff --git a/src/util.h b/src/util.h index e73950b..3b63163 100644 --- a/src/util.h +++ b/src/util.h @@ -55,6 +55,7 @@ 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); +void trg_error_dialog(GtkWindow * parent, int status, + JsonObject * response); #endif /* UTIL_H_ */ -- cgit v1.2.3