From 8cc810e1fbf069f808cfe3e9598273b2f3dd8aab Mon Sep 17 00:00:00 2001 From: Alan Fitton Date: Sun, 26 Aug 2012 11:42:39 +0100 Subject: add a menu for changing sort, useful when there are no column headers in Transmission style --- src/trg-main-window.c | 2 +- src/trg-menu-bar.c | 29 ++++++++++++++-- src/trg-menu-bar.h | 3 +- src/trg-peers-tree-view.c | 2 +- src/trg-torrent-tree-view.c | 16 ++++----- src/trg-tree-view.c | 85 +++++++++++++++++++++++++++++++++++++++++++-- src/trg-tree-view.h | 12 ++++--- 7 files changed, 128 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/trg-main-window.c b/src/trg-main-window.c index 6d1925d..d8c7961 100644 --- a/src/trg-main-window.c +++ b/src/trg-main-window.c @@ -1717,7 +1717,7 @@ static TrgMenuBar *trg_main_window_menu_bar_new(TrgMainWindow * win) accel_group = gtk_accel_group_new(); - menuBar = trg_menu_bar_new(win, trg_client_get_prefs(priv->client), + menuBar = trg_menu_bar_new(win, trg_client_get_prefs(priv->client), priv->torrentTreeView, accel_group); g_object_get(menuBar, "disconnect-button", &b_disconnect, "add-button", diff --git a/src/trg-menu-bar.c b/src/trg-menu-bar.c index 338389d..955ae8e 100644 --- a/src/trg-menu-bar.c +++ b/src/trg-menu-bar.c @@ -26,6 +26,8 @@ #include "trg-prefs.h" #include "trg-torrent-graph.h" +#include "trg-tree-view.h" +#include "trg-torrent-tree-view.h" #include "trg-main-window.h" #include "trg-menu-bar.h" @@ -54,6 +56,7 @@ enum { PROP_QUIT, PROP_PREFS, PROP_MAIN_WINDOW, + PROP_TORRENT_TREE_VIEW, PROP_ACCEL_GROUP, PROP_DIR_FILTERS, PROP_TRACKER_FILTERS, @@ -114,6 +117,7 @@ struct _TrgMenuBarPrivate { GtkAccelGroup *accel_group; TrgPrefs *prefs; TrgMainWindow *main_window; + TrgTorrentTreeView *torrent_tree_view; }; void trg_menu_bar_set_supports_queues(TrgMenuBar * mb, @@ -179,6 +183,9 @@ trg_menu_bar_set_property(GObject * object, case PROP_MAIN_WINDOW: priv->main_window = g_value_get_object(value); break; + case PROP_TORRENT_TREE_VIEW: + priv->torrent_tree_view = g_value_get_object(value); + break; } } @@ -458,6 +465,10 @@ static GtkWidget *trg_menu_bar_view_menu_new(TrgMenuBar * mb) priv->mb_view_classic = trg_menu_bar_view_radio_item_new(priv->prefs, group, TRG_PREFS_KEY_STYLE, TRG_STYLE_CLASSIC, _("Classic Style")); gtk_menu_shell_append(GTK_MENU_SHELL(viewMenu), priv->mb_view_classic); + gtk_menu_shell_append(GTK_MENU_SHELL(viewMenu), + trg_tree_view_sort_menu(TRG_TREE_VIEW(priv->torrent_tree_view), + _("Sort"))); + priv->mb_view_states = trg_menu_bar_view_item_new(priv->prefs, TRG_PREFS_KEY_SHOW_STATE_SELECTOR, @@ -912,6 +923,20 @@ static void trg_menu_bar_class_init(TrgMenuBarClass * klass) | G_PARAM_STATIC_BLURB)); + g_object_class_install_property(object_class, + PROP_TORRENT_TREE_VIEW, + g_param_spec_object("torrent-tree-view", + "torrent-tree-view", + "torrent-tree-view", + TRG_TYPE_TORRENT_TREE_VIEW, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY + | + G_PARAM_STATIC_NAME + | + G_PARAM_STATIC_NICK + | + G_PARAM_STATIC_BLURB)); } static void trg_menu_bar_init(TrgMenuBar * self) @@ -919,9 +944,9 @@ static void trg_menu_bar_init(TrgMenuBar * self) } TrgMenuBar *trg_menu_bar_new(TrgMainWindow * win, TrgPrefs * prefs, - GtkAccelGroup * accel_group) + TrgTorrentTreeView *ttv, GtkAccelGroup * accel_group) { return g_object_new(TRG_TYPE_MENU_BAR, - "prefs", prefs, "mainwin", win, "accel-group", + "torrent-tree-view", ttv, "prefs", prefs, "mainwin", win, "accel-group", accel_group, NULL); } diff --git a/src/trg-menu-bar.h b/src/trg-menu-bar.h index 2c8fd18..47750f5 100644 --- a/src/trg-menu-bar.h +++ b/src/trg-menu-bar.h @@ -24,6 +24,7 @@ #include #include "trg-prefs.h" +#include "trg-torrent-tree-view.h" #include "trg-main-window.h" G_BEGIN_DECLS @@ -49,7 +50,7 @@ typedef struct { GType trg_menu_bar_get_type(void); TrgMenuBar *trg_menu_bar_new(TrgMainWindow * win, TrgPrefs * prefs, - GtkAccelGroup * accel_group); + TrgTorrentTreeView *ttv, GtkAccelGroup * accel_group); GtkWidget *trg_menu_bar_item_new(GtkMenuShell * shell, const gchar * text, const gchar * stock_id, gboolean sensitive); diff --git a/src/trg-peers-tree-view.c b/src/trg-peers-tree-view.c index d4f974d..422bca5 100644 --- a/src/trg-peers-tree-view.c +++ b/src/trg-peers-tree-view.c @@ -77,7 +77,7 @@ TrgPeersTreeView *trg_peers_tree_view_new(TrgPrefs * prefs, GObject *obj = g_object_new(TRG_TYPE_PEERS_TREE_VIEW, NULL); trg_tree_view_set_prefs(TRG_TREE_VIEW(obj), prefs); gtk_tree_view_set_model(GTK_TREE_VIEW(obj), GTK_TREE_MODEL(model)); - trg_tree_view_restore_sort(TRG_TREE_VIEW(obj), FALSE); + trg_tree_view_restore_sort(TRG_TREE_VIEW(obj), 0x00); trg_tree_view_setup_columns(TRG_TREE_VIEW(obj)); return TRG_PEERS_TREE_VIEW(obj); diff --git a/src/trg-torrent-tree-view.c b/src/trg-torrent-tree-view.c index f079e5a..d54286a 100644 --- a/src/trg-torrent-tree-view.c +++ b/src/trg-torrent-tree-view.c @@ -78,28 +78,28 @@ static void trg_torrent_tree_view_init(TrgTorrentTreeView * tttv) _("Connected"), "connected-peers", 0); trg_tree_view_reg_column(ttv, TRG_COLTYPE_NUMGTZERO, TORRENT_COLUMN_FROMPEX, _("PEX Peers"), - "from-pex", TRG_COLUMN_EXTRA); + "from-pex", TRG_COLUMN_EXTRA | TRG_COLUMN_HIDE_FROM_TOP_MENU); trg_tree_view_reg_column(ttv, TRG_COLTYPE_NUMGTZERO, TORRENT_COLUMN_FROMDHT, _("DHT Peers"), - "from-dht", TRG_COLUMN_EXTRA); + "from-dht", TRG_COLUMN_EXTRA | TRG_COLUMN_HIDE_FROM_TOP_MENU); trg_tree_view_reg_column(ttv, TRG_COLTYPE_NUMGTZERO, TORRENT_COLUMN_FROMTRACKERS, _("Tracker Peers"), "from-trackers", - TRG_COLUMN_EXTRA); + TRG_COLUMN_EXTRA | TRG_COLUMN_HIDE_FROM_TOP_MENU); trg_tree_view_reg_column(ttv, TRG_COLTYPE_NUMGTZERO, TORRENT_COLUMN_FROMLTEP, _("LTEP Peers"), - "from-ltep", TRG_COLUMN_EXTRA); + "from-ltep", TRG_COLUMN_EXTRA | TRG_COLUMN_HIDE_FROM_TOP_MENU); trg_tree_view_reg_column(ttv, TRG_COLTYPE_NUMGTZERO, TORRENT_COLUMN_FROMRESUME, _("Resumed Peers"), - "from-resume", TRG_COLUMN_EXTRA); + "from-resume", TRG_COLUMN_EXTRA | TRG_COLUMN_HIDE_FROM_TOP_MENU); trg_tree_view_reg_column(ttv, TRG_COLTYPE_NUMGTZERO, TORRENT_COLUMN_FROMINCOMING, _("Incoming Peers"), "from-incoming", - TRG_COLUMN_EXTRA); + TRG_COLUMN_EXTRA | TRG_COLUMN_HIDE_FROM_TOP_MENU); trg_tree_view_reg_column(ttv, TRG_COLTYPE_TEXT, TORRENT_COLUMN_PEER_SOURCES, _("Peers T/I/E/H/X/L/R"), "peer-sources", - TRG_COLUMN_EXTRA); + TRG_COLUMN_EXTRA | TRG_COLUMN_HIDE_FROM_TOP_MENU); trg_tree_view_reg_column(ttv, TRG_COLTYPE_SPEED, TORRENT_COLUMN_DOWNSPEED, _("Down Speed"), "down-speed", 0); @@ -282,7 +282,7 @@ TrgTorrentTreeView *trg_torrent_tree_view_new(TrgClient *tc, g_signal_connect(prefs, "pref-changed", G_CALLBACK(trg_torrent_tree_view_pref_changed), obj); - trg_tree_view_restore_sort(TRG_TREE_VIEW(obj), TRUE); + trg_tree_view_restore_sort(TRG_TREE_VIEW(obj), TRG_TREE_VIEW_SORTABLE_PARENT); return TRG_TORRENT_TREE_VIEW(obj); } diff --git a/src/trg-tree-view.c b/src/trg-tree-view.c index 42d4885..d507fc3 100644 --- a/src/trg-tree-view.c +++ b/src/trg-tree-view.c @@ -149,7 +149,7 @@ trg_column_description *trg_tree_view_reg_column(TrgTreeView * tv, gint type, gint model_column, const gchar * header, - const gchar * id, gint flags) + const gchar * id, guint flags) { TrgTreeViewPrivate *priv = TRG_TREE_VIEW_GET_PRIVATE(tv); trg_column_description *desc = g_new0(trg_column_description, 1); @@ -209,6 +209,85 @@ trg_tree_view_user_add_column_cb(GtkWidget * w, trg_tree_view_add_column_after(tv, desc, -1, col); } +static void trg_tree_view_sort_menu_item_toggled(GtkCheckMenuItem * w, gpointer data) +{ + GtkTreeSortable *model = GTK_TREE_SORTABLE(data); + trg_column_description *desc = + (trg_column_description *)g_object_get_data(G_OBJECT(w), GDATA_KEY_COLUMN_DESC); + + if (gtk_check_menu_item_get_active(w)) { + GtkSortType sortType; + gtk_tree_sortable_get_sort_column_id (model, NULL, &sortType); + gtk_tree_sortable_set_sort_column_id(model, desc->model_column, sortType); + } +} + +static void trg_tree_view_sort_menu_type_toggled(GtkCheckMenuItem * w, gpointer data) +{ + GtkTreeSortable *model = GTK_TREE_SORTABLE(data); + + if (gtk_check_menu_item_get_active(w)) { + gint sortColumn; + gint sortType = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w), "sort-type")); + gtk_tree_sortable_get_sort_column_id (model, &sortColumn, NULL); + gtk_tree_sortable_set_sort_column_id(model, sortColumn, sortType); + } +} + + +GtkWidget *trg_tree_view_sort_menu(TrgTreeView *tv, const gchar *label) +{ + TrgTreeViewPrivate *priv = TRG_TREE_VIEW_GET_PRIVATE(tv); + GtkWidget *item = gtk_menu_item_new_with_mnemonic(label); + GtkTreeModel *treeViewModel = gtk_tree_view_get_model(GTK_TREE_VIEW(tv)); + GtkTreeSortable *sortableModel = GTK_TREE_SORTABLE(gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(treeViewModel))); + GtkWidget *menu = gtk_menu_new(); + GtkWidget *b; + GList *li; + gint sort; + GtkSortType sortType; + GSList *group = NULL; + + gtk_tree_sortable_get_sort_column_id(sortableModel, &sort, &sortType); + + b = gtk_radio_menu_item_new_with_label(group, _("Ascending")); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(b), sortType == GTK_SORT_ASCENDING); + g_object_set_data(G_OBJECT(b), "sort-type", GINT_TO_POINTER(GTK_SORT_ASCENDING)); + g_signal_connect(b, "toggled", G_CALLBACK(trg_tree_view_sort_menu_type_toggled), sortableModel); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), b); + group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(b)); + b = gtk_radio_menu_item_new_with_label(group, _("Descending")); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(b), sortType == GTK_SORT_DESCENDING); + g_object_set_data(G_OBJECT(b), "sort-type", GINT_TO_POINTER(GTK_SORT_DESCENDING)); + g_signal_connect(b, "toggled", G_CALLBACK(trg_tree_view_sort_menu_type_toggled), sortableModel); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), b); + + group = NULL; + + gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new()); + + for (li = priv->columns; li; li = g_list_next(li)) { + trg_column_description *desc = + (trg_column_description *) li->data; + if (!(desc->flags & TRG_COLUMN_HIDE_FROM_TOP_MENU)) { + b = gtk_radio_menu_item_new_with_label(group, desc->header); + group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(b)); + + if (desc->model_column == sort) + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(b), TRUE); + + g_object_set_data(G_OBJECT(b), GDATA_KEY_COLUMN_DESC, desc); + g_signal_connect(b, "toggled", G_CALLBACK(trg_tree_view_sort_menu_item_toggled), sortableModel); + + gtk_menu_shell_append(GTK_MENU_SHELL(menu), b); + } + } + + gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu); + + return item; +} + static void view_popup_menu(GtkButton * button, GdkEventButton * event, GtkTreeViewColumn * column) @@ -528,7 +607,7 @@ void trg_tree_view_persist(TrgTreeView * tv, guint flags) } void -trg_tree_view_restore_sort(TrgTreeView * tv, gboolean parentIsSortable) +trg_tree_view_restore_sort(TrgTreeView * tv, guint flags) { JsonObject *props = trg_prefs_get_tree_view_props(tv); GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(tv)); @@ -540,7 +619,7 @@ trg_tree_view_restore_sort(TrgTreeView * tv, gboolean parentIsSortable) gint64 sort_type = json_object_get_int_member(props, TRG_PREFS_KEY_TV_SORT_TYPE); gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE - (parentIsSortable ? + ((flags & TRG_TREE_VIEW_SORTABLE_PARENT)? gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model)) : model), sort_col, diff --git a/src/trg-tree-view.h b/src/trg-tree-view.h index a7b2315..3f410f2 100644 --- a/src/trg-tree-view.h +++ b/src/trg-tree-view.h @@ -71,16 +71,17 @@ typedef struct { gint model_column_extra; gchar *header; gchar *id; - gint flags; - gint type; + guint flags; + guint type; GtkCellRenderer *customRenderer; GtkTreeViewColumn **out; } trg_column_description; #define TRG_COLUMN_DEFAULT 0x00 #define TRG_COLUMN_SHOWING (1 << 0) /* 0x01 */ -#define TRG_COLUMN_UNREMOVABLE (1 << 1) /* 0x02 */ +#define TRG_COLUMN_UNREMOVABLE (1 << 1) /* 0x02 */ #define TRG_COLUMN_EXTRA (1 << 2) /* 0x04 */ +#define TRG_COLUMN_HIDE_FROM_TOP_MENU (1 << 3) /* 0x08 */ #define TRG_TREE_VIEW_PERSIST_SORT (1 << 0) #define TRG_TREE_VIEW_PERSIST_LAYOUT (1 << 1) @@ -90,13 +91,14 @@ trg_column_description *trg_tree_view_reg_column(TrgTreeView * tv, gint type, gint model_column, const gchar * header, - const gchar * id, gint flags); + const gchar * id, guint flags); void trg_tree_view_setup_columns(TrgTreeView * tv); void trg_tree_view_set_prefs(TrgTreeView * tv, TrgPrefs * prefs); void trg_tree_view_persist(TrgTreeView * tv, guint flags); void trg_tree_view_remove_all_columns(TrgTreeView *tv); void trg_tree_view_restore_sort(TrgTreeView * tv, - gboolean parentIsSortable); + guint flags); +GtkWidget *trg_tree_view_sort_menu(TrgTreeView *tv, const gchar *label); gboolean trg_tree_view_is_column_showing(TrgTreeView * tv, gint index); #endif /* _TRG_TREE_VIEW_H_ */ -- cgit v1.2.3