[gnome-commander] Fixed problem #600292 (crash when double-clicking on bookmarks list)



commit 735051111f2e9a0d62880786c6eb269f6b222e9e
Author: Piotr Eljasiak <epiotr src gnome org>
Date:   Mon Nov 23 22:23:12 2009 +0100

    Fixed problem #600292 (crash when double-clicking on bookmarks list)

 NEWS                                             |    3 +-
 doc/C/gnome-commander.xml                        |    5 +-
 po/POTFILES.in                                   |    3 +-
 src/Makefile.am                                  |    1 -
 src/dialogs/Makefile.am                          |    2 +
 src/dialogs/gnome-cmd-edit-bookmark-dialog.cc    |  135 ++++++
 src/dialogs/gnome-cmd-edit-bookmark-dialog.h     |   28 ++
 src/dialogs/gnome-cmd-manage-bookmarks-dialog.cc |  537 ++++++++++++++++++++++
 src/dialogs/gnome-cmd-manage-bookmarks-dialog.h  |   31 ++
 src/gnome-cmd-data.cc                            |   28 --
 src/gnome-cmd-data.h                             |    3 -
 src/gnome-cmd-main-menu.cc                       |    2 +-
 src/gnome-cmd-main-win.cc                        |    2 +-
 src/gnome-cmd-types.h                            |    1 -
 src/gnome-cmd-user-actions.cc                    |    8 +-
 15 files changed, 746 insertions(+), 43 deletions(-)
---
diff --git a/NEWS b/NEWS
index eaa047a..bb93a2a 100644
--- a/NEWS
+++ b/NEWS
@@ -3,9 +3,10 @@ gnome-commander 1.2.9
 ---------------
 
 Bug fixes:
- * Fixed problem #... (...)
+ * Fixed problem #600292 (crash when double-clicking on bookmarks list)
 
 New features:
+ * Revamped bookmarks dialog
  * Revamped file properties dialog
  * New or updated docs: de, es, fr
  * New or updated translations: da, es, eu, hu, ru, sl, zh_CN
diff --git a/doc/C/gnome-commander.xml b/doc/C/gnome-commander.xml
index fcf092f..61a34c1 100644
--- a/doc/C/gnome-commander.xml
+++ b/doc/C/gnome-commander.xml
@@ -5992,7 +5992,7 @@
                 <para>
                     <itemizedlist>
                         <listitem>
-                            <para>Fixed problem #... (...)</para>
+                            <para>Fixed problem #600292 (crash when double-clicking on bookmarks list)</para>
                         </listitem>
                     </itemizedlist>
                 </para>
@@ -6000,6 +6000,9 @@
                 <para>
                     <itemizedlist>
                         <listitem>
+                            <para>Revamped bookmarks dialog</para>
+                        </listitem>
+                        <listitem>
                             <para>Revamped file properties dialog</para>
                         </listitem>
                         <listitem>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 365d9c5..9fad991 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -8,13 +8,14 @@ plugins/cvs/interface.c
 plugins/fileroller/file-roller-plugin.c
 plugins/test/test-plugin.c
 src/dialogs/gnome-cmd-advrename-regex-dialog.cc
+src/dialogs/gnome-cmd-edit-bookmark-dialog.cc
 src/dialogs/gnome-cmd-edit-profile-dialog.cc
+src/dialogs/gnome-cmd-manage-bookmarks-dialog.cc
 src/dialogs/gnome-cmd-manage-profiles-dialog.cc
 src/dirlist.cc
 src/eggcellrendererkeys.cc
 src/gnome-cmd-about-plugin.cc
 src/gnome-cmd-advrename-dialog.cc
-src/gnome-cmd-bookmark-dialog.cc
 src/gnome-cmd-chmod-component.cc
 src/gnome-cmd-chmod-dialog.cc
 src/gnome-cmd-chown-component.cc
diff --git a/src/Makefile.am b/src/Makefile.am
index f9469d8..e5d2503 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -23,7 +23,6 @@ gnome_commander_SOURCES = \
 	gnome-cmd-advrename-dialog.h gnome-cmd-advrename-dialog.cc \
 	gnome-cmd-advrename-lexer.h gnome-cmd-advrename-lexer.ll \
 	gnome-cmd-app.h gnome-cmd-app.cc \
-	gnome-cmd-bookmark-dialog.h gnome-cmd-bookmark-dialog.cc \
 	gnome-cmd-chmod-component.h gnome-cmd-chmod-component.cc \
 	gnome-cmd-chmod-dialog.h gnome-cmd-chmod-dialog.cc \
 	gnome-cmd-chown-component.h gnome-cmd-chown-component.cc \
diff --git a/src/dialogs/Makefile.am b/src/dialogs/Makefile.am
index 322ef5f..48b7454 100644
--- a/src/dialogs/Makefile.am
+++ b/src/dialogs/Makefile.am
@@ -17,5 +17,7 @@ AM_CPPFLAGS = \
 
 libgcmd_dialogs_a_SOURCES = \
 	gnome-cmd-advrename-regex-dialog.h gnome-cmd-advrename-regex-dialog.cc \
+	gnome-cmd-edit-bookmark-dialog.h gnome-cmd-edit-bookmark-dialog.cc \
+	gnome-cmd-manage-bookmarks-dialog.h gnome-cmd-manage-bookmarks-dialog.cc \
 	gnome-cmd-edit-profile-dialog.h gnome-cmd-edit-profile-dialog.cc \
 	gnome-cmd-manage-profiles-dialog.h gnome-cmd-manage-profiles-dialog.cc
diff --git a/src/dialogs/gnome-cmd-edit-bookmark-dialog.cc b/src/dialogs/gnome-cmd-edit-bookmark-dialog.cc
new file mode 100644
index 0000000..488d10a
--- /dev/null
+++ b/src/dialogs/gnome-cmd-edit-bookmark-dialog.cc
@@ -0,0 +1,135 @@
+/*
+    GNOME Commander - A GNOME based file manager
+    Copyright (C) 2001-2006 Marcus Bjurman
+    Copyright (C) 2007-2009 Piotr Eljasiak
+
+    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 St, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <config.h>
+
+#include "gnome-cmd-includes.h"
+#include "gnome-cmd-data.h"
+#include "gnome-cmd-edit-bookmark-dialog.h"
+#include "utils.h"
+
+using namespace std;
+
+
+static void response_callback (GtkDialog *dialog, int response_id, gpointer unused)
+{
+    switch (response_id)
+    {
+        case GTK_RESPONSE_OK:
+            {
+                const gchar *name = gtk_entry_get_text (GTK_ENTRY (lookup_widget (GTK_WIDGET (dialog), "name")));
+
+                if (!name || !*name)
+                {
+                    g_signal_stop_emission_by_name (dialog, "response");
+                    gnome_cmd_show_message (GTK_WINDOW (dialog), _("Bookmark name is missing"));
+                    break;
+                }
+
+                const gchar *path = gtk_entry_get_text (GTK_ENTRY (lookup_widget (GTK_WIDGET (dialog), "path")));
+
+                if (!path || !*path)
+                {
+                    g_signal_stop_emission_by_name (dialog, "response");
+                    gnome_cmd_show_message (GTK_WINDOW (dialog), _("Bookmark target is missing"));
+                    break;
+                }
+            }
+
+            break;
+
+        case GTK_RESPONSE_NONE:
+        case GTK_RESPONSE_DELETE_EVENT:
+        case GTK_RESPONSE_CANCEL:
+            break;
+
+        default :
+            g_assert_not_reached ();
+    }
+}
+
+
+gboolean gnome_cmd_edit_bookmark_dialog (GtkWindow *parent, const gchar *title, gchar *&name, gchar *&path)
+{
+    GtkWidget *dialog = gtk_dialog_new_with_buttons (title, parent,
+                                                     GtkDialogFlags (GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
+                                                     GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                                     GTK_STOCK_OK, GTK_RESPONSE_OK,
+                                                     NULL);
+
+    gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
+    gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
+
+    // HIG defaults
+    gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
+    gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 2);
+    gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 5);
+    gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->action_area),6);
+
+    GtkWidget *table, *label, *entry;
+
+    table = gtk_table_new (3, 2, FALSE);
+    gtk_container_set_border_width (GTK_CONTAINER (table), 5);
+    gtk_table_set_row_spacings (GTK_TABLE (table), 6);
+    gtk_table_set_col_spacings (GTK_TABLE (table), 12);
+    gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), table);
+
+    label = gtk_label_new_with_mnemonic (_("Bookmark _name:"));
+    gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+    gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 0, 1);
+
+    entry = gtk_entry_new ();
+    gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
+    gtk_entry_set_text (GTK_ENTRY (entry), name);
+    g_object_set_data (G_OBJECT (dialog), "name", entry);
+    gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
+    gtk_table_attach_defaults (GTK_TABLE (table), entry, 1, 2, 0, 1);
+
+    label = gtk_label_new_with_mnemonic (_("Bookmark _target:"));
+    gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+    gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2);
+
+    entry = gtk_entry_new ();
+    gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
+    gtk_entry_set_text (GTK_ENTRY (entry), path);
+    g_object_set_data (G_OBJECT (dialog), "path", entry);
+    gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
+    gtk_table_attach_defaults (GTK_TABLE (table), entry, 1, 2, 1, 2);
+
+    gtk_widget_show_all (GTK_DIALOG (dialog)->vbox);
+
+    gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+
+    g_signal_connect (dialog, "response", G_CALLBACK (response_callback), NULL);
+
+    gint result = gtk_dialog_run (GTK_DIALOG (dialog));
+
+    if (result==GTK_RESPONSE_OK)
+    {
+        g_free (name);
+        name = g_strdup (gtk_entry_get_text (GTK_ENTRY (lookup_widget (GTK_WIDGET (dialog), "name"))));
+        g_free (path);
+        path = g_strdup (gtk_entry_get_text (GTK_ENTRY (lookup_widget (GTK_WIDGET (dialog), "path"))));
+    }
+
+    gtk_widget_destroy (dialog);
+
+    return result==GTK_RESPONSE_OK;
+}
diff --git a/src/dialogs/gnome-cmd-edit-bookmark-dialog.h b/src/dialogs/gnome-cmd-edit-bookmark-dialog.h
new file mode 100644
index 0000000..0c18d37
--- /dev/null
+++ b/src/dialogs/gnome-cmd-edit-bookmark-dialog.h
@@ -0,0 +1,28 @@
+/*
+    GNOME Commander - A GNOME based file manager
+    Copyright (C) 2001-2006 Marcus Bjurman
+    Copyright (C) 2007-2009 Piotr Eljasiak
+
+    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 St, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __GNOME_CMD_EDIT_BOOKMARK_DIALOG_H__
+#define __GNOME_CMD_EDIT_BOOKMARK_DIALOG_H__
+
+#include "gnome-cmd-data.h"
+
+gboolean gnome_cmd_edit_bookmark_dialog (GtkWindow *parent, const gchar *title, gchar *&name, gchar *&path);
+
+#endif // __GNOME_CMD_EDIT_BOOKMARK_DIALOG_H__
diff --git a/src/dialogs/gnome-cmd-manage-bookmarks-dialog.cc b/src/dialogs/gnome-cmd-manage-bookmarks-dialog.cc
new file mode 100644
index 0000000..c8c687c
--- /dev/null
+++ b/src/dialogs/gnome-cmd-manage-bookmarks-dialog.cc
@@ -0,0 +1,537 @@
+/*
+    GNOME Commander - A GNOME based file manager
+    Copyright (C) 2001-2006 Marcus Bjurman
+    Copyright (C) 2007-2009 Piotr Eljasiak
+
+    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 St, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <config.h>
+#include <map>
+#include <set>
+
+#include "gnome-cmd-includes.h"
+#include "gnome-cmd-data.h"
+#include "gnome-cmd-con-list.h"
+#include "gnome-cmd-main-win.h"
+#include "gnome-cmd-manage-bookmarks-dialog.h"
+#include "gnome-cmd-edit-bookmark-dialog.h"
+#include "gnome-cmd-treeview.h"
+#include "gnome-cmd-user-actions.h"
+#include "gnome-cmd-menu-button.h"
+#include "gnome-cmd-hintbox.h"
+#include "eggcellrendererkeys.h"
+#include "utils.h"
+
+using namespace std;
+
+
+static GtkTreeModel *create_and_fill_model (GtkTreePath *&current_group);
+static GtkWidget *create_view_and_model ();
+
+static void cursor_changed_callback (GtkTreeView *view, GtkWidget *dialog);
+static void row_activated_callback (GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *col, gpointer);
+static void edit_clicked_callback (GtkButton *button, GtkWidget *view);
+static void remove_clicked_callback (GtkButton *button, GtkWidget *view);
+static void up_clicked_callback (GtkButton *button, GtkWidget *view);
+static void down_clicked_callback (GtkButton *button, GtkWidget *view);
+static void size_allocate_callback (GtkWidget *widget, GtkAllocation *allocation, gpointer unused);
+static void response_callback (GtkDialog *dialog, int response_id, GtkTreeView *view);
+
+
+enum
+{
+    COL_GROUP,
+    COL_NAME,
+    COL_PATH,
+    COL_SHORTCUT,
+    COL_BOOKMARK,
+    NUM_COLUMNS
+} ;
+
+
+const int RESPONSE_JUMP_TO = 123;
+
+
+void gnome_cmd_bookmark_dialog_new (const gchar *title, GtkWindow *parent)
+{
+    GtkWidget *dialog = gtk_dialog_new_with_buttons (title, parent,
+                                                     GtkDialogFlags (GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
+                                                     GTK_STOCK_HELP, GTK_RESPONSE_HELP,
+                                                     GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
+                                                     GTK_STOCK_JUMP_TO, RESPONSE_JUMP_TO,
+                                                     NULL);
+
+    GtkWidget *vbox, *hbox, *scrolled_window, *view, *button;
+
+    gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
+    gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
+    gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
+    gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 2);
+    gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
+
+    vbox = gtk_vbox_new (FALSE, 12);
+    gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
+    gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), vbox);
+
+    hbox = gtk_hbox_new (FALSE, 12);
+    gtk_container_add (GTK_CONTAINER (vbox), hbox);
+
+    scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+    gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN);
+    gtk_box_pack_start (GTK_BOX (hbox), scrolled_window, TRUE, TRUE, 0);
+
+    view = create_view_and_model ();
+    gtk_window_set_default_size (GTK_WINDOW (dialog), gnome_cmd_data.bookmarks_defaults.width, gnome_cmd_data.bookmarks_defaults.height);
+    gtk_widget_set_size_request (view, 400, 250);
+    g_signal_connect (view, "cursor-changed", G_CALLBACK (cursor_changed_callback), dialog);
+    g_signal_connect (view, "row-activated", G_CALLBACK (row_activated_callback), dialog);
+    gtk_container_add (GTK_CONTAINER (scrolled_window), view);
+
+    vbox = gtk_vbox_new (FALSE, 12);
+    gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
+
+    button = gtk_button_new_from_stock (GTK_STOCK_EDIT);
+    gtk_widget_set_sensitive (button, FALSE);
+    g_signal_connect (button, "clicked", G_CALLBACK (edit_clicked_callback), view);
+    gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+    g_object_set_data (G_OBJECT (dialog), "edit-button", button);
+
+    button = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
+    gtk_widget_set_sensitive (button, FALSE);
+    g_signal_connect (button, "clicked", G_CALLBACK (remove_clicked_callback), view);
+    gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+    g_object_set_data (G_OBJECT (dialog), "remove-button", button);
+
+    button = gtk_button_new_from_stock (GTK_STOCK_GO_UP);
+    gtk_widget_set_sensitive (button, FALSE);
+    g_signal_connect (button, "clicked", G_CALLBACK (up_clicked_callback), view);
+    gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+    g_object_set_data (G_OBJECT (dialog), "up-button", button);
+
+    button = gtk_button_new_from_stock (GTK_STOCK_GO_DOWN);
+    gtk_widget_set_sensitive (button, FALSE);
+    g_signal_connect (button, "clicked", G_CALLBACK (down_clicked_callback), view);
+    gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+    g_object_set_data (G_OBJECT (dialog), "down-button", button);
+
+    gtk_widget_grab_focus (view);
+
+    gtk_dialog_set_default_response (GTK_DIALOG (dialog), RESPONSE_JUMP_TO);
+    gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), RESPONSE_JUMP_TO, FALSE);
+
+    gtk_widget_show_all (GTK_DIALOG (dialog)->vbox);
+
+    g_signal_connect (dialog, "size-allocate", G_CALLBACK (size_allocate_callback), NULL);
+    g_signal_connect (dialog, "response", G_CALLBACK (response_callback), view);
+
+    gtk_dialog_run (GTK_DIALOG (dialog));
+
+    gtk_widget_destroy (dialog);
+}
+
+
+static GtkTreeModel *create_and_fill_model (GtkTreePath *&current_group)
+{
+    GtkTreeStore *store = gtk_tree_store_new (NUM_COLUMNS,
+                                              G_TYPE_STRING,
+                                              G_TYPE_STRING,
+                                              G_TYPE_STRING,
+                                              G_TYPE_STRING,
+                                              G_TYPE_POINTER);
+
+    GnomeCmdCon *current_con = main_win->fs(ACTIVE)->get_connection();
+    GtkTreeIter toplevel;
+
+    map<string,set<string> > keys;
+
+    for (GnomeCmdUserActions::const_iterator i=gcmd_user_actions.begin(); i!=gcmd_user_actions.end(); ++i)
+        if (!ascii_isupper (*i))                                       // ignore lowercase keys as they duplicate uppercase ones
+        {
+            const gchar *options = gcmd_user_actions.options(i);
+
+            if (options && strcmp(gcmd_user_actions.name(i),"bookmarks.goto")==0)
+            {
+                gchar *accelerator = egg_accelerator_get_label(i->first.keyval, (GdkModifierType) i->first.state);
+                keys[options].insert(accelerator);
+                g_free (accelerator);
+            }
+        }
+
+    for (GList *all_cons = gnome_cmd_con_list_get_all (gnome_cmd_con_list_get ()); all_cons; all_cons = all_cons->next)
+    {
+        GnomeCmdCon *con = (GnomeCmdCon *) all_cons->data;
+        GnomeCmdPixmap *pixmap = gnome_cmd_con_get_open_pixmap (con);
+        GnomeCmdBookmarkGroup *group = gnome_cmd_con_get_bookmarks (con);
+
+        if (!group || !group->bookmarks)
+            continue;
+
+        gtk_tree_store_append (store, &toplevel, NULL);
+        gtk_tree_store_set (store, &toplevel,
+                            COL_GROUP, gnome_cmd_con_get_alias (con),
+                            -1);
+
+        if (con==current_con)
+            current_group = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &toplevel);
+
+        GtkTreeIter child;
+
+        for (GList *bookmarks = group->bookmarks; bookmarks; bookmarks = bookmarks->next)
+        {
+            gtk_tree_store_append (store, &child, &toplevel);
+            GnomeCmdBookmark *bookmark = (GnomeCmdBookmark *) bookmarks->data;
+
+            gtk_tree_store_set (store, &child,
+                                COL_NAME, bookmark->name,
+                                COL_PATH, bookmark->path,
+                                COL_SHORTCUT, join(keys[bookmark->name], ", ").c_str(),
+                                COL_BOOKMARK, bookmark,
+                                -1);
+        }
+    }
+
+    return GTK_TREE_MODEL (store);
+}
+
+
+static GtkWidget *create_view_and_model ()
+{
+    GtkWidget *view = gtk_tree_view_new ();
+
+    g_object_set (view,
+                  "rules-hint", TRUE,
+                  "enable-search", TRUE,
+                  "search-column", COL_NAME,
+                  NULL);
+
+    GtkCellRenderer *renderer = NULL;
+    GtkTreeViewColumn *col = NULL;
+
+    GtkTooltips *tips = gtk_tooltips_new ();
+
+    col = gnome_cmd_treeview_create_new_text_column (GTK_TREE_VIEW (view), renderer, COL_GROUP, _("Group"));
+    gtk_tooltips_set_tip (tips, col->button, _("Bookmark group"), NULL);
+
+    g_object_set (renderer,
+                  "weight-set", TRUE,
+                  "weight", PANGO_WEIGHT_BOLD,
+                  NULL);
+
+    col = gnome_cmd_treeview_create_new_text_column (GTK_TREE_VIEW (view), renderer, COL_NAME, _("Name"));
+    gtk_tooltips_set_tip (tips, col->button, _("Bookmark name"), NULL);
+
+    col = gnome_cmd_treeview_create_new_text_column (GTK_TREE_VIEW (view), renderer, COL_SHORTCUT, _("Shortcut"));
+    gtk_tooltips_set_tip (tips, col->button, _("Keyboard shortcut for selected bookmark"), NULL);
+
+    g_object_set (renderer,
+                  "foreground-set", TRUE,
+                  "foreground", "DarkGray",
+                  NULL);
+
+    col = gnome_cmd_treeview_create_new_text_column (GTK_TREE_VIEW (view), renderer, COL_PATH, _("Path"));
+    gtk_tooltips_set_tip (tips, col->button, _("Bookmarked path"), NULL);
+
+    g_object_set (renderer,
+                  "foreground-set", TRUE,
+                  "foreground", "DarkGray",
+                  "ellipsize-set", TRUE,
+                  "ellipsize", PANGO_ELLIPSIZE_END,
+                  NULL);
+
+    GtkTreePath *group = NULL;
+    GtkTreeModel *model = create_and_fill_model (group);
+
+    gtk_tree_view_set_model (GTK_TREE_VIEW (view), model);
+
+    g_object_unref (model);          // destroy model automatically with view
+
+    GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
+    gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
+
+    if (group)
+        gtk_tree_view_expand_row (GTK_TREE_VIEW (view), group, TRUE);
+    else
+        group = gtk_tree_path_new_first ();
+
+    gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), group, NULL, FALSE);
+    gtk_tree_path_free (group);
+
+    return view;
+}
+
+
+static void cursor_changed_callback (GtkTreeView *view, GtkWidget *dialog)
+{
+    GtkTreeModel *model = gtk_tree_view_get_model (view);
+    GtkTreeIter iter;
+
+    if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (view), NULL, &iter))
+    {
+        GnomeCmdBookmark *bookmark = NULL;
+
+        gtk_tree_model_get (model, &iter, COL_BOOKMARK, &bookmark, -1);
+
+        gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), RESPONSE_JUMP_TO, bookmark!=NULL);
+        gtk_widget_set_sensitive ((GtkWidget *) g_object_get_data (G_OBJECT (dialog), "edit-button"), bookmark!=NULL);
+        gtk_widget_set_sensitive ((GtkWidget *) g_object_get_data (G_OBJECT (dialog), "remove-button"), bookmark!=NULL);
+        gtk_widget_set_sensitive ((GtkWidget *) g_object_get_data (G_OBJECT (dialog), "up-button"), bookmark!=NULL && bookmark->group->bookmarks->data!=bookmark);
+        gtk_widget_set_sensitive ((GtkWidget *) g_object_get_data (G_OBJECT (dialog), "down-button"), bookmark!=NULL && gtk_tree_model_iter_next (model, &iter));
+    }
+}
+
+
+static void row_activated_callback (GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *col, gpointer)
+{
+    gtk_dialog_response ((GtkDialog *) gtk_widget_get_ancestor (GTK_WIDGET (view), GTK_TYPE_DIALOG), RESPONSE_JUMP_TO);
+}
+
+
+static void edit_clicked_callback (GtkButton *button, GtkWidget *view)
+{
+    GtkWidget *dialog = gtk_widget_get_ancestor (view, GTK_TYPE_DIALOG);
+
+    g_return_if_fail (dialog!=NULL);
+
+    GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
+    GtkTreeIter iter;
+
+    if (gtk_tree_selection_get_selected (selection, NULL, &iter))
+    {
+        GnomeCmdBookmark *bookmark = NULL;
+        GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
+        gtk_tree_model_get (model, &iter, COL_BOOKMARK, &bookmark, -1);
+
+        if (gnome_cmd_edit_bookmark_dialog (GTK_WINDOW (dialog), _("Edit Bookmark"), bookmark->name, bookmark->path))
+            gtk_tree_store_set (GTK_TREE_STORE (model), &iter,
+                                COL_NAME, bookmark->name,
+                                COL_PATH, bookmark->path,
+                                -1);
+    }
+}
+
+
+static void remove_clicked_callback (GtkButton *button, GtkWidget *view)
+{
+    GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
+    GtkTreeIter iter;
+
+    if (gtk_tree_selection_get_selected (selection, NULL, &iter))
+    {
+        GnomeCmdBookmark *bookmark = NULL;
+        GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
+        gtk_tree_model_get (model, &iter, COL_BOOKMARK, &bookmark, -1);
+        gtk_tree_store_remove (GTK_TREE_STORE (model), &iter);
+
+        if (bookmark)
+        {
+            bookmark->group->bookmarks = g_list_remove (bookmark->group->bookmarks, bookmark);
+            g_free (bookmark->name);
+            g_free (bookmark->path);
+            g_free (bookmark);
+        }
+    }
+}
+
+
+static void up_clicked_callback (GtkButton *button, GtkWidget *view)
+{
+    GtkWidget *dialog = gtk_widget_get_ancestor (view, GTK_TYPE_DIALOG);
+    GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
+    GtkTreeIter iter;
+
+    if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
+        return;
+
+    GnomeCmdBookmark *bookmark = NULL;
+    GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
+    gtk_tree_model_get (model, &iter, COL_BOOKMARK, &bookmark, -1);
+
+    if (!bookmark)
+        return;
+
+    GList *elem = g_list_find (bookmark->group->bookmarks, bookmark);
+
+    if (!elem)
+        return;
+
+    bookmark->group->bookmarks = g_list_insert_before (bookmark->group->bookmarks, g_list_previous (elem), bookmark);
+    g_list_remove_link (bookmark->group->bookmarks, elem);
+
+    GtkTreePath *path = gtk_tree_model_get_path (model, &iter);
+    GtkTreeIter prev;
+    gtk_tree_path_prev (path);
+    gtk_tree_model_get_iter (model, &prev, path);
+    gtk_tree_path_free (path);
+
+    gtk_tree_store_swap (GTK_TREE_STORE (model), &prev, &iter);
+
+    gtk_widget_set_sensitive ((GtkWidget *) g_object_get_data (G_OBJECT (dialog), "up-button"), bookmark!=NULL && bookmark->group->bookmarks->data!=bookmark);
+    gtk_widget_set_sensitive ((GtkWidget *) g_object_get_data (G_OBJECT (dialog), "down-button"), bookmark!=NULL && gtk_tree_model_iter_next (model, &iter));
+}
+
+
+static void down_clicked_callback (GtkButton *button, GtkWidget *view)
+{
+    GtkWidget *dialog = gtk_widget_get_ancestor (view, GTK_TYPE_DIALOG);
+    GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
+    GtkTreeIter iter;
+
+    if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
+        return;
+
+    GnomeCmdBookmark *bookmark = NULL;
+    GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
+    gtk_tree_model_get (model, &iter, COL_BOOKMARK, &bookmark, -1);
+
+    if (!bookmark)
+        return;
+
+    GList *elem = g_list_find (bookmark->group->bookmarks, bookmark);
+
+    if (!elem)
+        return;
+
+    g_list_insert (elem, bookmark, 2);
+    bookmark->group->bookmarks = g_list_remove_link (bookmark->group->bookmarks, elem);
+
+    GtkTreeIter next = iter;
+
+    gtk_tree_model_iter_next (model, &next);
+    gtk_tree_store_swap (GTK_TREE_STORE (model), &iter, &next);
+    gtk_widget_set_sensitive ((GtkWidget *) g_object_get_data (G_OBJECT (dialog), "up-button"), bookmark!=NULL && bookmark->group->bookmarks->data!=bookmark);
+    gtk_widget_set_sensitive ((GtkWidget *) g_object_get_data (G_OBJECT (dialog), "down-button"), bookmark!=NULL && gtk_tree_model_iter_next (model, &iter));
+}
+
+
+static void size_allocate_callback (GtkWidget *widget, GtkAllocation *allocation, gpointer unused)
+{
+    gnome_cmd_data.bookmarks_defaults.width = allocation->width;
+    gnome_cmd_data.bookmarks_defaults.height = allocation->height;
+}
+
+
+static void response_callback (GtkDialog *dialog, int response_id, GtkTreeView *view)
+{
+    switch (response_id)
+    {
+        case GTK_RESPONSE_HELP:
+            gnome_cmd_help_display ("gnome-commander.xml", "gnome-commander-advanced-rename");
+            g_signal_stop_emission_by_name (dialog, "response");
+            break;
+
+        case RESPONSE_JUMP_TO:
+            {
+                GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
+                GtkTreeIter iter;
+
+                if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (view)), NULL, &iter))
+                {
+                    GnomeCmdBookmark *bookmark = NULL;
+
+                    gtk_tree_model_get (model, &iter, COL_BOOKMARK, &bookmark, -1);
+
+                    if (bookmark)
+                        gnome_cmd_bookmark_goto (bookmark);
+                    else
+                        g_signal_stop_emission_by_name (dialog, "response");
+                }
+                else
+                    g_signal_stop_emission_by_name (dialog, "response");
+            }
+
+        case GTK_RESPONSE_CLOSE:
+            break;
+
+        case GTK_RESPONSE_NONE:
+        case GTK_RESPONSE_DELETE_EVENT:
+        case GTK_RESPONSE_CANCEL:
+            break;
+
+        default :
+            g_assert_not_reached ();
+    }
+}
+
+
+void gnome_cmd_bookmark_goto (GnomeCmdBookmark *bookmark)
+{
+    g_return_if_fail (bookmark->group->con != NULL);
+
+    GnomeCmdFileSelector *fs = main_win->fs(ACTIVE);
+    g_return_if_fail (GNOME_CMD_IS_FILE_SELECTOR (fs));
+
+    GnomeCmdCon *current_con = fs->get_connection();
+
+    if (current_con == bookmark->group->con)
+        fs->goto_directory(bookmark->path);
+    else
+    {
+        GnomeCmdCon *con = bookmark->group->con;
+
+        if (con->state == CON_STATE_OPEN)
+        {
+            GnomeCmdDir *dir = gnome_cmd_dir_new (con, gnome_cmd_con_create_path (con, bookmark->path));
+            fs->set_connection(con, dir);
+
+        }
+        else
+        {
+            if (con->base_path)
+                g_object_unref (con->base_path);
+
+            con->base_path = gnome_cmd_con_create_path (con, bookmark->path);
+            gtk_object_ref (GTK_OBJECT (con->base_path));
+            fs->set_connection(con);
+        }
+    }
+}
+
+
+void gnome_cmd_bookmark_add_current (GnomeCmdDir *dir)
+{
+    gchar *path = gnome_cmd_dir_is_local (dir) ? gnome_cmd_file_get_real_path (GNOME_CMD_FILE (dir)) :
+                                                 gnome_cmd_file_get_path (GNOME_CMD_FILE (dir));
+
+    if (!g_utf8_validate (path, -1, NULL))
+    {
+        gnome_cmd_show_message (NULL, _("To bookmark a directory the whole search path to the directory must be in valid UTF-8 encoding"));
+        g_free (path);
+        return;
+    }
+
+    gchar *name = g_strdup (g_basename (path));
+
+    if (gnome_cmd_edit_bookmark_dialog (NULL, _("New Bookmark"), name, path))
+    {
+        GnomeCmdCon *con = gnome_cmd_dir_is_local (dir) ? get_home_con () : gnome_cmd_dir_get_connection (dir);
+        GnomeCmdBookmarkGroup *group = gnome_cmd_con_get_bookmarks (con);
+        GnomeCmdBookmark *bookmark = g_new0 (GnomeCmdBookmark, 1);
+
+        bookmark->name = name;
+        bookmark->path = path;
+        bookmark->group = group;
+
+        group->bookmarks = g_list_append (group->bookmarks, bookmark);
+
+        main_win->update_bookmarks();
+    }
+    else
+    {
+        g_free (name);
+        g_free (path);
+    }
+}
diff --git a/src/dialogs/gnome-cmd-manage-bookmarks-dialog.h b/src/dialogs/gnome-cmd-manage-bookmarks-dialog.h
new file mode 100644
index 0000000..d676bbc
--- /dev/null
+++ b/src/dialogs/gnome-cmd-manage-bookmarks-dialog.h
@@ -0,0 +1,31 @@
+/*
+    GNOME Commander - A GNOME based file manager
+    Copyright (C) 2001-2006 Marcus Bjurman
+    Copyright (C) 2007-2009 Piotr Eljasiak
+
+    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 St, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __GNOME_CMD_MANAGE_BOOKMARKS_DIALOG_H__
+#define __GNOME_CMD_MANAGE_BOOKMARKS_DIALOG_H__
+
+#include "gnome-cmd-data.h"
+
+void gnome_cmd_bookmark_dialog_new (const gchar *title, GtkWindow *parent);
+
+void gnome_cmd_bookmark_goto (GnomeCmdBookmark *bookmark);
+void gnome_cmd_bookmark_add_current (GnomeCmdDir *dir);
+
+#endif // __GNOME_CMD_MANAGE_BOOKMARKS_DIALOG_H__
diff --git a/src/gnome-cmd-data.cc b/src/gnome-cmd-data.cc
index 8c4f24a..21ed41e 100644
--- a/src/gnome-cmd-data.cc
+++ b/src/gnome-cmd-data.cc
@@ -35,7 +35,6 @@
 #include "gnome-cmd-cmdline.h"
 #include "gnome-cmd-main-win.h"
 #include "gnome-cmd-advrename-dialog.h"
-#include "gnome-cmd-bookmark-dialog.h"
 #include "gnome-cmd-user-actions.h"
 #include "filter.h"
 #include "utils.h"
@@ -59,7 +58,6 @@ struct GnomeCmdData::Private
     gchar                *list_font;
     gchar                *theme_icon_dir;
     gchar                *document_icon_dir;
-    guint                bookmark_dialog_col_width[BOOKMARK_DIALOG_NUM_COLUMNS];
     gchar                *start_dirs[2];
     gchar                *last_pattern;
     GList                *auto_load_plugins;
@@ -1260,13 +1258,6 @@ void GnomeCmdData::load()
         g_free (tmp);
     }
 
-    for (gint i=0; i<BOOKMARK_DIALOG_NUM_COLUMNS; i++)
-    {
-        gchar *tmp = g_strdup_printf ("/gnome-commander-size/column-widths/bookmark_dialog_col_width%d", i);
-        priv->bookmark_dialog_col_width[i] = get_int (tmp, bookmark_dialog_default_column_width[i]);
-        g_free (tmp);
-    }
-
     color_mode = (GnomeCmdColorMode) gnome_cmd_data_get_int ("/colors/mode", GNOME_CMD_COLOR_DEEP_BLUE);
 
     gnome_cmd_data_get_color ("/colors/norm_fg", priv->color_themes[GNOME_CMD_COLOR_CUSTOM].norm_fg);
@@ -1614,13 +1605,6 @@ void GnomeCmdData::load_more()
 
 void GnomeCmdData::save()
 {
-    for (gint i=0; i<BOOKMARK_DIALOG_NUM_COLUMNS; i++)
-    {
-        gchar *tmp = g_strdup_printf ("/gnome-commander-size/column-widths/bookmark_dialog_col_width%d", i);
-        gnome_config_set_int (tmp, priv->bookmark_dialog_col_width[i]);
-        g_free (tmp);
-    }
-
     gnome_cmd_data_set_int    ("/options/size_disp_mode", size_disp_mode);
     gnome_cmd_data_set_int    ("/options/perm_disp_mode", perm_disp_mode);
     gnome_cmd_data_set_int    ("/options/layout", layout);
@@ -1898,18 +1882,6 @@ void gnome_cmd_data_set_document_icon_dir (const gchar *dir)
 }
 
 
-void gnome_cmd_data_set_bookmark_dialog_col_width (guint column, gint width)
-{
-    gnome_cmd_data.priv->bookmark_dialog_col_width[column] = width;
-}
-
-
-gint gnome_cmd_data_get_bookmark_dialog_col_width (guint column)
-{
-    return gnome_cmd_data.priv->bookmark_dialog_col_width[column];
-}
-
-
 void gnome_cmd_data_set_start_dir (gboolean fs, const gchar *start_dir)
 {
     if (gnome_cmd_data.priv->start_dirs[fs])
diff --git a/src/gnome-cmd-data.h b/src/gnome-cmd-data.h
index d2d0dd6..b55e4f9 100644
--- a/src/gnome-cmd-data.h
+++ b/src/gnome-cmd-data.h
@@ -312,9 +312,6 @@ void gnome_cmd_data_set_theme_icon_dir (const gchar *dir);
 const gchar *gnome_cmd_data_get_document_icon_dir ();
 void gnome_cmd_data_set_document_icon_dir (const gchar *dir);
 
-gint gnome_cmd_data_get_bookmark_dialog_col_width (guint column);
-void gnome_cmd_data_set_bookmark_dialog_col_width (guint column, gint width);
-
 const gchar *gnome_cmd_data_get_start_dir (gboolean fs);
 void gnome_cmd_data_set_start_dir (gboolean fs, const gchar *start_dir);
 
diff --git a/src/gnome-cmd-main-menu.cc b/src/gnome-cmd-main-menu.cc
index 4d614fc..45a1577 100644
--- a/src/gnome-cmd-main-menu.cc
+++ b/src/gnome-cmd-main-menu.cc
@@ -23,7 +23,6 @@
 #include "gnome-cmd-includes.h"
 #include "gnome-cmd-main-menu.h"
 #include "gnome-cmd-types.h"
-#include "gnome-cmd-bookmark-dialog.h"
 #include "gnome-cmd-main-win.h"
 #include "gnome-cmd-file-selector.h"
 #include "gnome-cmd-con.h"
@@ -32,6 +31,7 @@
 #include "utils.h"
 #include "imageloader.h"
 #include "gnome-cmd-user-actions.h"
+#include "dialogs/gnome-cmd-manage-bookmarks-dialog.h"
 
 #include "../pixmaps/exec_wheel.xpm"
 
diff --git a/src/gnome-cmd-main-win.cc b/src/gnome-cmd-main-win.cc
index 1dd0df6..5424c83 100644
--- a/src/gnome-cmd-main-win.cc
+++ b/src/gnome-cmd-main-win.cc
@@ -37,9 +37,9 @@
 #include "gnome-cmd-plain-path.h"
 #include "gnome-cmd-con.h"
 #include "gnome-cmd-con-list.h"
-#include "gnome-cmd-bookmark-dialog.h"
 #include "owner.h"
 #include "utils.h"
+#include "dialogs/gnome-cmd-manage-bookmarks-dialog.h"
 
 #include "../pixmaps/copy_file_names.xpm"
 
diff --git a/src/gnome-cmd-types.h b/src/gnome-cmd-types.h
index 257f4aa..6bfe66f 100644
--- a/src/gnome-cmd-types.h
+++ b/src/gnome-cmd-types.h
@@ -92,7 +92,6 @@ struct GnomeCmdBookmarkGroup
 {
     GList *bookmarks;
     GnomeCmdCon *con;
-    gpointer *data;
 };
 
 
diff --git a/src/gnome-cmd-user-actions.cc b/src/gnome-cmd-user-actions.cc
index 30b2127..e770d48 100644
--- a/src/gnome-cmd-user-actions.cc
+++ b/src/gnome-cmd-user-actions.cc
@@ -23,7 +23,6 @@
 #include <algorithm>
 
 #include "gnome-cmd-includes.h"
-#include "gnome-cmd-bookmark-dialog.h"
 #include "gnome-cmd-con.h"
 #include "gnome-cmd-con-list.h"
 #include "gnome-cmd-data.h"
@@ -45,6 +44,7 @@
 #include "gnome-cmd-key-shortcuts-dialog.h"
 #include "gnome-cmd-chmod-dialog.h"
 #include "gnome-cmd-chown-dialog.h"
+#include "dialogs/gnome-cmd-manage-bookmarks-dialog.h"
 #include "gnome-cmd-user-actions.h"
 #include "plugin_manager.h"
 #include "cap.h"
@@ -1522,15 +1522,13 @@ void connections_close_current (GtkMenuItem *menuitem, gpointer not_used)
 
 void bookmarks_add_current (GtkMenuItem *menuitem, gpointer not_used)
 {
-    gnome_cmd_bookmark_add_current ();
+    gnome_cmd_bookmark_add_current (get_fs (ACTIVE)->get_directory());
 }
 
 
 void bookmarks_edit (GtkMenuItem *menuitem, gpointer not_used)
 {
-    GtkWidget *dialog = gnome_cmd_bookmark_dialog_new ();
-    gtk_widget_ref (dialog);
-    gtk_widget_show (dialog);
+    gnome_cmd_bookmark_dialog_new (_("Bookmarks"), *main_win);
 }
 
 



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