[gnome-commander: 1/2] Replace directly used deprecated widget GtkCList with GtkTreeView+GtkListStore




commit 256d8f301992e9d1dda2c1b08770466f78fe386c
Author: Roman Pauer <roman pauer gmail com>
Date:   Mon Aug 29 13:20:53 2022 +0200

    Replace directly used deprecated widget GtkCList with GtkTreeView+GtkListStore

 libgcmd/libgcmd-widget-factory.cc       |  74 ++++++---
 libgcmd/libgcmd-widget-factory.h        |  14 +-
 src/dialogs/gnome-cmd-options-dialog.cc | 282 ++++++++++++++++++++------------
 src/plugin_manager.cc                   | 171 +++++++++----------
 4 files changed, 333 insertions(+), 208 deletions(-)
---
diff --git a/libgcmd/libgcmd-widget-factory.cc b/libgcmd/libgcmd-widget-factory.cc
index 9cd4e525..7e859b1f 100644
--- a/libgcmd/libgcmd-widget-factory.cc
+++ b/libgcmd/libgcmd-widget-factory.cc
@@ -477,9 +477,9 @@ GtkWidget *create_file_chooser_button (GtkWidget *parent, const gchar *name, con
 }
 
 
-GtkWidget *create_clist (GtkWidget *parent, const gchar *name, gint cols, gint rowh, GtkSignalFunc 
on_row_selected, GtkSignalFunc on_row_moved)
+GtkWidget *create_treeview (GtkWidget *parent, const gchar *name, GtkTreeModel *model, gint rowh, 
GtkSignalFunc on_selection_changed, GtkSignalFunc on_rows_reordered)
 {
-    GtkWidget *sw, *clist;
+    GtkWidget *sw, *view;
 
     sw = gtk_scrolled_window_new (nullptr, nullptr);
     g_object_ref (sw);
@@ -487,28 +487,64 @@ GtkWidget *create_clist (GtkWidget *parent, const gchar *name, gint cols, gint r
     gtk_widget_show (sw);
     gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
-    clist = gtk_clist_new (cols);
-    g_object_ref (clist);
-    g_object_set_data (G_OBJECT (sw), "clist", clist);
-    g_object_set_data_full (G_OBJECT (parent), name, clist, g_object_unref);
-    gtk_widget_show (clist);
-    gtk_clist_set_row_height (GTK_CLIST (clist), rowh);
-    gtk_container_add (GTK_CONTAINER (sw), clist);
-    gtk_clist_column_titles_show (GTK_CLIST (clist));
-
-    if (on_row_selected)
-        g_signal_connect (clist, "select-row", G_CALLBACK (on_row_selected), parent);
-    if (on_row_moved)
-        g_signal_connect (clist, "row-move", G_CALLBACK (on_row_moved), parent);
+    view = gtk_tree_view_new_with_model (model);
+    g_object_ref (view);
+    g_object_set_data (G_OBJECT (sw), "view", view);
+    g_object_set_data (G_OBJECT (sw), "rowh", GINT_TO_POINTER (rowh));
+    g_object_set_data_full (G_OBJECT (parent), name, view, g_object_unref);
+    gtk_tree_view_set_fixed_height_mode (GTK_TREE_VIEW (view), TRUE);
+    gtk_tree_view_set_headers_clickable (GTK_TREE_VIEW (view), FALSE);
+    gtk_widget_show (view);
+    gtk_container_add (GTK_CONTAINER (sw), view);
+
+    g_object_unref (model);
+
+    GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
+    gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
+
+    if (on_selection_changed)
+        g_signal_connect (selection, "changed", G_CALLBACK (on_selection_changed), parent);
+    if (on_rows_reordered)
+        g_signal_connect (model, "rows-reordered", G_CALLBACK (on_rows_reordered), parent);
     return sw;
 }
 
 
-void create_clist_column (GtkWidget *sw, gint col, gint width, const gchar *label)
+void create_treeview_column (GtkWidget *sw, gint col, gint width, const gchar *label)
 {
-    GtkWidget *clist = (GtkWidget *) g_object_get_data (G_OBJECT (sw), "clist");
-    gtk_clist_set_column_width (GTK_CLIST (clist), col, width);
-    gtk_clist_set_column_title (GTK_CLIST (clist), col, label);
+    GtkTreeView *view = GTK_TREE_VIEW (g_object_get_data (G_OBJECT (sw), "view"));
+    gint rowh = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (sw), "rowh"));
+    GtkTreeModel *model = gtk_tree_view_get_model (view);
+
+    GtkCellRenderer *renderer;
+    const gchar *attribute;
+    GType type = gtk_tree_model_get_column_type (model, col);
+    switch (type)
+    {
+        case G_TYPE_STRING:
+            renderer = gtk_cell_renderer_text_new ();
+            attribute = "text";
+            break;
+        default:
+            if (type == GDK_TYPE_PIXBUF)
+            {
+                renderer = gtk_cell_renderer_pixbuf_new ();
+                attribute = "pixbuf";
+                break;
+            }
+            return;
+    }
+
+    gtk_cell_renderer_set_fixed_size (renderer, -1, rowh);
+
+    GtkTreeViewColumn *column = gtk_tree_view_column_new ();
+    gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
+    gtk_tree_view_column_set_fixed_width (column, width);
+    gtk_tree_view_column_set_resizable (column, TRUE);
+    gtk_tree_view_column_set_title (column, label);
+    gtk_tree_view_column_pack_start (column, renderer, TRUE);
+    gtk_tree_view_column_add_attribute (column, renderer, attribute, col);
+    gtk_tree_view_insert_column (view, column, col);
 }
 
 
diff --git a/libgcmd/libgcmd-widget-factory.h b/libgcmd/libgcmd-widget-factory.h
index 6da996fe..33e7e1a5 100644
--- a/libgcmd/libgcmd-widget-factory.h
+++ b/libgcmd/libgcmd-widget-factory.h
@@ -113,9 +113,9 @@ GtkWidget *create_directory_chooser_button (GtkWidget *parent, const gchar *name
 
 GtkWidget *create_file_chooser_button (GtkWidget *parent, const gchar *name, const gchar *value);
 
-GtkWidget *create_clist (GtkWidget *parent, const gchar *name, gint cols, gint rowh, GtkSignalFunc 
on_row_selected, GtkSignalFunc on_row_moved);
+GtkWidget *create_treeview (GtkWidget *parent, const gchar *name, GtkTreeModel *model, gint rowh, 
GtkSignalFunc on_selection_changed, GtkSignalFunc on_rows_reordered);
 
-void create_clist_column (GtkWidget *sw, gint col, gint width, const gchar *label);
+void create_treeview_column (GtkWidget *sw, gint col, gint width, const gchar *label);
 
 GtkWidget *create_vbuttonbox (GtkWidget *parent);
 
@@ -176,4 +176,14 @@ inline GtkWidget *gtk_tree_view_column_get_button (GtkTreeViewColumn *tree_colum
 {
     return tree_column->button;
 }
+
+inline gboolean gtk_tree_model_iter_previous (GtkTreeModel *tree_model, GtkTreeIter *iter)
+{
+    GtkTreePath *path = gtk_tree_model_get_path (tree_model, iter);
+    gboolean result = gtk_tree_path_prev (path);
+    if (result)
+        result = gtk_tree_model_get_iter (tree_model, iter, path);
+    gtk_tree_path_free (path);
+    return result;
+}
 #endif
diff --git a/src/dialogs/gnome-cmd-options-dialog.cc b/src/dialogs/gnome-cmd-options-dialog.cc
index 79e63296..993c1ec5 100644
--- a/src/dialogs/gnome-cmd-options-dialog.cc
+++ b/src/dialogs/gnome-cmd-options-dialog.cc
@@ -34,8 +34,8 @@ using namespace std;
 GtkWidget *create_filter_tab (GtkWidget *parent, GnomeCmdData::Options &cfg);
 GtkWidget *create_font_picker (GtkWidget *parent, const gchar *name);
 GtkWidget *create_tabs_tab (GtkWidget *parent, GnomeCmdData::Options &cfg);
-void add_app_to_list (GtkCList *clist, GnomeCmdApp *app);
-void add_device_to_list (GtkCList *clist, GnomeCmdConDevice *dev);
+void add_app_to_list (GtkTreeView *view, GnomeCmdApp *app);
+void add_device_to_list (GtkTreeView *view, GnomeCmdConDevice *dev);
 void get_device_dialog_values (GtkWidget *dialog, gchar **alias, gchar **device_utf8, gchar **mountp_utf8, 
gchar **icon_path);
 void store_confirmation_options (GtkWidget *dialog, GnomeCmdData::Options &cfg);
 void store_devices_options (GtkWidget *dialog, GnomeCmdData::Options &cfg);
@@ -45,8 +45,8 @@ void store_general_options (GtkWidget *dialog, GnomeCmdData::Options &cfg);
 void store_layout_options (GtkWidget *dialog, GnomeCmdData::Options &cfg);
 void store_programs_options (GtkWidget *dialog, GnomeCmdData::Options &cfg);
 void store_tabs_options (GtkWidget *dialog, GnomeCmdData::Options &cfg);
-void update_app_in_list (GtkCList *clist, GnomeCmdApp *app);
-void update_device_in_list (GtkCList *clist, GnomeCmdConDevice *dev, gchar *alias, gchar *device_fn, gchar 
*mountp, gchar *icon_path);
+void update_app_in_list (GtkTreeView *view, GnomeCmdApp *app);
+void update_device_in_list (GtkTreeView *view, GnomeCmdConDevice *dev, gchar *alias, gchar *device_fn, gchar 
*mountp, gchar *icon_path);
 
 GtkWidget *create_font_picker (GtkWidget *parent, const gchar *name)
 {
@@ -1321,33 +1321,47 @@ void store_filter_options (GtkWidget *dialog, GnomeCmdData::Options &cfg)
  *
  **********************************************************************/
 
-void add_app_to_list (GtkCList *clist, GnomeCmdApp *app)
+void add_app_to_list (GtkTreeView *view, GnomeCmdApp *app)
 {
-    gchar *text[3];
+    GtkListStore *store = GTK_LIST_STORE (gtk_tree_view_get_model (view));
+    GtkTreeIter iter;
 
-    text[0] = NULL;
-    text[1] = (gchar *) gnome_cmd_app_get_name (app);
-    text[2] = (gchar *) gnome_cmd_app_get_command (app);
-
-    gint row = gtk_clist_append (GTK_CLIST (clist), text);
     GnomeCmdPixmap *pm = gnome_cmd_app_get_pixmap (app);
 
-    if (pm)
-        gtk_clist_set_pixmap (GTK_CLIST (clist), row, 0, pm->pixmap, pm->mask);
-
-    gtk_clist_set_row_data (GTK_CLIST (clist), row, app);
+    gtk_list_store_append (store, &iter);
+    gtk_list_store_set (store, &iter,
+                        0, pm ? pm->pixbuf : nullptr,
+                        1, (gchar *) gnome_cmd_app_get_name (app),
+                        2, (gchar *) gnome_cmd_app_get_command (app),
+                        3, app,
+                        -1);
 }
 
 
-void update_app_in_list (GtkCList *clist, GnomeCmdApp *app)
+void update_app_in_list (GtkTreeView *view, GnomeCmdApp *app)
 {
-    gint row = gtk_clist_find_row_from_data (clist, app);
     GnomeCmdPixmap *pm = gnome_cmd_app_get_pixmap (app);
 
-    if (pm)
-        gtk_clist_set_pixmap (GTK_CLIST (clist), row, 0, pm->pixmap, pm->mask);
+    GtkTreeModel *model = gtk_tree_view_get_model (view);
+    GtkTreeIter iter;
+    GnomeCmdApp *row_app;
 
-    gtk_clist_set_text (clist, row, 1, gnome_cmd_app_get_name (app));
+    if (gtk_tree_model_get_iter_first (model, &iter))
+    {
+        do
+        {
+            gtk_tree_model_get (model, &iter, 3, &row_app, -1);
+
+            if (row_app == app)
+            {
+                gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+                                    0, pm ? pm->pixbuf : nullptr,
+                                    1, (gchar *) gnome_cmd_app_get_name (app),
+                                    -1);
+                break;
+            }
+        } while (gtk_tree_model_iter_next (model, &iter));
+    }
 }
 
 
@@ -1417,7 +1431,7 @@ static void on_add_app_dialog_ok (GtkButton *button, GtkWidget *dialog)
     gchar *name, *cmd, *icon_path, *pattern_string;
 
     GtkWidget *options_dialog = lookup_widget (dialog, "options_dialog");
-    GtkWidget *clist = lookup_widget (options_dialog, "app_clist");
+    GtkWidget *view = lookup_widget (options_dialog, "app_view");
 
     get_app_dialog_values (dialog, &name, &cmd, &icon_path,
                            &target, &pattern_string,
@@ -1436,7 +1450,7 @@ static void on_add_app_dialog_ok (GtkButton *button, GtkWidget *dialog)
                                                       pattern_string,
                                                       handles_uris, handles_multiple, requires_terminal, 
nullptr);
     gnome_cmd_data.options.add_fav_app(app);
-    add_app_to_list (GTK_CLIST (clist), app);
+    add_app_to_list (GTK_TREE_VIEW (view), app);
     gtk_widget_destroy (dialog);
 
     g_free (icon_path);
@@ -1450,7 +1464,7 @@ static void on_edit_app_dialog_ok (GtkButton *button, GtkWidget *dialog)
     gchar *name, *cmd, *icon_path, *pattern_string;
 
     GtkWidget *options_dialog = lookup_widget (dialog, "options_dialog");
-    GtkWidget *clist = lookup_widget (options_dialog, "app_clist");
+    GtkWidget *view = lookup_widget (options_dialog, "app_view");
 
     get_app_dialog_values (dialog, &name, &cmd, &icon_path,
                            &target, &pattern_string,
@@ -1470,7 +1484,7 @@ static void on_edit_app_dialog_ok (GtkButton *button, GtkWidget *dialog)
     gnome_cmd_app_set_handles_multiple (app, handles_multiple);
     gnome_cmd_app_set_requires_terminal (app, requires_terminal);
 
-    update_app_in_list (GTK_CLIST (clist), app);
+    update_app_in_list (GTK_TREE_VIEW (view), app);
     gtk_widget_destroy (dialog);
 
     g_free (icon_path);
@@ -1604,30 +1618,39 @@ static void on_app_edit (GtkWidget *button, GtkWidget *parent)
 }
 
 
-static void on_app_selected (GtkCList *clist, gint row, gint column, GdkEventButton *event, GtkWidget 
*parent)
+static void on_app_selection_changed (GtkTreeSelection *selection, GtkWidget *parent)
 {
-    GnomeCmdApp *app = (GnomeCmdApp *) gtk_clist_get_row_data (clist, row);
+    GtkTreeModel *model;
+    GtkTreeIter iter;
+    GnomeCmdApp *app = nullptr;
+
+    if (gtk_tree_selection_get_selected (selection, &model, &iter))
+        gtk_tree_model_get (model, &iter, 3, &app, -1);
+
     g_object_set_data (G_OBJECT (parent), "selected_app", app);
 
-    gtk_widget_set_sensitive (lookup_widget (parent, "remove_app_button"), TRUE);
-    gtk_widget_set_sensitive (lookup_widget (parent, "edit_app_button"), TRUE);
+    gtk_widget_set_sensitive (lookup_widget (parent, "remove_app_button"), app != nullptr);
+    gtk_widget_set_sensitive (lookup_widget (parent, "edit_app_button"), app != nullptr);
 }
 
 
-static void on_app_moved (GtkCList *clist, gint arg1, gint arg2, GtkWidget *frame)
+static void on_app_reordered (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gint *new_order, 
GtkWidget *frame)
 {
+    gint row;
+
+    for (row = 0; new_order[row] == row; row++); // find first difference in order
+
     GList *apps = gnome_cmd_data.options.fav_apps;
 
     if (!apps
-        || MAX (arg1, arg2) >= (gint) g_list_length (apps) // cast will only be problematic for incredibly 
large lists
-        || MIN (arg1, arg2) < 0
-        || arg1 == arg2)
+        || MAX (row, new_order[row]) >= (gint) g_list_length (apps) // cast will only be problematic for 
incredibly large lists
+        || MIN (row, new_order[row]) < 0)
         return;
 
-    gpointer data = g_list_nth_data (apps, arg1);
+    gpointer data = g_list_nth_data (apps, row);
     apps = g_list_remove (apps, data);
 
-    apps = g_list_insert (apps, data, arg2);
+    apps = g_list_insert (apps, data, new_order[row]);
 
     gnome_cmd_data.options.set_fav_apps(apps);
 }
@@ -1635,40 +1658,56 @@ static void on_app_moved (GtkCList *clist, gint arg1, gint arg2, GtkWidget *fram
 
 static void on_app_remove (GtkWidget *button, GtkWidget *frame)
 {
-    GtkCList *clist = GTK_CLIST (lookup_widget (frame, "app_clist"));
+    GtkTreeView *view = GTK_TREE_VIEW (lookup_widget (frame, "app_view"));
+    GtkTreeModel *model;
+    GtkTreeIter iter;
 
-    if (clist->focus_row >= 0)
+    if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (view), &model, &iter))
     {
-        GnomeCmdApp *app = (GnomeCmdApp *) gtk_clist_get_row_data (clist, clist->focus_row);
+        GnomeCmdApp *app;
+        gtk_tree_model_get (model, &iter, 3, &app, -1);
         gnome_cmd_data.options.remove_fav_app(app);
-        gtk_clist_remove (clist, clist->focus_row);
+        gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
     }
 }
 
 
 static void on_app_move_up (GtkWidget *button, GtkWidget *frame)
 {
-    GtkCList *clist = GTK_CLIST (lookup_widget (frame, "app_clist"));
+    GtkTreeView *view = GTK_TREE_VIEW (lookup_widget (frame, "app_view"));
+    GtkTreeModel *model;
+    GtkTreeIter iter, prev;
 
-    if (clist->focus_row >= 1)
-        gtk_clist_row_move (clist, clist->focus_row, clist->focus_row-1);
+    if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (view), &model, &iter))
+    {
+        prev = iter;
+        if (gtk_tree_model_iter_previous (model, &prev))
+            gtk_list_store_swap (GTK_LIST_STORE (model), &iter, &prev);
+    }
 }
 
 
 static void on_app_move_down (GtkWidget *button, GtkWidget *frame)
 {
-    GtkCList *clist = GTK_CLIST (lookup_widget (frame, "app_clist"));
+    GtkTreeView *view = GTK_TREE_VIEW (lookup_widget (frame, "app_view"));
+    GtkTreeModel *model;
+    GtkTreeIter iter, next;
 
-    if (clist->focus_row >= 0)
-        gtk_clist_row_move (clist, clist->focus_row, clist->focus_row+1);
+    if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (view), &model, &iter))
+    {
+        next = iter;
+        if (gtk_tree_model_iter_next (model, &next))
+            gtk_list_store_swap (GTK_LIST_STORE (model), &iter, &next);
+    }
 }
 
 
 static GtkWidget *create_programs_tab (GtkWidget *parent, GnomeCmdData::Options &cfg)
 {
     GtkWidget *frame, *hbox, *scrolled_window, *vbox, *cat, *table1, *table2;
-    GtkWidget *entry, *button, *label, *clist, *bbox, *check;
+    GtkWidget *entry, *button, *label, *view, *bbox, *check;
     GtkWidget *separator;
+    GtkListStore *store;
 
     frame = create_tabframe (parent);
     hbox = create_tabhbox (parent);
@@ -1733,12 +1772,13 @@ static GtkWidget *create_programs_tab (GtkWidget *parent, GnomeCmdData::Options
     gtk_box_pack_start (GTK_BOX (vbox), cat, FALSE, TRUE, 0);
 
 
-    clist = create_clist (parent, "app_clist", 3, 16,
-                          GTK_SIGNAL_FUNC (on_app_selected), GTK_SIGNAL_FUNC (on_app_moved));
-    create_clist_column (clist, 0, 20, "");
-    create_clist_column (clist, 1, 100, _("Label"));
-    create_clist_column (clist, 2, 150, _("Command"));
-    gtk_box_pack_start (GTK_BOX (hbox), clist, TRUE, TRUE, 0);
+    store = gtk_list_store_new (4, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
+    view = create_treeview (parent, "app_view", GTK_TREE_MODEL (store), 16,
+                            GTK_SIGNAL_FUNC (on_app_selection_changed), GTK_SIGNAL_FUNC (on_app_reordered));
+    create_treeview_column (view, 0, 20, "");
+    create_treeview_column (view, 1, 100, _("Label"));
+    create_treeview_column (view, 2, 150, _("Command"));
+    gtk_box_pack_start (GTK_BOX (hbox), view, TRUE, TRUE, 0);
 
     bbox = create_vbuttonbox (parent);
     gtk_box_pack_start (GTK_BOX (hbox), bbox, FALSE, TRUE, 0);
@@ -1767,9 +1807,9 @@ static GtkWidget *create_programs_tab (GtkWidget *parent, GnomeCmdData::Options
     gtk_widget_set_can_default (button, TRUE);
     gtk_container_add (GTK_CONTAINER (bbox), button);
 
-    clist = (GtkWidget *) g_object_get_data (G_OBJECT (parent), "app_clist");
+    view = (GtkWidget *) g_object_get_data (G_OBJECT (parent), "app_view");
     for (GList *apps = gnome_cmd_data.options.fav_apps; apps; apps = apps->next)
-        add_app_to_list (GTK_CLIST (clist), (GnomeCmdApp *) apps->data);
+        add_app_to_list (GTK_TREE_VIEW (view), (GnomeCmdApp *) apps->data);
 
     table2 = create_table (parent, 1, 3);
     cat = create_category (parent, table2, _("Global app options"));
@@ -1822,24 +1862,23 @@ void store_programs_options (GtkWidget *dialog, GnomeCmdData::Options &cfg)
  *
  **********************************************************************/
 
-void add_device_to_list (GtkCList *clist, GnomeCmdConDevice *dev)
+void add_device_to_list (GtkTreeView *view, GnomeCmdConDevice *dev)
 {
-    gchar *text[2];
-
-    text[0] = NULL;
-    text[1] = (gchar *) gnome_cmd_con_device_get_alias (dev);
+    GtkListStore *store = GTK_LIST_STORE (gtk_tree_view_get_model (view));
+    GtkTreeIter iter;
 
-    gint row = gtk_clist_append (GTK_CLIST (clist), text);
     GnomeCmdPixmap *pm = gnome_cmd_con_get_open_pixmap (GNOME_CMD_CON (dev));
 
-    if (pm)
-        gtk_clist_set_pixmap (GTK_CLIST (clist), row, 0, pm->pixmap, pm->mask);
-
-    gtk_clist_set_row_data (GTK_CLIST (clist), row, dev);
+    gtk_list_store_append (store, &iter);
+    gtk_list_store_set (store, &iter,
+                        0, pm ? pm->pixbuf : nullptr,
+                        1, (gchar *) gnome_cmd_con_device_get_alias (dev),
+                        2, dev,
+                        -1);
 }
 
 
-void update_device_in_list (GtkCList *clist, GnomeCmdConDevice *dev, gchar *alias, gchar *device_fn, gchar 
*mountp, gchar *icon_path)
+void update_device_in_list (GtkTreeView *view, GnomeCmdConDevice *dev, gchar *alias, gchar *device_fn, gchar 
*mountp, gchar *icon_path)
 {
     gnome_cmd_con_device_set_alias (dev, alias);
     gnome_cmd_con_device_set_device_fn (dev, device_fn);
@@ -1847,16 +1886,27 @@ void update_device_in_list (GtkCList *clist, GnomeCmdConDevice *dev, gchar *alia
     gnome_cmd_con_device_set_icon_path (dev, icon_path);
 
     GnomeCmdPixmap *pm = gnome_cmd_con_get_open_pixmap (GNOME_CMD_CON (dev));
-    gint row = gtk_clist_find_row_from_data (clist, dev);
 
-    gtk_clist_set_text (GTK_CLIST (clist), row, 1, alias);
-    gtk_clist_set_text (GTK_CLIST (clist), row, 2, device_fn);
-    gtk_clist_set_text (GTK_CLIST (clist), row, 3, mountp);
+    GtkTreeModel *model = gtk_tree_view_get_model (view);
+    GtkTreeIter iter;
+    GnomeCmdConDevice *row_dev;
 
-    if (pm)
-        gtk_clist_set_pixmap (GTK_CLIST (clist), row, 0, pm->pixmap, pm->mask);
-    else
-        gtk_clist_set_pixmap (GTK_CLIST (clist), row, 0, NULL, NULL);
+    if (gtk_tree_model_get_iter_first (model, &iter))
+    {
+        do
+        {
+            gtk_tree_model_get (model, &iter, 2, &row_dev, -1);
+
+            if (row_dev == dev)
+            {
+                gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+                                    0, pm ? pm->pixbuf : nullptr,
+                                    1, alias,
+                                    -1);
+                break;
+            }
+        } while (gtk_tree_model_iter_next (model, &iter));
+    }
 }
 
 
@@ -1897,7 +1947,7 @@ static void on_add_device_dialog_ok (GtkButton *button, GtkWidget *dialog)
     gchar *icon_path = nullptr;
 
     GtkWidget *options_dialog = lookup_widget (dialog, "options_dialog");
-    GtkWidget *clist = lookup_widget (options_dialog, "device_clist");
+    GtkWidget *view = lookup_widget (options_dialog, "device_view");
 
     get_device_dialog_values (dialog, &alias, &device, &mountp, &icon_path);
     if ((!alias || strlen (alias) < 1) ||
@@ -1905,7 +1955,7 @@ static void on_add_device_dialog_ok (GtkButton *button, GtkWidget *dialog)
         (!mountp || strlen(mountp) < 1)) return;
 
     GnomeCmdConDevice *dev = gnome_cmd_con_device_new (alias, device, mountp, icon_path);
-    add_device_to_list (GTK_CLIST (clist), GNOME_CMD_CON_DEVICE (dev));
+    add_device_to_list (GTK_TREE_VIEW (view), GNOME_CMD_CON_DEVICE (dev));
     gtk_widget_destroy (dialog);
 
     gnome_cmd_con_list_get()->add(dev);
@@ -1921,7 +1971,7 @@ static void on_edit_device_dialog_ok (GtkButton *button, GtkWidget *dialog)
     gchar *alias, *device, *mountp, *icon_path;
 
     GtkWidget *options_dialog = lookup_widget (dialog, "options_dialog");
-    GtkWidget *clist = lookup_widget (options_dialog, "device_clist");
+    GtkWidget *view = lookup_widget (options_dialog, "device_view");
 
     get_device_dialog_values (dialog, &alias, &device, &mountp, &icon_path);
     if ((!alias || strlen (alias) < 1) ||
@@ -1931,7 +1981,7 @@ static void on_edit_device_dialog_ok (GtkButton *button, GtkWidget *dialog)
     GnomeCmdConDevice *dev = GNOME_CMD_CON_DEVICE (g_object_get_data (G_OBJECT (options_dialog), 
"selected_device"));
     if (!dev) return;
 
-    update_device_in_list (GTK_CLIST (clist), dev, alias, device, mountp, icon_path);
+    update_device_in_list (GTK_TREE_VIEW (view), dev, alias, device, mountp, icon_path);
     gtk_widget_destroy (dialog);
 
     g_free (device);
@@ -2030,41 +2080,53 @@ static void on_device_edit (GtkWidget *button, GtkWidget *parent)
 
 static void on_device_remove (GtkWidget *button, GtkWidget *frame)
 {
-    GtkCList *clist = GTK_CLIST (lookup_widget (frame, "device_clist"));
+    GtkTreeView *view = GTK_TREE_VIEW (lookup_widget (frame, "device_view"));
+    GtkTreeModel *model;
+    GtkTreeIter iter;
+    GnomeCmdConDevice *dev;
 
-    if (clist->focus_row >= 0)
+    if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (view), &model, &iter))
     {
-        GnomeCmdConDevice *dev = GNOME_CMD_CON_DEVICE (gtk_clist_get_row_data (clist, clist->focus_row));
+        gtk_tree_model_get (model, &iter, 2, &dev, -1);
         gnome_cmd_con_list_get()->remove(dev);
-        gtk_clist_remove (clist, clist->focus_row);
+        gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
     }
 }
 
 
-static void on_device_selected (GtkCList *clist, gint row, gint column, GdkEventButton *event, GtkWidget 
*parent)
+static void on_device_selection_changed (GtkTreeSelection *selection, GtkWidget *parent)
 {
-    GnomeCmdConDevice *dev = GNOME_CMD_CON_DEVICE (gtk_clist_get_row_data (clist, row));
+    GtkTreeModel *model;
+    GtkTreeIter iter;
+    GnomeCmdConDevice *dev = nullptr;
+
+    if (gtk_tree_selection_get_selected (selection, &model, &iter))
+        gtk_tree_model_get (model, &iter, 2, &dev, -1);
+
     g_object_set_data (G_OBJECT (parent), "selected_device", dev);
 
-    gtk_widget_set_sensitive (lookup_widget (parent, "remove_device_button"), TRUE);
-    gtk_widget_set_sensitive (lookup_widget (parent, "edit_device_button"), TRUE);
+    gtk_widget_set_sensitive (lookup_widget (parent, "remove_device_button"), dev != nullptr);
+    gtk_widget_set_sensitive (lookup_widget (parent, "edit_device_button"), dev != nullptr);
 }
 
 
-static void on_device_moved (GtkCList *clist, gint arg1, gint arg2, GtkWidget *frame)
+static void on_device_reordered (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gint *new_order, 
GtkWidget *frame)
 {
+    gint row;
+
+    for (row = 0; new_order[row] == row; row++); // find first difference in order
+
     GList *list = gnome_cmd_con_list_get_all_dev (gnome_cmd_con_list_get ());
 
     if (!list
-        || MAX (arg1, arg2) >= (gint) g_list_length (list) // cast will only be problematic for incredibly 
large lists
-        || MIN (arg1, arg2) < 0
-        || arg1 == arg2)
+        || MAX (row, new_order[row]) >= (gint) g_list_length (list) // cast will only be problematic for 
incredibly large lists
+        || MIN (row, new_order[row]) < 0)
         return;
 
-    gpointer data = g_list_nth_data (list, arg1);
+    gpointer data = g_list_nth_data (list, row);
     list = g_list_remove (list, data);
 
-    list = g_list_insert (list, data, arg2);
+    list = g_list_insert (list, data, new_order[row]);
 
     gnome_cmd_con_list_set_all_dev (gnome_cmd_con_list_get (), list);
 }
@@ -2072,24 +2134,39 @@ static void on_device_moved (GtkCList *clist, gint arg1, gint arg2, GtkWidget *f
 
 static void on_device_move_up (GtkWidget *button, GtkWidget *frame)
 {
-    GtkCList *clist = GTK_CLIST (lookup_widget (frame, "device_clist"));
+    GtkTreeView *view = GTK_TREE_VIEW (lookup_widget (frame, "device_view"));
+    GtkTreeModel *model;
+    GtkTreeIter iter, prev;
 
-    gtk_clist_row_move (clist, clist->focus_row, clist->focus_row-1);
+    if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (view), &model, &iter))
+    {
+        prev = iter;
+        if (gtk_tree_model_iter_previous (model, &prev))
+            gtk_list_store_swap (GTK_LIST_STORE (model), &iter, &prev);
+    }
 }
 
 
 static void on_device_move_down (GtkWidget *button, GtkWidget *frame)
 {
-    GtkCList *clist = GTK_CLIST (lookup_widget (frame, "device_clist"));
+    GtkTreeView *view = GTK_TREE_VIEW (lookup_widget (frame, "device_view"));
+    GtkTreeModel *model;
+    GtkTreeIter iter, next;
 
-    gtk_clist_row_move (clist, clist->focus_row, clist->focus_row+1);
+    if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (view), &model, &iter))
+    {
+        next = iter;
+        if (gtk_tree_model_iter_next (model, &next))
+            gtk_list_store_swap (GTK_LIST_STORE (model), &iter, &next);
+    }
 }
 
 
 static GtkWidget *create_devices_tab (GtkWidget *parent, GnomeCmdData::Options &cfg)
 {
     GtkWidget *frame, *hbox, *scrolled_window, *vbox, *cat, *cat_box;
-    GtkWidget *button, *clist, *bbox, *check;
+    GtkWidget *button, *view, *bbox, *check;
+    GtkListStore *store;
 
     frame = create_tabframe (parent);
     hbox = create_tabhbox (parent);
@@ -2112,11 +2189,12 @@ static GtkWidget *create_devices_tab (GtkWidget *parent, GnomeCmdData::Options &
     gtk_box_set_spacing (GTK_BOX (hbox), 12);
     gtk_container_add (GTK_CONTAINER (cat_box), hbox);
 
-    clist = create_clist (parent, "device_clist", 2, 24,
-                          GTK_SIGNAL_FUNC (on_device_selected), GTK_SIGNAL_FUNC (on_device_moved));
-    create_clist_column (clist, 0, 26, "");
-    create_clist_column (clist, 1, 40, _("Alias"));
-    gtk_box_pack_start (GTK_BOX (hbox), clist, TRUE, TRUE, 0);
+    store = gtk_list_store_new (3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER);
+    view = create_treeview (parent, "device_view", GTK_TREE_MODEL (store), 24,
+                            GTK_SIGNAL_FUNC (on_device_selection_changed), GTK_SIGNAL_FUNC 
(on_device_reordered));
+    create_treeview_column (view, 0, 26, "");
+    create_treeview_column (view, 1, 40, _("Alias"));
+    gtk_box_pack_start (GTK_BOX (hbox), view, TRUE, TRUE, 0);
 
     bbox = create_vbuttonbox (parent);
     gtk_box_pack_start (GTK_BOX (hbox), bbox, FALSE, TRUE, 0);
@@ -2155,10 +2233,10 @@ static GtkWidget *create_devices_tab (GtkWidget *parent, GnomeCmdData::Options &
     gtk_container_add (GTK_CONTAINER (cat_box), check);
     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), cfg.device_only_icon);
 
-    clist = (GtkWidget *) g_object_get_data (G_OBJECT (parent), "device_clist");
+    view = (GtkWidget *) g_object_get_data (G_OBJECT (parent), "device_view");
     for (GList *devices = gnome_cmd_con_list_get_all_dev (gnome_cmd_con_list_get ()); devices; devices = 
devices->next)
         if (!gnome_cmd_con_device_get_autovol ((GnomeCmdConDevice *) devices->data))
-            add_device_to_list (GTK_CLIST (clist), GNOME_CMD_CON_DEVICE (devices->data));
+            add_device_to_list (GTK_TREE_VIEW (view), GNOME_CMD_CON_DEVICE (devices->data));
 
     return frame;
 }
diff --git a/src/plugin_manager.cc b/src/plugin_manager.cc
index 44500716..db83b608 100644
--- a/src/plugin_manager.cc
+++ b/src/plugin_manager.cc
@@ -40,10 +40,8 @@ using namespace std;
 
 
 static GList *plugins = nullptr;
-static GdkPixmap *exec_pixmap = nullptr;
-static GdkBitmap *exec_mask = nullptr;
-static GdkPixmap *blank_pixmap = nullptr;
-static GdkBitmap *blank_mask = nullptr;
+static GdkPixbuf *exec_pixbuf = nullptr;
+static GdkPixbuf *blank_pixbuf = nullptr;
 
 gchar* get_plugin_config_location();
 
@@ -246,50 +244,85 @@ GList *plugin_manager_get_all ()
 }
 
 
-static PluginData *get_selected_plugin (GtkCList *list)
+static PluginData *get_selected_plugin (GtkTreeView *view)
 {
-    return static_cast<PluginData*> (gtk_clist_get_row_data (list, list->focus_row));
+    GtkTreeModel *model;
+    GtkTreeIter iter;
+    PluginData *data;
+
+    g_return_val_if_fail (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (view), &model, 
&iter), nullptr);
+    gtk_tree_model_get (model, &iter, 4, &data, -1);
+    return data;
 }
 
 
-static void update_plugin_list (GtkCList *list, GtkWidget *dialog)
+static void on_plugin_selection_changed (GtkTreeSelection *selection, GtkWidget *dialog)
 {
-    gint old_focus = list->focus_row;
-    gint row = 0;
-    gboolean only_update = (list->rows > 0);
+    GtkWidget *toggle_button = lookup_widget (dialog, "toggle_button");
+    GtkWidget *conf_button = lookup_widget (dialog, "conf_button");
+    GtkWidget *about_button = lookup_widget (dialog, "about_button");
+    GtkTreeModel *model;
+    GtkTreeIter iter;
+    PluginData *data;
 
-    for (GList *i=plugins; i; i=i->next, ++row)
+    if (gtk_tree_selection_get_selected (selection, &model, &iter))
     {
-        auto data = static_cast<PluginData*> (i->data);
-        gchar *text[5];
+        gtk_tree_model_get (model, &iter, 4, &data, -1);
+        gtk_widget_set_sensitive (about_button, TRUE);
+        gtk_button_set_label (GTK_BUTTON (toggle_button), data->active ? _("Disable") : _("Enable"));
+        gtk_widget_set_sensitive (toggle_button, TRUE);
+        gtk_widget_set_sensitive (conf_button, data->active);
+    }
+    else
+    {
+        gtk_widget_set_sensitive (toggle_button, FALSE);
+        gtk_widget_set_sensitive (about_button, FALSE);
+        gtk_widget_set_sensitive (conf_button, FALSE);
+    }
+}
 
-        text[0] = nullptr;
-        text[1] = (gchar *) data->info->name;
-        text[2] = (gchar *) data->info->version;
-        text[3] = data->fname;
-        text[4] = nullptr;
 
-        if (only_update)
-            gtk_clist_set_text (list, row, 1, text[1]);
-        else
-            gtk_clist_append (list, text);
+static void update_plugin_list (GtkTreeView *view, GtkWidget *dialog)
+{
+    GtkTreeModel *model = gtk_tree_view_get_model (view);
+    GtkTreeIter iter;
+    gboolean only_update = gtk_tree_model_get_iter_first (model, &iter);
+    GtkListStore *store = GTK_LIST_STORE (model);
 
-        if (data->active)
-            gtk_clist_set_pixmap (list, row, 0, exec_pixmap, exec_mask);
-        else
-            gtk_clist_set_pixmap (list, row, 0, blank_pixmap, blank_mask);
+    for (GList *i=plugins; i; i=i->next)
+    {
+        auto data = static_cast<PluginData*> (i->data);
 
-        gtk_clist_set_row_data (list, row, data);
+        if (only_update)
+        {
+            gtk_list_store_set (store, &iter,
+                                0, data->active ? exec_pixbuf : blank_pixbuf,
+                                1, (gchar *) data->info->name,
+                                4, data,
+                                -1);
+            gtk_tree_model_iter_next (model, &iter);
+        }
+        else
+        {
+            gtk_list_store_append (store, &iter);
+            gtk_list_store_set (store, &iter,
+                                0, data->active ? exec_pixbuf : blank_pixbuf,
+                                1, (gchar *) data->info->name,
+                                2, (gchar *) data->info->version,
+                                3, data->fname,
+                                4, data,
+                                -1);
+        }
     }
 
-    gtk_clist_select_row (list, old_focus, 0);
+    on_plugin_selection_changed (gtk_tree_view_get_selection (view), dialog);
 }
 
 
 inline void do_toggle (GtkWidget *dialog)
 {
-    GtkCList *list = GTK_CLIST (lookup_widget (dialog, "avail_list"));
-    PluginData *data = get_selected_plugin (list);
+    GtkTreeView *view = GTK_TREE_VIEW (lookup_widget (dialog, "avail_view"));
+    PluginData *data = get_selected_plugin (view);
 
     if (!data) return;
 
@@ -298,41 +331,13 @@ inline void do_toggle (GtkWidget *dialog)
     else
         activate_plugin (data);
 
-    update_plugin_list (list, dialog);
+    update_plugin_list (view, dialog);
 }
 
 
-static void on_plugin_selected (GtkCList *list, gint row, gint column, GdkEventButton *event, GtkWidget 
*dialog)
+static void on_plugin_activated (GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *column, GtkWidget 
*dialog)
 {
-    GtkWidget *toggle_button = lookup_widget (dialog, "toggle_button");
-    GtkWidget *conf_button = lookup_widget (dialog, "conf_button");
-    GtkWidget *about_button = lookup_widget (dialog, "about_button");
-
-    PluginData *data = get_selected_plugin (list);
-    g_return_if_fail (data != nullptr);
-
-    if (event && event->type == GDK_2BUTTON_PRESS && event->button == 1)
-    {
-        do_toggle (dialog);
-        return;
-    }
-
-    gtk_widget_set_sensitive (about_button, TRUE);
-    gtk_button_set_label (GTK_BUTTON (toggle_button), data->active ? _("Disable") : _("Enable"));
-    gtk_widget_set_sensitive (toggle_button, TRUE);
-    gtk_widget_set_sensitive (conf_button, data->active);
-}
-
-
-static void on_plugin_unselected (GtkCList *list, gint row, gint column, GdkEventButton *event, GtkWidget 
*dialog)
-{
-    GtkWidget *toggle_button = lookup_widget (dialog, "toggle_button");
-    GtkWidget *conf_button = lookup_widget (dialog, "conf_button");
-    GtkWidget *about_button = lookup_widget (dialog, "about_button");
-
-    gtk_widget_set_sensitive (toggle_button, FALSE);
-    gtk_widget_set_sensitive (about_button, FALSE);
-    gtk_widget_set_sensitive (conf_button, FALSE);
+    do_toggle (dialog);
 }
 
 
@@ -344,8 +349,8 @@ static void on_toggle (GtkButton *button, GtkWidget *dialog)
 
 static void on_configure (GtkButton *button, GtkWidget *dialog)
 {
-    GtkCList *list = GTK_CLIST (lookup_widget (dialog, "avail_list"));
-    PluginData *data = get_selected_plugin (list);
+    GtkTreeView *view = GTK_TREE_VIEW (lookup_widget (dialog, "avail_view"));
+    PluginData *data = get_selected_plugin (view);
 
     g_return_if_fail (data != nullptr);
     g_return_if_fail (data->active);
@@ -356,8 +361,8 @@ static void on_configure (GtkButton *button, GtkWidget *dialog)
 
 static void on_about (GtkButton *button, GtkWidget *dialog)
 {
-    GtkCList *list = GTK_CLIST (lookup_widget (dialog, "avail_list"));
-    PluginData *data = get_selected_plugin (list);
+    GtkTreeView *view = GTK_TREE_VIEW (lookup_widget (dialog, "avail_view"));
+    PluginData *data = get_selected_plugin (view);
 
     g_return_if_fail (data != nullptr);
 
@@ -378,17 +383,19 @@ static void on_close (GtkButton *button, GtkWidget *dialog)
 void plugin_manager_show ()
 {
     GtkWidget *dialog, *hbox, *bbox, *button;
-    GtkWidget *avail_list;
+    GtkListStore *avail_store;
+    GtkWidget *avail_view;
 
     dialog = gnome_cmd_dialog_new (_("Available plugins"));
     g_object_ref (dialog);
 
     hbox = create_vbox (dialog, FALSE, 6);
-    avail_list = create_clist (dialog, "avail_list", 4, 20, GTK_SIGNAL_FUNC (on_plugin_selected), nullptr);
-    create_clist_column (avail_list, 0, 20, "");
-    create_clist_column (avail_list, 1, 200, _("Name"));
-    create_clist_column (avail_list, 2, 50, _("Version"));
-    create_clist_column (avail_list, 3, 50, _("File"));
+    avail_store = gtk_list_store_new (5, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, 
G_TYPE_POINTER);
+    avail_view = create_treeview (dialog, "avail_view", GTK_TREE_MODEL (avail_store), 20, GTK_SIGNAL_FUNC 
(on_plugin_selection_changed), nullptr);
+    create_treeview_column (avail_view, 0, 20, "");
+    create_treeview_column (avail_view, 1, 200, _("Name"));
+    create_treeview_column (avail_view, 2, 50, _("Version"));
+    create_treeview_column (avail_view, 3, 50, _("File"));
 
     bbox = create_hbuttonbox (dialog);
     gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_START);
@@ -407,27 +414,21 @@ void plugin_manager_show ()
     gtk_widget_set_sensitive (button, FALSE);
     gtk_box_pack_start (GTK_BOX (bbox), button, TRUE, FALSE, 0);
 
-    gtk_box_pack_start (GTK_BOX (hbox), avail_list, TRUE, TRUE, 0);
+    gtk_box_pack_start (GTK_BOX (hbox), avail_view, TRUE, TRUE, 0);
     gtk_box_pack_start (GTK_BOX (hbox), bbox, FALSE, TRUE, 0);
 
     gnome_cmd_dialog_add_expanding_category (GNOME_CMD_DIALOG (dialog), hbox);
 
-    avail_list = lookup_widget (avail_list, "avail_list");
-    g_signal_connect (avail_list, "unselect-row", G_CALLBACK (on_plugin_unselected), dialog);
+    avail_view = lookup_widget (avail_view, "avail_view");
+    g_signal_connect (GTK_TREE_VIEW (avail_view), "row-activated", G_CALLBACK (on_plugin_activated), dialog);
 
-    if (!exec_pixmap)
-    {
-        exec_pixmap = IMAGE_get_pixmap (PIXMAP_EXEC_WHEEL);
-        exec_mask = IMAGE_get_mask (PIXMAP_EXEC_WHEEL);
-    }
+    if (!exec_pixbuf)
+        exec_pixbuf = IMAGE_get_pixbuf (PIXMAP_EXEC_WHEEL);
 
-    if (!blank_pixmap)
-    {
-        blank_pixmap = IMAGE_get_pixmap (PIXMAP_FLIST_ARROW_BLANK);
-        blank_mask = IMAGE_get_mask (PIXMAP_FLIST_ARROW_BLANK);
-    }
+    if (!blank_pixbuf)
+        blank_pixbuf = IMAGE_get_pixbuf (PIXMAP_FLIST_ARROW_BLANK);
 
-    update_plugin_list (GTK_CLIST (avail_list), dialog);
+    update_plugin_list (GTK_TREE_VIEW (avail_view), dialog);
 
     gnome_cmd_dialog_add_button (GNOME_CMD_DIALOG (dialog), GTK_STOCK_CLOSE, GTK_SIGNAL_FUNC(on_close), 
dialog);
     gtk_window_set_transient_for (GTK_WINDOW (dialog), *main_win);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]