diff options
Diffstat (limited to 'src/trg-trackers-tree-view.c')
-rw-r--r-- | src/trg-trackers-tree-view.c | 330 |
1 files changed, 199 insertions, 131 deletions
diff --git a/src/trg-trackers-tree-view.c b/src/trg-trackers-tree-view.c index 6d9bbdd..3ed4d4d 100644 --- a/src/trg-trackers-tree-view.c +++ b/src/trg-trackers-tree-view.c @@ -30,31 +30,30 @@ #include "trg-main-window.h" G_DEFINE_TYPE(TrgTrackersTreeView, trg_trackers_tree_view, - TRG_TYPE_TREE_VIEW) - + TRG_TYPE_TREE_VIEW) #define TRG_TRACKERS_TREE_VIEW_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRG_TYPE_TRACKERS_TREE_VIEW, TrgTrackersTreeViewPrivate)) - typedef struct _TrgTrackersTreeViewPrivate TrgTrackersTreeViewPrivate; struct _TrgTrackersTreeViewPrivate { trg_client *client; GtkCellRenderer *announceRenderer; + GtkTreeViewColumn *announceColumn; TrgMainWindow *win; }; static void -trg_trackers_tree_view_class_init(TrgTrackersTreeViewClass *klass) +trg_trackers_tree_view_class_init(TrgTrackersTreeViewClass * klass) { - g_type_class_add_private(klass, sizeof(TrgTrackersTreeViewPrivate)); + g_type_class_add_private(klass, sizeof(TrgTrackersTreeViewPrivate)); } static void trg_trackers_tree_view_json_id_array_foreach(GtkTreeModel * model, - GtkTreePath * - path G_GNUC_UNUSED, - GtkTreeIter * iter, - gpointer data) + GtkTreePath * + path G_GNUC_UNUSED, + GtkTreeIter * iter, + gpointer data) { JsonArray *output = (JsonArray *) data; gint64 id; @@ -65,205 +64,271 @@ trg_trackers_tree_view_json_id_array_foreach(GtkTreeModel * model, static JsonArray *trackers_build_json_id_array(TrgTrackersTreeView * tv) { GtkTreeSelection *selection = - gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)); + gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)); JsonArray *ids = json_array_new(); gtk_tree_selection_selected_foreach(selection, - (GtkTreeSelectionForeachFunc) - trg_trackers_tree_view_json_id_array_foreach, - ids); - - if (json_array_get_length(ids) < 1) - { - json_array_unref(ids); - return NULL; + (GtkTreeSelectionForeachFunc) + trg_trackers_tree_view_json_id_array_foreach, + ids); + + if (json_array_get_length(ids) < 1) { + json_array_unref(ids); + return NULL; } return ids; } -void trg_trackers_tree_view_new_connection(TrgTrackersTreeView *tv, trg_client *tc) +void trg_trackers_tree_view_new_connection(TrgTrackersTreeView * tv, + trg_client * tc) { - TrgTrackersTreeViewPrivate *priv = TRG_TRACKERS_TREE_VIEW_GET_PRIVATE(tv); - gboolean editable = trg_client_supports_tracker_edit(tc); - - g_object_set(priv->announceRenderer, "editable", editable, NULL); - g_object_set(priv->announceRenderer, "mode", editable ? GTK_CELL_RENDERER_MODE_EDITABLE : GTK_CELL_RENDERER_MODE_INERT, NULL); + TrgTrackersTreeViewPrivate *priv = + TRG_TRACKERS_TREE_VIEW_GET_PRIVATE(tv); + gboolean editable = trg_client_supports_tracker_edit(tc); + + g_object_set(priv->announceRenderer, "editable", editable, NULL); + g_object_set(priv->announceRenderer, "mode", + editable ? GTK_CELL_RENDERER_MODE_EDITABLE : + GTK_CELL_RENDERER_MODE_INERT, NULL); } -static void trg_tracker_announce_edited(GtkCellRendererText *renderer, - gchar *path, - gchar *new_text, - gpointer user_data) +static void trg_tracker_announce_edited(GtkCellRendererText * renderer, + gchar * path, + gchar * new_text, + gpointer user_data) { - TrgTrackersTreeViewPrivate *priv = TRG_TRACKERS_TREE_VIEW_GET_PRIVATE(user_data); - GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(user_data)); - gint64 torrentId = trg_trackers_model_get_torrent_id(TRG_TRACKERS_MODEL(model)); - JsonArray *torrentIds = json_array_new(); - JsonArray *modPairs = json_array_new(); - - gint64 trackerId; - JsonNode *req; - JsonObject *args; - GtkTreeIter iter; - - gtk_tree_model_get_iter_from_string(model, &iter, path); - gtk_list_store_set(GTK_LIST_STORE(model), &iter, TRACKERCOL_ANNOUNCE, new_text, -1); - gtk_tree_model_get(model, &iter, TRACKERCOL_ID, &trackerId, -1); - - json_array_add_int_element(torrentIds, torrentId); - - req = torrent_set(torrentIds); - args = node_get_arguments(req); - - json_array_add_int_element(modPairs, trackerId); - json_array_add_string_element(modPairs, new_text); + TrgTrackersTreeViewPrivate *priv = + TRG_TRACKERS_TREE_VIEW_GET_PRIVATE(user_data); + GtkTreeModel *model = + gtk_tree_view_get_model(GTK_TREE_VIEW(user_data)); + gint64 torrentId = + trg_trackers_model_get_torrent_id(TRG_TRACKERS_MODEL(model)); + JsonArray *torrentIds = json_array_new(); + JsonArray *trackerModifiers = json_array_new(); + + gint64 trackerId; + JsonNode *req; + JsonObject *args; + GtkTreeIter iter; + gchar *icon; + + gtk_tree_model_get_iter_from_string(model, &iter, path); + gtk_list_store_set(GTK_LIST_STORE(model), &iter, TRACKERCOL_ANNOUNCE, + new_text, -1); + gtk_tree_model_get(model, &iter, TRACKERCOL_ID, &trackerId, + TRACKERCOL_ICON, &icon, -1); + + json_array_add_int_element(torrentIds, torrentId); + + req = torrent_set(torrentIds); + args = node_get_arguments(req); + + if (g_strcmp0(icon, GTK_STOCK_ADD) == 0) { + json_array_add_string_element(trackerModifiers, new_text); + json_object_set_array_member(args, "trackerAdd", trackerModifiers); + } else { + json_array_add_int_element(trackerModifiers, trackerId); + json_array_add_string_element(trackerModifiers, new_text); + json_object_set_array_member(args, "trackerReplace", + trackerModifiers); + } - json_object_set_array_member(args, "trackerReplace", modPairs); + g_free(icon); - trg_trackers_model_set_update_barrier(TRG_TRACKERS_MODEL(model), priv->client->updateSerial+1); + trg_trackers_model_set_update_barrier(TRG_TRACKERS_MODEL(model), + priv->client->updateSerial + 1); - dispatch_async(priv->client, req, on_generic_interactive_action, priv->win); + dispatch_async(priv->client, req, on_generic_interactive_action, + priv->win); } -static void trg_tracker_announce_editing_started(GtkCellRenderer *renderer, - GtkCellEditable *editable, - gchar *path, - gpointer user_data) +static void trg_tracker_announce_editing_started(GtkCellRenderer * + renderer, + GtkCellEditable * + editable, gchar * path, + gpointer user_data) { - TrgTrackersModel *model = TRG_TRACKERS_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(user_data))); - trg_trackers_model_set_update_barrier(model, TRACKERS_UPDATE_BARRIER_FULL); + TrgTrackersModel *model = + TRG_TRACKERS_MODEL(gtk_tree_view_get_model + (GTK_TREE_VIEW(user_data))); + trg_trackers_model_set_update_barrier(model, + TRACKERS_UPDATE_BARRIER_FULL); } -static void trg_tracker_announce_editing_canceled(GtkWidget *w, gpointer data) +static void trg_tracker_announce_editing_canceled(GtkWidget * w, + gpointer data) { - TrgTrackersTreeViewPrivate *priv = TRG_TRACKERS_TREE_VIEW_GET_PRIVATE(data); - TrgTrackersModel *model = TRG_TRACKERS_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(data))); + TrgTrackersTreeViewPrivate *priv = + TRG_TRACKERS_TREE_VIEW_GET_PRIVATE(data); + TrgTrackersModel *model = + TRG_TRACKERS_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(data))); - trg_trackers_model_set_update_barrier(model, priv->client->updateSerial+1); + trg_trackers_model_set_update_barrier(model, + priv->client->updateSerial + 1); } static void trg_trackers_tree_view_init(TrgTrackersTreeView * self) { - TrgTrackersTreeViewPrivate *priv = TRG_TRACKERS_TREE_VIEW_GET_PRIVATE(self); + TrgTrackersTreeViewPrivate *priv = + TRG_TRACKERS_TREE_VIEW_GET_PRIVATE(self); trg_tree_view_add_pixbuf_text_column(TRG_TREE_VIEW(self), - TRACKERCOL_ICON, - TRACKERCOL_TIER, "Tier", -1); - - priv->announceRenderer = trg_tree_view_add_column(TRG_TREE_VIEW(self), "Announce URL", - TRACKERCOL_ANNOUNCE); - g_signal_connect(priv->announceRenderer, "edited", G_CALLBACK(trg_tracker_announce_edited), self); - g_signal_connect(priv->announceRenderer, "editing-canceled", G_CALLBACK(trg_tracker_announce_editing_canceled), self); - g_signal_connect(priv->announceRenderer, "editing-started", G_CALLBACK(trg_tracker_announce_editing_started), self); + TRACKERCOL_ICON, + TRACKERCOL_TIER, "Tier", -1); + + priv->announceRenderer = gtk_cell_renderer_text_new(); + g_signal_connect(priv->announceRenderer, "edited", + G_CALLBACK(trg_tracker_announce_edited), self); + g_signal_connect(priv->announceRenderer, "editing-canceled", + G_CALLBACK(trg_tracker_announce_editing_canceled), + self); + g_signal_connect(priv->announceRenderer, "editing-started", + G_CALLBACK(trg_tracker_announce_editing_started), + self); + + priv->announceColumn = + gtk_tree_view_column_new_with_attributes("Announce URL", + priv->announceRenderer, + "text", + TRACKERCOL_ANNOUNCE, + NULL); + + trg_tree_view_std_column_setup(priv->announceColumn, + TRACKERCOL_ANNOUNCE, -1); + gtk_tree_view_append_column(GTK_TREE_VIEW(self), priv->announceColumn); trg_tree_view_add_column(TRG_TREE_VIEW(self), "Scrape URL", - TRACKERCOL_SCRAPE); + TRACKERCOL_SCRAPE); } -static void add_tracker(GtkWidget *w, gpointer data) +static void add_tracker(GtkWidget * w, gpointer data) { - GtkTreeView *tv = GTK_TREE_VIEW(data); - GtkTreeModel *model = gtk_tree_view_get_model(tv); - GtkTreeIter iter; + GtkTreeView *tv = GTK_TREE_VIEW(data); + TrgTrackersTreeViewPrivate *priv = + TRG_TRACKERS_TREE_VIEW_GET_PRIVATE(data); + GtkTreeModel *model = gtk_tree_view_get_model(tv); + GtkTreeIter iter; + GtkTreePath *path; - gtk_list_store_append(GTK_LIST_STORE(model), &iter); + gtk_list_store_append(GTK_LIST_STORE(model), &iter); + gtk_list_store_set(GTK_LIST_STORE(model), &iter, TRACKERCOL_ICON, + GTK_STOCK_ADD, -1); + + path = gtk_tree_model_get_path(model, &iter); + gtk_tree_view_set_cursor(tv, path, priv->announceColumn, TRUE); + gtk_tree_path_free(path); } -static void delete_tracker(GtkWidget *w, gpointer data) +static void delete_tracker(GtkWidget * w, gpointer data) { - TrgTrackersTreeViewPrivate *priv = TRG_TRACKERS_TREE_VIEW_GET_PRIVATE(data); - TrgTrackersTreeView *tv = TRG_TRACKERS_TREE_VIEW(data); - TrgTrackersModel *model = TRG_TRACKERS_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(data))); - - JsonArray *trackerIds, *torrentIds; - JsonNode *req; - JsonObject *args; + TrgTrackersTreeViewPrivate *priv = + TRG_TRACKERS_TREE_VIEW_GET_PRIVATE(data); + TrgTrackersTreeView *tv = TRG_TRACKERS_TREE_VIEW(data); + TrgTrackersModel *model = + TRG_TRACKERS_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(data))); - if ((trackerIds = trackers_build_json_id_array(tv)) == NULL) - return; + JsonArray *trackerIds, *torrentIds; + JsonNode *req; + JsonObject *args; - torrentIds = json_array_new(); - json_array_add_int_element(torrentIds, trg_trackers_model_get_torrent_id(model)); + if ((trackerIds = trackers_build_json_id_array(tv)) == NULL) + return; - req = torrent_set(torrentIds); + torrentIds = json_array_new(); + json_array_add_int_element(torrentIds, + trg_trackers_model_get_torrent_id(model)); - args = node_get_arguments(req); + req = torrent_set(torrentIds); + args = node_get_arguments(req); - json_object_set_array_member(args, "trackerRemove", trackerIds); + json_object_set_array_member(args, "trackerRemove", trackerIds); - dispatch_async(priv->client, req, on_generic_interactive_action, priv->win); + dispatch_async(priv->client, req, on_generic_interactive_action, + priv->win); } static void view_popup_menu_add_only(GtkWidget * treeview, GdkEventButton * event, - gpointer data G_GNUC_UNUSED) + gpointer data G_GNUC_UNUSED) { GtkWidget *menu, *menuitem; menu = gtk_menu_new(); - menuitem = trg_menu_bar_item_new(GTK_MENU_SHELL(menu), "Add", GTK_STOCK_ADD, TRUE); - g_signal_connect(menuitem, "activate", G_CALLBACK(add_tracker), treeview); + menuitem = + trg_menu_bar_item_new(GTK_MENU_SHELL(menu), "Add", GTK_STOCK_ADD, + TRUE); + g_signal_connect(menuitem, "activate", G_CALLBACK(add_tracker), + treeview); gtk_widget_show_all(menu); gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, - (event != NULL) ? event->button : 0, - gdk_event_get_time((GdkEvent *) event)); + (event != NULL) ? event->button : 0, + gdk_event_get_time((GdkEvent *) event)); } static void view_popup_menu(GtkWidget * treeview, GdkEventButton * event, - gpointer data G_GNUC_UNUSED) + gpointer data G_GNUC_UNUSED) { GtkWidget *menu, *menuitem; menu = gtk_menu_new(); - menuitem = trg_menu_bar_item_new(GTK_MENU_SHELL(menu), "Delete", GTK_STOCK_DELETE, TRUE); - g_signal_connect(menuitem, "activate", G_CALLBACK(delete_tracker), treeview); + menuitem = + trg_menu_bar_item_new(GTK_MENU_SHELL(menu), "Delete", + GTK_STOCK_DELETE, TRUE); + g_signal_connect(menuitem, "activate", G_CALLBACK(delete_tracker), + treeview); - menuitem = trg_menu_bar_item_new(GTK_MENU_SHELL(menu), "Add", GTK_STOCK_ADD, TRUE); - g_signal_connect(menuitem, "activate", G_CALLBACK(add_tracker), treeview); + menuitem = + trg_menu_bar_item_new(GTK_MENU_SHELL(menu), "Add", GTK_STOCK_ADD, + TRUE); + g_signal_connect(menuitem, "activate", G_CALLBACK(add_tracker), + treeview); gtk_widget_show_all(menu); gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, - (event != NULL) ? event->button : 0, - gdk_event_get_time((GdkEvent *) event)); + (event != NULL) ? event->button : 0, + gdk_event_get_time((GdkEvent *) event)); } static gboolean view_onButtonPressed(GtkWidget * treeview, GdkEventButton * event, - gpointer userdata) + gpointer userdata) { - TrgTrackersTreeViewPrivate *priv = TRG_TRACKERS_TREE_VIEW_GET_PRIVATE(treeview); - TrgTrackersModel *model = TRG_TRACKERS_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeview))); + TrgTrackersTreeViewPrivate *priv = + TRG_TRACKERS_TREE_VIEW_GET_PRIVATE(treeview); + TrgTrackersModel *model = + TRG_TRACKERS_MODEL(gtk_tree_view_get_model + (GTK_TREE_VIEW(treeview))); GtkTreeSelection *selection; GtkTreePath *path; if (!trg_client_supports_tracker_edit(priv->client)) - return FALSE; + return FALSE; if (event->type == GDK_BUTTON_PRESS && event->button == 3) { - selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); - - if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(treeview), - (gint) event->x, - (gint) event->y, &path, - NULL, NULL, NULL)) { - if (!gtk_tree_selection_path_is_selected(selection, path)) { - gtk_tree_selection_unselect_all(selection); - gtk_tree_selection_select_path(selection, path); - } - gtk_tree_path_free(path); - - view_popup_menu(treeview, event, userdata); - return TRUE; - } else if (trg_trackers_model_get_torrent_id(model) >= 0) { - view_popup_menu_add_only(treeview, event, userdata); - } + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); + + if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(treeview), + (gint) event->x, + (gint) event->y, &path, + NULL, NULL, NULL)) { + if (!gtk_tree_selection_path_is_selected(selection, path)) { + gtk_tree_selection_unselect_all(selection); + gtk_tree_selection_select_path(selection, path); + } + gtk_tree_path_free(path); + + view_popup_menu(treeview, event, userdata); + return TRUE; + } else if (trg_trackers_model_get_torrent_id(model) >= 0) { + view_popup_menu_add_only(treeview, event, userdata); + } } return FALSE; @@ -275,15 +340,18 @@ static gboolean view_onPopupMenu(GtkWidget * treeview, gpointer userdata) return TRUE; } -TrgTrackersTreeView *trg_trackers_tree_view_new(TrgTrackersModel * model, trg_client *client, TrgMainWindow *win) +TrgTrackersTreeView *trg_trackers_tree_view_new(TrgTrackersModel * model, + trg_client * client, + TrgMainWindow * win) { GObject *obj = g_object_new(TRG_TYPE_TRACKERS_TREE_VIEW, NULL); - TrgTrackersTreeViewPrivate *priv = TRG_TRACKERS_TREE_VIEW_GET_PRIVATE(obj); + TrgTrackersTreeViewPrivate *priv = + TRG_TRACKERS_TREE_VIEW_GET_PRIVATE(obj); g_signal_connect(obj, "button-press-event", - G_CALLBACK(view_onButtonPressed), NULL); + G_CALLBACK(view_onButtonPressed), NULL); g_signal_connect(obj, "popup-menu", G_CALLBACK(view_onPopupMenu), - NULL); + NULL); gtk_tree_view_set_model(GTK_TREE_VIEW(obj), GTK_TREE_MODEL(model)); priv->client = client; |