diff src/gtk/bookmarks.c @ 48:e5f6054590b5

2002-11-5 Brian Masney <masneyb@gftp.org> * lib/*.c src/gtk/*.c - removed function declarations for the static functions from the top of the file. I had to rearrange the order of a bunch of functions to avoid compiler warnings * lib/gftp.h - include sys/sysmacros.h. If major() and minor() isn't defined, give a compiler warning and define our own * lib/local.c (local_get_next_file) - if this file is a device, store the major/minor number in the file size * src/gtk/misc-gtk.c (add_file_listbox) - if this file is a device, use the major() and minor() macros to display the major and minor number
author masneyb
date Wed, 06 Nov 2002 02:20:25 +0000
parents 311e29c40ed6
children c226809c03c8
line wrap: on
line diff
--- a/src/gtk/bookmarks.c	Tue Nov 05 20:36:11 2002 +0000
+++ b/src/gtk/bookmarks.c	Wed Nov 06 02:20:25 2002 +0000
@@ -20,39 +20,6 @@
 #include "gftp-gtk.h"
 static const char cvsid[] = "$Id$";
 
-static void doadd_bookmark 			( gpointer * data,
-						  gftp_dialog_data * ddata);
-static void bm_apply_changes 			( GtkWidget * widget, 
-						  gpointer backup_data );
-static gftp_bookmarks * copy_bookmarks 		( gftp_bookmarks * bookmarks );
-static void bm_close_dialog 			( GtkWidget * widget, 
-						  GtkWidget * dialog );
-static void after_move 				( GtkCTree * ctree, 
-						  GtkCTreeNode * child, 
-						  GtkCTreeNode * parent, 
-						  GtkCTreeNode * sibling, 
-						  gpointer data );
-static gint bm_dblclick 			( GtkWidget * widget, 
-						  GdkEventButton * event, 
-						  gpointer data );
-static gint bm_enter 				( GtkWidget * widget, 
-						  GdkEventKey * event, 
-						  gpointer data );
-static void new_folder_entry 			( gpointer data );
-static void do_make_new 			( gpointer data,
-						  gftp_dialog_data * ddata );
-static void new_item_entry 			( gpointer data );
-static void edit_entry 				( gpointer data );
-static void delete_entry 			( gpointer data );
-static void do_delete_entry 			( gftp_bookmarks * entry,
-						  gftp_dialog_data * ddata );
-static void entry_apply_changes 		( GtkWidget * widget, 
-						  gftp_bookmarks * entry );
-static void set_userpass_visible 		( GtkWidget * checkbutton, 
-						  GtkWidget * entry );
-static void build_bookmarks_tree 		( void );
-static void clear_bookmarks_tree 		( void );
-
 static GtkWidget * bm_hostedit, * bm_portedit, * bm_localdiredit,
   * bm_remotediredit, * bm_useredit, * bm_passedit, * bm_acctedit, * anon_chk,
   * bm_pathedit, * bm_protocol, * tree, *bm_sftppath;
@@ -132,25 +99,6 @@
   ftp_connect (current_wdata, current_wdata->request, 1);
 }
 
-void
-add_bookmark (gpointer data)
-{
-  const char *edttxt;
-
-  if (!check_status (_("Add Bookmark"), current_wdata, 0, 0, 0, 1))
-    return;
-
-  edttxt = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (hostedit)->entry));
-  if (*edttxt == '\0')
-    {
-      ftp_log (gftp_logging_error, NULL,
-	       _("Add Bookmark: You must enter a hostname\n"));
-      return;
-    }
-
-  MakeEditDialog (_("Add Bookmark"), _("Enter the name of the bookmark you want to add\nYou can separate items by a / to put it into a submenu\n(ex: Linux Sites/Debian)"), NULL, 1, _("Remember password"), gftp_dialog_button_create, doadd_bookmark, data, NULL, NULL);
-}
-
 
 static void
 doadd_bookmark (gpointer * data, gftp_dialog_data * ddata)
@@ -230,6 +178,26 @@
 
 
 void
+add_bookmark (gpointer data)
+{
+  const char *edttxt;
+
+  if (!check_status (_("Add Bookmark"), current_wdata, 0, 0, 0, 1))
+    return;
+
+  edttxt = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (hostedit)->entry));
+  if (*edttxt == '\0')
+    {
+      ftp_log (gftp_logging_error, NULL,
+	       _("Add Bookmark: You must enter a hostname\n"));
+      return;
+    }
+
+  MakeEditDialog (_("Add Bookmark"), _("Enter the name of the bookmark you want to add\nYou can separate items by a / to put it into a submenu\n(ex: Linux Sites/Debian)"), NULL, 1, _("Remember password"), gftp_dialog_button_create, doadd_bookmark, data, NULL, NULL);
+}
+
+
+void
 build_bookmarks_menu (void)
 {
   GtkItemFactoryEntry test = { NULL, NULL, NULL, 0 };
@@ -265,132 +233,6 @@
 }
 
 
-#if GTK_MAJOR_VERSION > 1 
-static void
-editbm_action (GtkWidget * widget, gint response, gpointer user_data)
-{
-  switch (response)
-    {
-      case GTK_RESPONSE_OK:
-        bm_apply_changes (widget, NULL);
-        /* no break */
-      default:
-        bm_close_dialog (NULL, widget);
-    }
-}
-#endif
-
-
-void
-edit_bookmarks (gpointer data)
-{
-  GtkWidget * dialog, * scroll;
-  GtkItemFactory * ifactory;
-  GtkItemFactoryEntry menu_items[] = {
-    {N_("/_File"), NULL, 0, 0, "<Branch>"},
-    {N_("/File/tearoff"), NULL, 0, 0, "<Tearoff>"},
-    {N_("/File/New Folder..."), NULL, new_folder_entry, 0, MN_(NULL)},
-    {N_("/File/New Item..."), NULL, new_item_entry, 0, MS_(GTK_STOCK_NEW)},
-    {N_("/File/Delete"), NULL, delete_entry, 0, MS_(GTK_STOCK_DELETE)},
-    {N_("/File/Properties..."), NULL, edit_entry, 0, MS_(GTK_STOCK_PROPERTIES)},
-    {N_("/File/sep"), NULL, 0, 0, "<Separator>"},
-    {N_("/File/Close"), NULL, gtk_widget_destroy, 0, MS_(GTK_STOCK_CLOSE)}
-  };
-#if GTK_MAJOR_VERSION == 1
-  GtkWidget * tempwid;
-#endif
-
-  new_bookmarks = copy_bookmarks (bookmarks);
-  new_bookmarks_htable = build_bookmarks_hash_table (new_bookmarks);
-
-#if GTK_MAJOR_VERSION == 1
-  dialog = gtk_dialog_new ();
-  gtk_window_set_title (GTK_WINDOW (dialog), _("Edit Bookmarks"));
-  gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->action_area), 15);
-#else
-  dialog = gtk_dialog_new_with_buttons (_("Edit Bookmarks"), NULL, 0,
-                                        GTK_STOCK_SAVE,
-                                        GTK_RESPONSE_OK,
-                                        GTK_STOCK_CANCEL,
-                                        GTK_RESPONSE_CANCEL,
-                                        NULL);
-#endif
-  gtk_window_set_wmclass (GTK_WINDOW(dialog), "Edit Bookmarks", "gFTP");
-  gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
-  gtk_widget_realize (dialog);
-
-  if (gftp_icon != NULL)
-    {
-      gdk_window_set_icon (dialog->window, NULL, gftp_icon->pixmap,
-                           gftp_icon->bitmap);
-      gdk_window_set_icon_name (dialog->window, _("gFTP Icon"));
-    }
-
-  /* FIXME - memory leak */
-  ifactory = item_factory_new (GTK_TYPE_MENU_BAR, "<bookmarks>", NULL, NULL);
-  create_item_factory (ifactory, 7, menu_items, NULL);
-  create_item_factory (ifactory, 1, menu_items + 7, dialog);
-  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), ifactory->widget,
-		      FALSE, FALSE, 0);
-  gtk_widget_show (ifactory->widget);
-
-  scroll = gtk_scrolled_window_new (NULL, NULL);
-  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
-				  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-  gtk_widget_set_size_request (scroll, 150, 200);
-
-  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), scroll, TRUE, TRUE,
-		      0);
-  gtk_container_border_width (GTK_CONTAINER (scroll), 3);
-  gtk_widget_show (scroll);
-
-  /* FIXME - memory leak */
-  edit_factory = item_factory_new (GTK_TYPE_MENU, "<edit_bookmark>", NULL, "/File");
-
-  create_item_factory (edit_factory, 6, menu_items + 2, dialog);
-
-  tree = gtk_ctree_new (1, 0);
-  gtk_clist_set_selection_mode (GTK_CLIST (tree), GTK_SELECTION_BROWSE);
-  gtk_clist_set_reorderable (GTK_CLIST (tree), 1);
-  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scroll), tree);
-  gtk_signal_connect_after (GTK_OBJECT (tree), "key_press_event",
-			    GTK_SIGNAL_FUNC (bm_enter), (gpointer) tree);
-  gtk_signal_connect_after (GTK_OBJECT (tree), "tree_move",
-			    GTK_SIGNAL_FUNC (after_move), NULL);
-  gtk_signal_connect_after (GTK_OBJECT (tree), "button_press_event",
-			    GTK_SIGNAL_FUNC (bm_dblclick), (gpointer) tree);
-  gtk_widget_show (tree);
-
-#if GTK_MAJOR_VERSION == 1
-  tempwid = gtk_button_new_with_label (_("OK"));
-  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), tempwid,
-		      TRUE, TRUE, 0);
-  gtk_signal_connect (GTK_OBJECT (tempwid), "clicked",
-		      GTK_SIGNAL_FUNC (bm_apply_changes), NULL);
-  gtk_signal_connect (GTK_OBJECT (tempwid), "clicked",
-		      GTK_SIGNAL_FUNC (bm_close_dialog), (gpointer) dialog);
-  GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT);
-  gtk_widget_show (tempwid);
-
-  tempwid = gtk_button_new_with_label (_("  Cancel  "));
-  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), tempwid,
-		      TRUE, TRUE, 0);
-  gtk_signal_connect (GTK_OBJECT (tempwid), "clicked",
-		      GTK_SIGNAL_FUNC (bm_close_dialog), (gpointer) dialog);
-  GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT);
-  gtk_widget_grab_focus (tempwid);
-  gtk_widget_show (tempwid);
-#else
-  g_signal_connect (GTK_OBJECT (dialog), "response",
-                    G_CALLBACK (editbm_action), NULL);
-#endif
-
-  gtk_widget_show (dialog);
-
-  build_bookmarks_tree ();
-}
-
-
 static void
 free_bookmark_entry_items (gftp_bookmarks * entry)
 {
@@ -411,87 +253,6 @@
 }
 
 
-static void
-bm_apply_changes (GtkWidget * widget, gpointer backup_data)
-{
-  gftp_bookmarks * tempentry, * delentry;
-  char *tempstr;
-
-  tempentry = bookmarks->children;
-  while (tempentry != NULL)
-    {
-      if (tempentry->path && !tempentry->isfolder)
-	{
-	  tempstr = g_strdup_printf ("/Bookmarks/%s", tempentry->path);
-          gtk_widget_destroy (gtk_item_factory_get_item (factory, tempstr));
-	  g_free (tempentry->path);
-	  g_free (tempstr);
-	}
-
-      free_bookmark_entry_items (tempentry);
-
-      if (tempentry->children != NULL)
-	tempentry = tempentry->children;
-      else
-	{
-	  if (tempentry->next == NULL)
-	    {
-	      while (tempentry->next == NULL && tempentry->prev != NULL)
-		{
-		  delentry = tempentry;
-		  tempentry = tempentry->prev;
-		  if (delentry->isfolder)
-		    {
-		      tempstr = g_strdup_printf ("/Bookmarks/%s", 
-                                                 delentry->path);
-                      gtk_widget_destroy (gtk_item_factory_get_item (factory, 
-                                                                     tempstr));
-		      g_free (tempstr);
-		      g_free (delentry->path);
-		    }
-		  g_free (delentry);
-		}
-	      delentry = tempentry;
-	      tempentry = tempentry->next;
-	      if (delentry->isfolder && tempentry != NULL)
-		{
-		  tempstr = g_strdup_printf ("/Bookmarks/%s", 
-                                             delentry->path);
-                    gtk_widget_destroy (gtk_item_factory_get_item (factory, 
-                                                                   tempstr));
-		  g_free (delentry->path);
-		  g_free (tempstr);
-		  g_free (delentry);
-		}
-	    }
-	  else
-	    {
-	      delentry = tempentry;
-	      tempentry = tempentry->next;
-	      g_free (delentry);
-	    }
-	}
-    }
-  g_free (bookmarks);
-  g_hash_table_destroy (bookmarks_htable);
-
-  bookmarks = new_bookmarks;
-  bookmarks_htable = new_bookmarks_htable;
-  if (backup_data)
-    {
-      new_bookmarks = copy_bookmarks (bookmarks);
-      new_bookmarks_htable = build_bookmarks_hash_table (new_bookmarks);
-    }
-  else
-    {
-      new_bookmarks = NULL;
-      new_bookmarks_htable = NULL;
-    }
-  build_bookmarks_menu ();
-  gftp_write_bookmarks_file ();
-}
-
-
 static gftp_bookmarks *
 copy_bookmarks (gftp_bookmarks * bookmarks)
 {
@@ -605,6 +366,87 @@
 
 
 static void
+bm_apply_changes (GtkWidget * widget, gpointer backup_data)
+{
+  gftp_bookmarks * tempentry, * delentry;
+  char *tempstr;
+
+  tempentry = bookmarks->children;
+  while (tempentry != NULL)
+    {
+      if (tempentry->path && !tempentry->isfolder)
+	{
+	  tempstr = g_strdup_printf ("/Bookmarks/%s", tempentry->path);
+          gtk_widget_destroy (gtk_item_factory_get_item (factory, tempstr));
+	  g_free (tempentry->path);
+	  g_free (tempstr);
+	}
+
+      free_bookmark_entry_items (tempentry);
+
+      if (tempentry->children != NULL)
+	tempentry = tempentry->children;
+      else
+	{
+	  if (tempentry->next == NULL)
+	    {
+	      while (tempentry->next == NULL && tempentry->prev != NULL)
+		{
+		  delentry = tempentry;
+		  tempentry = tempentry->prev;
+		  if (delentry->isfolder)
+		    {
+		      tempstr = g_strdup_printf ("/Bookmarks/%s", 
+                                                 delentry->path);
+                      gtk_widget_destroy (gtk_item_factory_get_item (factory, 
+                                                                     tempstr));
+		      g_free (tempstr);
+		      g_free (delentry->path);
+		    }
+		  g_free (delentry);
+		}
+	      delentry = tempentry;
+	      tempentry = tempentry->next;
+	      if (delentry->isfolder && tempentry != NULL)
+		{
+		  tempstr = g_strdup_printf ("/Bookmarks/%s", 
+                                             delentry->path);
+                    gtk_widget_destroy (gtk_item_factory_get_item (factory, 
+                                                                   tempstr));
+		  g_free (delentry->path);
+		  g_free (tempstr);
+		  g_free (delentry);
+		}
+	    }
+	  else
+	    {
+	      delentry = tempentry;
+	      tempentry = tempentry->next;
+	      g_free (delentry);
+	    }
+	}
+    }
+  g_free (bookmarks);
+  g_hash_table_destroy (bookmarks_htable);
+
+  bookmarks = new_bookmarks;
+  bookmarks_htable = new_bookmarks_htable;
+  if (backup_data)
+    {
+      new_bookmarks = copy_bookmarks (bookmarks);
+      new_bookmarks_htable = build_bookmarks_hash_table (new_bookmarks);
+    }
+  else
+    {
+      new_bookmarks = NULL;
+      new_bookmarks_htable = NULL;
+    }
+  build_bookmarks_menu ();
+  gftp_write_bookmarks_file ();
+}
+
+
+static void
 bm_close_dialog (GtkWidget * widget, GtkWidget * dialog)
 {
   gftp_bookmarks * tempentry, * delentry;
@@ -642,142 +484,20 @@
 }
 
 
+#if GTK_MAJOR_VERSION > 1 
 static void
-after_move (GtkCTree * ctree, GtkCTreeNode * child, GtkCTreeNode * parent,
-	    GtkCTreeNode * sibling, gpointer data)
+editbm_action (GtkWidget * widget, gint response, gpointer user_data)
 {
-
-  gftp_bookmarks * childentry, * siblingentry, * parententry, * tempentry;
-  char *tempstr, *pos, *stpos;
-
-  childentry = gtk_ctree_node_get_row_data (ctree, child);
-  parententry = gtk_ctree_node_get_row_data (ctree, parent);
-  siblingentry = gtk_ctree_node_get_row_data (ctree, sibling);
-
-  tempentry = childentry->prev->children;
-  if (tempentry == childentry)
-    childentry->prev->children = childentry->prev->children->next;
-  else
-    {
-      while (tempentry->next != childentry)
-	tempentry = tempentry->next;
-      tempentry->next = childentry->next;
-    }
-  childentry->prev = parententry;
-  if (!parententry->isfolder)
-    {
-      childentry->next = parententry->children;
-      parententry->children = childentry;
-      gtk_ctree_move (ctree, child, parententry->prev->cnode,
-		      parententry->cnode);
-    }
-  else
+  switch (response)
     {
-      if (siblingentry == NULL || parententry->children == siblingentry)
-	{
-	  childentry->next = parententry->children;
-	  parententry->children = childentry;
-	}
-      else
-	{
-	  tempentry = parententry->children;
-	  while (tempentry->next != siblingentry)
-	    tempentry = tempentry->next;
-	  childentry->next = tempentry->next;
-	  tempentry->next = childentry;
-	}
-
-      tempentry = childentry;
-      while (tempentry != NULL)
-	{
-	  g_hash_table_remove (new_bookmarks_htable, tempentry->path);
-	  if ((pos = strrchr (tempentry->path, '/')) == NULL)
-	    pos = tempentry->path;
-	  else
-	    pos++;
-	  tempstr = g_strdup_printf ("%s/%s", tempentry->prev->path, pos);
-	  for (stpos = tempstr; *stpos == '/'; stpos++);
-	  g_free (tempentry->path);
-	  tempentry->path = g_malloc (strlen (stpos) + 1);
-	  strcpy (tempentry->path, stpos);
-	  g_free (tempstr);
-	  g_hash_table_insert (new_bookmarks_htable, tempentry->path,
-			       tempentry);
-	  if (tempentry->children != NULL)
-	    tempentry = tempentry->children;
-	  else
-	    {
-	      if (tempentry->next == NULL)
-		{
-		  if (tempentry->prev == childentry)
-		    break;
-		  else
-		    {
-		      while (tempentry->next == NULL
-			     && tempentry->prev != NULL)
-			tempentry = tempentry->prev;
-		    }
-		}
-	      tempentry = tempentry->next;
-	    }
-	}
+      case GTK_RESPONSE_OK:
+        bm_apply_changes (widget, NULL);
+        /* no break */
+      default:
+        bm_close_dialog (NULL, widget);
     }
 }
-
-
-static gint
-bm_dblclick (GtkWidget * widget, GdkEventButton * event, gpointer data)
-{
-  if (event->button == 3)
-    gtk_item_factory_popup (edit_factory, (guint) event->x_root,
-			    (guint) event->y_root, 1, 0);
-  else if (event->type == GDK_2BUTTON_PRESS)
-    {
-      edit_entry (NULL);
-      return (FALSE);
-    }
-  return (TRUE);
-}
-
-
-static gint
-bm_enter (GtkWidget * widget, GdkEventKey * event, gpointer data)
-{
-  if (event->type == GDK_KEY_PRESS)
-    {
-      if (event->keyval == GDK_Return || event->keyval == GDK_KP_Enter)
-	{
-	  edit_entry (NULL);
-	  return (FALSE);
-	}
-      else if (event->keyval == GDK_KP_Delete || event->keyval == GDK_Delete)
-	{
-	  delete_entry (NULL);
-	  return (FALSE);
-	}
-    }
-  return (TRUE);
-}
-
-
-static void
-new_folder_entry (gpointer data)
-{
-  MakeEditDialog (_("New Folder"),
-		  _("Enter the name of the new folder to create"), NULL, 1,
-		  NULL, gftp_dialog_button_create, 
-                  do_make_new, (gpointer) 0x1, NULL, NULL);
-}
-
-
-static void
-new_item_entry (gpointer data)
-{
-  MakeEditDialog (_("New Folder"),
-		  _("Enter the name of the new item to create"), NULL, 1,
-		  NULL, gftp_dialog_button_create,
-                  do_make_new, NULL, NULL, NULL);
-}
+#endif
 
 
 static void
@@ -851,6 +571,353 @@
 }
 
 
+static void
+new_folder_entry (gpointer data)
+{
+  MakeEditDialog (_("New Folder"),
+		  _("Enter the name of the new folder to create"), NULL, 1,
+		  NULL, gftp_dialog_button_create, 
+                  do_make_new, (gpointer) 0x1, NULL, NULL);
+}
+
+
+static void
+new_item_entry (gpointer data)
+{
+  MakeEditDialog (_("New Folder"),
+		  _("Enter the name of the new item to create"), NULL, 1,
+		  NULL, gftp_dialog_button_create,
+                  do_make_new, NULL, NULL, NULL);
+}
+
+
+static void
+do_delete_entry (gftp_bookmarks * entry, gftp_dialog_data * ddata)
+{
+  gftp_bookmarks * tempentry, * delentry;
+
+  g_hash_table_remove (new_bookmarks_htable, entry->path);
+  gtk_ctree_remove_node (GTK_CTREE (tree), entry->cnode);
+  if (entry->prev->children == entry)
+    entry->prev->children = entry->prev->children->next;
+  else
+    {
+      tempentry = entry->prev->children;
+      while (tempentry->next != entry)
+	tempentry = tempentry->next;
+      tempentry->next = entry->next;
+    }
+
+  entry->prev = NULL;
+  entry->next = NULL;
+  tempentry = entry;
+  while (tempentry != NULL)
+    {
+      if (tempentry->path)
+	g_free (tempentry->path);
+      if (tempentry->hostname)
+	g_free (tempentry->hostname);
+      if (tempentry->remote_dir)
+	g_free (tempentry->remote_dir);
+      if (tempentry->user)
+	g_free (tempentry->user);
+      if (tempentry->pass)
+	g_free (tempentry->pass);
+      if (tempentry->sftpserv_path)
+        g_free (tempentry->sftpserv_path);
+
+      if (tempentry->children != NULL)
+	{
+	  tempentry = tempentry->children;
+	  continue;
+	}
+      else if (tempentry->next == NULL && tempentry->prev != NULL)
+	{
+	  delentry = tempentry->prev;
+	  g_free (tempentry);
+	  tempentry = delentry->next;
+	  if (delentry != entry)
+	    g_free (delentry);
+	}
+      else
+	tempentry = tempentry->next;
+    }
+  g_free (entry);
+}
+
+
+static void
+delete_entry (gpointer data)
+{
+  gftp_bookmarks * entry;
+  char *tempstr, *pos;
+
+  if (GTK_CLIST (tree)->selection == NULL)
+    return;
+  entry =
+    gtk_ctree_node_get_row_data (GTK_CTREE (tree),
+				 GTK_CLIST (tree)->selection->data);
+  if (entry == NULL || entry->prev == NULL)
+    return;
+
+  if (!entry->isfolder)
+    do_delete_entry (entry, NULL);
+  else
+    {
+      if ((pos = strrchr (entry->path, '/')) == NULL)
+	pos = entry->path;
+      else
+	pos++;
+
+      tempstr = g_strdup_printf (_("Are you sure you want to erase the bookmark\n%s and all it's children?"), pos);
+      MakeYesNoDialog (_("Delete Bookmark"), tempstr, do_delete_entry, entry, 
+                       NULL, NULL);
+      g_free (tempstr);
+    }
+}
+
+
+static void
+set_userpass_visible (GtkWidget * checkbutton, GtkWidget * entry)
+{
+  gtk_widget_set_sensitive (bm_useredit, !GTK_TOGGLE_BUTTON (anon_chk)->active);
+  gtk_widget_set_sensitive (bm_passedit, !GTK_TOGGLE_BUTTON (anon_chk)->active);
+  gtk_widget_set_sensitive (bm_acctedit, !GTK_TOGGLE_BUTTON (anon_chk)->active);
+}
+
+
+static void
+build_bookmarks_tree (void)
+{
+  GdkPixmap * closedir_pixmap, * opendir_pixmap;
+  GdkBitmap * closedir_bitmap, * opendir_bitmap;  
+  gftp_bookmarks * tempentry, * preventry;
+  char *pos, *prevpos, *text[2], *str;
+  GtkCTreeNode * parent;
+
+  gftp_get_pixmap (tree, "open_dir.xpm", &opendir_pixmap, &opendir_bitmap);
+  gftp_get_pixmap (tree, "dir.xpm", &closedir_pixmap, &closedir_bitmap);
+  text[0] = text[1] = _("Bookmarks");
+  parent = gtk_ctree_insert_node (GTK_CTREE (tree), NULL, NULL, text, 5, 
+                                  closedir_pixmap, closedir_bitmap, 
+                                  opendir_pixmap, opendir_bitmap, FALSE, TRUE);
+  gtk_ctree_node_set_row_data (GTK_CTREE (tree), parent, new_bookmarks);
+  new_bookmarks->cnode = parent;
+
+  tempentry = new_bookmarks->children;
+  while (tempentry != NULL)
+    {
+      tempentry->cnode = NULL;
+      if (tempentry->children != NULL)
+	{
+	  tempentry = tempentry->children;
+	  continue;
+	}
+      else
+	{
+	  pos = tempentry->path;
+	  while ((pos = strchr (pos, '/')) != NULL)
+	    {
+	      *pos = '\0';
+	      str = g_malloc (strlen (tempentry->path) + 1);
+	      strcpy (str, tempentry->path);
+	      *pos = '/';
+	      preventry = g_hash_table_lookup (new_bookmarks_htable, str);
+	      if (preventry->cnode == NULL)
+		{
+		  if ((prevpos = strrchr (str, '/')) == NULL)
+		    prevpos = str;
+		  else
+		    prevpos++;
+		  text[0] = text[1] = prevpos;
+		  preventry->cnode = gtk_ctree_insert_node (GTK_CTREE (tree),
+					   preventry->prev->cnode, NULL, text,
+					   5, closedir_pixmap, closedir_bitmap,
+					   opendir_pixmap, opendir_bitmap,
+					   FALSE, FALSE);
+		  gtk_ctree_node_set_row_data (GTK_CTREE (tree),
+					       preventry->cnode, preventry);
+		}
+
+	      g_free (str);
+	      pos++;
+	    }
+	}
+
+      if ((pos = strrchr (tempentry->path, '/')) == NULL)
+	pos = tempentry->path;
+      else
+	pos++;
+
+      text[0] = text[1] = pos;
+      tempentry->cnode = gtk_ctree_insert_node (GTK_CTREE (tree), 
+                               tempentry->prev->cnode, NULL,
+			       text, 5, NULL, NULL, NULL, NULL, FALSE, FALSE);
+      gtk_ctree_node_set_row_data (GTK_CTREE (tree), tempentry->cnode,
+				   tempentry);
+
+      while (tempentry->next == NULL && tempentry->prev != NULL)
+	tempentry = tempentry->prev;
+      tempentry = tempentry->next;
+    }
+}
+
+
+static void
+clear_bookmarks_tree (void)
+{
+  gftp_bookmarks * tempentry;
+
+  tempentry = new_bookmarks->children;
+  while (tempentry != NULL)
+    {
+      if (tempentry->children != NULL)
+	{
+	  tempentry = tempentry->children;
+	  continue;
+	}
+      while (tempentry->next == NULL && tempentry->prev != NULL)
+	{
+	  gtk_ctree_remove_node (GTK_CTREE (tree), tempentry->cnode);
+	  tempentry->cnode = NULL;
+	  tempentry = tempentry->prev;
+	}
+      gtk_ctree_remove_node (GTK_CTREE (tree), tempentry->cnode);
+      tempentry->cnode = NULL;
+      tempentry = tempentry->next;
+    }
+}
+
+
+static void
+entry_apply_changes (GtkWidget * widget, gftp_bookmarks * entry)
+{
+  char *pos, *newpath, tempchar, *tempstr, *origpath;
+  gftp_bookmarks * tempentry, * nextentry;
+  GtkWidget * tempwid;
+  const char *str;
+  int oldpathlen;
+
+  oldpathlen = strlen (entry->path);
+  if ((pos = strrchr (entry->path, '/')) == NULL)
+    {
+      pos = entry->path;
+      tempchar = *entry->path;
+      *entry->path = '\0';
+    }
+  else
+    {
+      tempchar = *pos;
+      *pos = '\0';
+    }
+  origpath = newpath = g_strconcat (entry->path, "/",
+                         gtk_entry_get_text (GTK_ENTRY (bm_pathedit)), NULL);
+  remove_double_slashes (newpath);
+  for (; *newpath == '/'; newpath++);
+  *pos = tempchar;
+
+  str = gtk_entry_get_text (GTK_ENTRY (bm_hostedit));
+  if (entry->hostname)
+    g_free (entry->hostname);
+  entry->hostname = g_malloc (strlen (str) + 1);
+  strcpy (entry->hostname, str);
+
+  str = gtk_entry_get_text (GTK_ENTRY (bm_portedit));
+  entry->port = strtol (str, NULL, 10);
+
+  tempwid = gtk_menu_get_active (GTK_MENU (bm_protocol));
+  str = gtk_object_get_user_data (GTK_OBJECT (tempwid));
+  if (entry->protocol)
+    g_free (entry->protocol);
+  entry->protocol = g_malloc (strlen (str) + 1);
+  strcpy (entry->protocol, str);
+
+  str = gtk_entry_get_text (GTK_ENTRY (bm_remotediredit));
+  if (entry->remote_dir)
+    g_free (entry->remote_dir);
+  entry->remote_dir = g_malloc (strlen (str) + 1);
+  strcpy (entry->remote_dir, str);
+
+  str = gtk_entry_get_text (GTK_ENTRY (bm_localdiredit));
+  if (entry->local_dir)
+    g_free (entry->local_dir);
+  entry->local_dir = g_malloc (strlen (str) + 1);
+  strcpy (entry->local_dir, str);
+
+  str = gtk_entry_get_text (GTK_ENTRY (bm_sftppath));
+  if (entry->sftpserv_path)
+    g_free (entry->sftpserv_path);
+  if (strlen (str) > 0)
+    {
+      entry->sftpserv_path = g_malloc (strlen (str) + 1);
+      strcpy (entry->sftpserv_path, str);
+    }
+  else
+    entry->sftpserv_path = NULL;
+
+  if (GTK_TOGGLE_BUTTON (anon_chk)->active)
+    str = "anonymous";
+  else
+    str = gtk_entry_get_text (GTK_ENTRY (bm_useredit));
+  if (entry->user)
+    g_free (entry->user);
+  entry->user = g_malloc (strlen (str) + 1);
+  strcpy (entry->user, str);
+
+  if (GTK_TOGGLE_BUTTON (anon_chk)->active)
+    str = "@EMAIL@";
+  else
+    str = gtk_entry_get_text (GTK_ENTRY (bm_passedit));
+  if (entry->pass)
+    g_free (entry->pass);
+  entry->pass = g_malloc (strlen (str) + 1);
+  strcpy (entry->pass, str);
+  entry->save_password = *entry->pass != '\0';
+
+  if (GTK_TOGGLE_BUTTON (anon_chk)->active)
+    str = "";
+  else
+    str = gtk_entry_get_text (GTK_ENTRY (bm_acctedit));
+  if (entry->acct)
+    g_free (entry->acct);
+  entry->acct = g_malloc (strlen (str) + 1);
+  strcpy (entry->acct, str);
+
+  if (strcmp (entry->path, newpath) != 0)
+    {
+      tempentry = entry;
+      nextentry = entry->next;
+      entry->next = NULL;
+      while (tempentry != NULL)
+	{
+	  g_hash_table_remove (new_bookmarks_htable, tempentry->path);
+	  tempstr = g_strconcat (newpath, "/", tempentry->path + oldpathlen, 
+                                 NULL);
+	  remove_double_slashes (tempstr);
+	  g_free (tempentry->path);
+	  tempentry->path = tempstr;
+	  g_hash_table_insert (new_bookmarks_htable, tempentry->path,
+			       tempentry);
+	  if (tempentry->children != NULL)
+	    {
+	      tempentry = tempentry->children;
+	      continue;
+	    }
+	  while (tempentry->next == NULL && tempentry != entry &&
+		 tempentry->prev != NULL)
+	    tempentry = tempentry->prev;
+
+	  tempentry = tempentry->next;
+	}
+      entry->next = nextentry;
+      clear_bookmarks_tree ();
+      build_bookmarks_tree ();
+    }
+
+  g_free (origpath);
+}
+
+
 #if GTK_MAJOR_VERSION > 1
 static void
 bmedit_action (GtkWidget * widget, gint response, gpointer user_data)
@@ -1131,329 +1198,230 @@
 }
 
 
-static void
-delete_entry (gpointer data)
+static gint
+bm_enter (GtkWidget * widget, GdkEventKey * event, gpointer data)
 {
-  gftp_bookmarks * entry;
-  char *tempstr, *pos;
-
-  if (GTK_CLIST (tree)->selection == NULL)
-    return;
-  entry =
-    gtk_ctree_node_get_row_data (GTK_CTREE (tree),
-				 GTK_CLIST (tree)->selection->data);
-  if (entry == NULL || entry->prev == NULL)
-    return;
-
-  if (!entry->isfolder)
-    do_delete_entry (entry, NULL);
-  else
-    {
-      if ((pos = strrchr (entry->path, '/')) == NULL)
-	pos = entry->path;
-      else
-	pos++;
-
-      tempstr = g_strdup_printf (_("Are you sure you want to erase the bookmark\n%s and all it's children?"), pos);
-      MakeYesNoDialog (_("Delete Bookmark"), tempstr, do_delete_entry, entry, 
-                       NULL, NULL);
-      g_free (tempstr);
-    }
-}
-
-
-static void
-do_delete_entry (gftp_bookmarks * entry, gftp_dialog_data * ddata)
-{
-  gftp_bookmarks * tempentry, * delentry;
-
-  g_hash_table_remove (new_bookmarks_htable, entry->path);
-  gtk_ctree_remove_node (GTK_CTREE (tree), entry->cnode);
-  if (entry->prev->children == entry)
-    entry->prev->children = entry->prev->children->next;
-  else
+  if (event->type == GDK_KEY_PRESS)
     {
-      tempentry = entry->prev->children;
-      while (tempentry->next != entry)
-	tempentry = tempentry->next;
-      tempentry->next = entry->next;
+      if (event->keyval == GDK_Return || event->keyval == GDK_KP_Enter)
+	{
+	  edit_entry (NULL);
+	  return (FALSE);
+	}
+      else if (event->keyval == GDK_KP_Delete || event->keyval == GDK_Delete)
+	{
+	  delete_entry (NULL);
+	  return (FALSE);
+	}
     }
-
-  entry->prev = NULL;
-  entry->next = NULL;
-  tempentry = entry;
-  while (tempentry != NULL)
-    {
-      if (tempentry->path)
-	g_free (tempentry->path);
-      if (tempentry->hostname)
-	g_free (tempentry->hostname);
-      if (tempentry->remote_dir)
-	g_free (tempentry->remote_dir);
-      if (tempentry->user)
-	g_free (tempentry->user);
-      if (tempentry->pass)
-	g_free (tempentry->pass);
-      if (tempentry->sftpserv_path)
-        g_free (tempentry->sftpserv_path);
-
-      if (tempentry->children != NULL)
-	{
-	  tempentry = tempentry->children;
-	  continue;
-	}
-      else if (tempentry->next == NULL && tempentry->prev != NULL)
-	{
-	  delentry = tempentry->prev;
-	  g_free (tempentry);
-	  tempentry = delentry->next;
-	  if (delentry != entry)
-	    g_free (delentry);
-	}
-      else
-	tempentry = tempentry->next;
-    }
-  g_free (entry);
+  return (TRUE);
 }
 
 
 static void
-entry_apply_changes (GtkWidget * widget, gftp_bookmarks * entry)
+after_move (GtkCTree * ctree, GtkCTreeNode * child, GtkCTreeNode * parent,
+	    GtkCTreeNode * sibling, gpointer data)
 {
-  char *pos, *newpath, tempchar, *tempstr, *origpath;
-  gftp_bookmarks * tempentry, * nextentry;
-  GtkWidget * tempwid;
-  const char *str;
-  int oldpathlen;
+
+  gftp_bookmarks * childentry, * siblingentry, * parententry, * tempentry;
+  char *tempstr, *pos, *stpos;
+
+  childentry = gtk_ctree_node_get_row_data (ctree, child);
+  parententry = gtk_ctree_node_get_row_data (ctree, parent);
+  siblingentry = gtk_ctree_node_get_row_data (ctree, sibling);
 
-  oldpathlen = strlen (entry->path);
-  if ((pos = strrchr (entry->path, '/')) == NULL)
+  tempentry = childentry->prev->children;
+  if (tempentry == childentry)
+    childentry->prev->children = childentry->prev->children->next;
+  else
     {
-      pos = entry->path;
-      tempchar = *entry->path;
-      *entry->path = '\0';
+      while (tempentry->next != childentry)
+	tempentry = tempentry->next;
+      tempentry->next = childentry->next;
+    }
+  childentry->prev = parententry;
+  if (!parententry->isfolder)
+    {
+      childentry->next = parententry->children;
+      parententry->children = childentry;
+      gtk_ctree_move (ctree, child, parententry->prev->cnode,
+		      parententry->cnode);
     }
   else
     {
-      tempchar = *pos;
-      *pos = '\0';
-    }
-  origpath = newpath = g_strconcat (entry->path, "/",
-                         gtk_entry_get_text (GTK_ENTRY (bm_pathedit)), NULL);
-  remove_double_slashes (newpath);
-  for (; *newpath == '/'; newpath++);
-  *pos = tempchar;
-
-  str = gtk_entry_get_text (GTK_ENTRY (bm_hostedit));
-  if (entry->hostname)
-    g_free (entry->hostname);
-  entry->hostname = g_malloc (strlen (str) + 1);
-  strcpy (entry->hostname, str);
-
-  str = gtk_entry_get_text (GTK_ENTRY (bm_portedit));
-  entry->port = strtol (str, NULL, 10);
-
-  tempwid = gtk_menu_get_active (GTK_MENU (bm_protocol));
-  str = gtk_object_get_user_data (GTK_OBJECT (tempwid));
-  if (entry->protocol)
-    g_free (entry->protocol);
-  entry->protocol = g_malloc (strlen (str) + 1);
-  strcpy (entry->protocol, str);
-
-  str = gtk_entry_get_text (GTK_ENTRY (bm_remotediredit));
-  if (entry->remote_dir)
-    g_free (entry->remote_dir);
-  entry->remote_dir = g_malloc (strlen (str) + 1);
-  strcpy (entry->remote_dir, str);
-
-  str = gtk_entry_get_text (GTK_ENTRY (bm_localdiredit));
-  if (entry->local_dir)
-    g_free (entry->local_dir);
-  entry->local_dir = g_malloc (strlen (str) + 1);
-  strcpy (entry->local_dir, str);
+      if (siblingentry == NULL || parententry->children == siblingentry)
+	{
+	  childentry->next = parententry->children;
+	  parententry->children = childentry;
+	}
+      else
+	{
+	  tempentry = parententry->children;
+	  while (tempentry->next != siblingentry)
+	    tempentry = tempentry->next;
+	  childentry->next = tempentry->next;
+	  tempentry->next = childentry;
+	}
 
-  str = gtk_entry_get_text (GTK_ENTRY (bm_sftppath));
-  if (entry->sftpserv_path)
-    g_free (entry->sftpserv_path);
-  if (strlen (str) > 0)
-    {
-      entry->sftpserv_path = g_malloc (strlen (str) + 1);
-      strcpy (entry->sftpserv_path, str);
-    }
-  else
-    entry->sftpserv_path = NULL;
-
-  if (GTK_TOGGLE_BUTTON (anon_chk)->active)
-    str = "anonymous";
-  else
-    str = gtk_entry_get_text (GTK_ENTRY (bm_useredit));
-  if (entry->user)
-    g_free (entry->user);
-  entry->user = g_malloc (strlen (str) + 1);
-  strcpy (entry->user, str);
-
-  if (GTK_TOGGLE_BUTTON (anon_chk)->active)
-    str = "@EMAIL@";
-  else
-    str = gtk_entry_get_text (GTK_ENTRY (bm_passedit));
-  if (entry->pass)
-    g_free (entry->pass);
-  entry->pass = g_malloc (strlen (str) + 1);
-  strcpy (entry->pass, str);
-  entry->save_password = *entry->pass != '\0';
-
-  if (GTK_TOGGLE_BUTTON (anon_chk)->active)
-    str = "";
-  else
-    str = gtk_entry_get_text (GTK_ENTRY (bm_acctedit));
-  if (entry->acct)
-    g_free (entry->acct);
-  entry->acct = g_malloc (strlen (str) + 1);
-  strcpy (entry->acct, str);
-
-  if (strcmp (entry->path, newpath) != 0)
-    {
-      tempentry = entry;
-      nextentry = entry->next;
-      entry->next = NULL;
+      tempentry = childentry;
       while (tempentry != NULL)
 	{
 	  g_hash_table_remove (new_bookmarks_htable, tempentry->path);
-	  tempstr = g_strconcat (newpath, "/", tempentry->path + oldpathlen, 
-                                 NULL);
-	  remove_double_slashes (tempstr);
+	  if ((pos = strrchr (tempentry->path, '/')) == NULL)
+	    pos = tempentry->path;
+	  else
+	    pos++;
+	  tempstr = g_strdup_printf ("%s/%s", tempentry->prev->path, pos);
+	  for (stpos = tempstr; *stpos == '/'; stpos++);
 	  g_free (tempentry->path);
-	  tempentry->path = tempstr;
+	  tempentry->path = g_malloc (strlen (stpos) + 1);
+	  strcpy (tempentry->path, stpos);
+	  g_free (tempstr);
 	  g_hash_table_insert (new_bookmarks_htable, tempentry->path,
 			       tempentry);
 	  if (tempentry->children != NULL)
+	    tempentry = tempentry->children;
+	  else
 	    {
-	      tempentry = tempentry->children;
-	      continue;
-	    }
-	  while (tempentry->next == NULL && tempentry != entry &&
-		 tempentry->prev != NULL)
-	    tempentry = tempentry->prev;
-
-	  tempentry = tempentry->next;
-	}
-      entry->next = nextentry;
-      clear_bookmarks_tree ();
-      build_bookmarks_tree ();
-    }
-
-  g_free (origpath);
-}
-
-
-static void
-set_userpass_visible (GtkWidget * checkbutton, GtkWidget * entry)
-{
-  gtk_widget_set_sensitive (bm_useredit, !GTK_TOGGLE_BUTTON (anon_chk)->active);
-  gtk_widget_set_sensitive (bm_passedit, !GTK_TOGGLE_BUTTON (anon_chk)->active);
-  gtk_widget_set_sensitive (bm_acctedit, !GTK_TOGGLE_BUTTON (anon_chk)->active);
-}
-
-
-static void
-build_bookmarks_tree (void)
-{
-  GdkPixmap * closedir_pixmap, * opendir_pixmap;
-  GdkBitmap * closedir_bitmap, * opendir_bitmap;  
-  gftp_bookmarks * tempentry, * preventry;
-  char *pos, *prevpos, *text[2], *str;
-  GtkCTreeNode * parent;
-
-  gftp_get_pixmap (tree, "open_dir.xpm", &opendir_pixmap, &opendir_bitmap);
-  gftp_get_pixmap (tree, "dir.xpm", &closedir_pixmap, &closedir_bitmap);
-  text[0] = text[1] = _("Bookmarks");
-  parent = gtk_ctree_insert_node (GTK_CTREE (tree), NULL, NULL, text, 5, 
-                                  closedir_pixmap, closedir_bitmap, 
-                                  opendir_pixmap, opendir_bitmap, FALSE, TRUE);
-  gtk_ctree_node_set_row_data (GTK_CTREE (tree), parent, new_bookmarks);
-  new_bookmarks->cnode = parent;
-
-  tempentry = new_bookmarks->children;
-  while (tempentry != NULL)
-    {
-      tempentry->cnode = NULL;
-      if (tempentry->children != NULL)
-	{
-	  tempentry = tempentry->children;
-	  continue;
-	}
-      else
-	{
-	  pos = tempentry->path;
-	  while ((pos = strchr (pos, '/')) != NULL)
-	    {
-	      *pos = '\0';
-	      str = g_malloc (strlen (tempentry->path) + 1);
-	      strcpy (str, tempentry->path);
-	      *pos = '/';
-	      preventry = g_hash_table_lookup (new_bookmarks_htable, str);
-	      if (preventry->cnode == NULL)
+	      if (tempentry->next == NULL)
 		{
-		  if ((prevpos = strrchr (str, '/')) == NULL)
-		    prevpos = str;
+		  if (tempentry->prev == childentry)
+		    break;
 		  else
-		    prevpos++;
-		  text[0] = text[1] = prevpos;
-		  preventry->cnode = gtk_ctree_insert_node (GTK_CTREE (tree),
-					   preventry->prev->cnode, NULL, text,
-					   5, closedir_pixmap, closedir_bitmap,
-					   opendir_pixmap, opendir_bitmap,
-					   FALSE, FALSE);
-		  gtk_ctree_node_set_row_data (GTK_CTREE (tree),
-					       preventry->cnode, preventry);
+		    {
+		      while (tempentry->next == NULL
+			     && tempentry->prev != NULL)
+			tempentry = tempentry->prev;
+		    }
 		}
-
-	      g_free (str);
-	      pos++;
+	      tempentry = tempentry->next;
 	    }
 	}
-
-      if ((pos = strrchr (tempentry->path, '/')) == NULL)
-	pos = tempentry->path;
-      else
-	pos++;
-
-      text[0] = text[1] = pos;
-      tempentry->cnode = gtk_ctree_insert_node (GTK_CTREE (tree), 
-                               tempentry->prev->cnode, NULL,
-			       text, 5, NULL, NULL, NULL, NULL, FALSE, FALSE);
-      gtk_ctree_node_set_row_data (GTK_CTREE (tree), tempentry->cnode,
-				   tempentry);
-
-      while (tempentry->next == NULL && tempentry->prev != NULL)
-	tempentry = tempentry->prev;
-      tempentry = tempentry->next;
     }
 }
 
 
-static void
-clear_bookmarks_tree (void)
+static gint
+bm_dblclick (GtkWidget * widget, GdkEventButton * event, gpointer data)
 {
-  gftp_bookmarks * tempentry;
-
-  tempentry = new_bookmarks->children;
-  while (tempentry != NULL)
+  if (event->button == 3)
+    gtk_item_factory_popup (edit_factory, (guint) event->x_root,
+			    (guint) event->y_root, 1, 0);
+  else if (event->type == GDK_2BUTTON_PRESS)
     {
-      if (tempentry->children != NULL)
-	{
-	  tempentry = tempentry->children;
-	  continue;
-	}
-      while (tempentry->next == NULL && tempentry->prev != NULL)
-	{
-	  gtk_ctree_remove_node (GTK_CTREE (tree), tempentry->cnode);
-	  tempentry->cnode = NULL;
-	  tempentry = tempentry->prev;
-	}
-      gtk_ctree_remove_node (GTK_CTREE (tree), tempentry->cnode);
-      tempentry->cnode = NULL;
-      tempentry = tempentry->next;
+      edit_entry (NULL);
+      return (FALSE);
     }
+  return (TRUE);
 }
 
+
+void
+edit_bookmarks (gpointer data)
+{
+  GtkWidget * dialog, * scroll;
+  GtkItemFactory * ifactory;
+  GtkItemFactoryEntry menu_items[] = {
+    {N_("/_File"), NULL, 0, 0, "<Branch>"},
+    {N_("/File/tearoff"), NULL, 0, 0, "<Tearoff>"},
+    {N_("/File/New Folder..."), NULL, new_folder_entry, 0, MN_(NULL)},
+    {N_("/File/New Item..."), NULL, new_item_entry, 0, MS_(GTK_STOCK_NEW)},
+    {N_("/File/Delete"), NULL, delete_entry, 0, MS_(GTK_STOCK_DELETE)},
+    {N_("/File/Properties..."), NULL, edit_entry, 0, MS_(GTK_STOCK_PROPERTIES)},
+    {N_("/File/sep"), NULL, 0, 0, "<Separator>"},
+    {N_("/File/Close"), NULL, gtk_widget_destroy, 0, MS_(GTK_STOCK_CLOSE)}
+  };
+#if GTK_MAJOR_VERSION == 1
+  GtkWidget * tempwid;
+#endif
+
+  new_bookmarks = copy_bookmarks (bookmarks);
+  new_bookmarks_htable = build_bookmarks_hash_table (new_bookmarks);
+
+#if GTK_MAJOR_VERSION == 1
+  dialog = gtk_dialog_new ();
+  gtk_window_set_title (GTK_WINDOW (dialog), _("Edit Bookmarks"));
+  gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->action_area), 15);
+#else
+  dialog = gtk_dialog_new_with_buttons (_("Edit Bookmarks"), NULL, 0,
+                                        GTK_STOCK_SAVE,
+                                        GTK_RESPONSE_OK,
+                                        GTK_STOCK_CANCEL,
+                                        GTK_RESPONSE_CANCEL,
+                                        NULL);
+#endif
+  gtk_window_set_wmclass (GTK_WINDOW(dialog), "Edit Bookmarks", "gFTP");
+  gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
+  gtk_widget_realize (dialog);
+
+  if (gftp_icon != NULL)
+    {
+      gdk_window_set_icon (dialog->window, NULL, gftp_icon->pixmap,
+                           gftp_icon->bitmap);
+      gdk_window_set_icon_name (dialog->window, _("gFTP Icon"));
+    }
+
+  /* FIXME - memory leak */
+  ifactory = item_factory_new (GTK_TYPE_MENU_BAR, "<bookmarks>", NULL, NULL);
+  create_item_factory (ifactory, 7, menu_items, NULL);
+  create_item_factory (ifactory, 1, menu_items + 7, dialog);
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), ifactory->widget,
+		      FALSE, FALSE, 0);
+  gtk_widget_show (ifactory->widget);
+
+  scroll = gtk_scrolled_window_new (NULL, NULL);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
+				  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+  gtk_widget_set_size_request (scroll, 150, 200);
+
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), scroll, TRUE, TRUE,
+		      0);
+  gtk_container_border_width (GTK_CONTAINER (scroll), 3);
+  gtk_widget_show (scroll);
+
+  /* FIXME - memory leak */
+  edit_factory = item_factory_new (GTK_TYPE_MENU, "<edit_bookmark>", NULL, "/File");
+
+  create_item_factory (edit_factory, 6, menu_items + 2, dialog);
+
+  tree = gtk_ctree_new (1, 0);
+  gtk_clist_set_selection_mode (GTK_CLIST (tree), GTK_SELECTION_BROWSE);
+  gtk_clist_set_reorderable (GTK_CLIST (tree), 1);
+  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scroll), tree);
+  gtk_signal_connect_after (GTK_OBJECT (tree), "key_press_event",
+			    GTK_SIGNAL_FUNC (bm_enter), (gpointer) tree);
+  gtk_signal_connect_after (GTK_OBJECT (tree), "tree_move",
+			    GTK_SIGNAL_FUNC (after_move), NULL);
+  gtk_signal_connect_after (GTK_OBJECT (tree), "button_press_event",
+			    GTK_SIGNAL_FUNC (bm_dblclick), (gpointer) tree);
+  gtk_widget_show (tree);
+
+#if GTK_MAJOR_VERSION == 1
+  tempwid = gtk_button_new_with_label (_("OK"));
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), tempwid,
+		      TRUE, TRUE, 0);
+  gtk_signal_connect (GTK_OBJECT (tempwid), "clicked",
+		      GTK_SIGNAL_FUNC (bm_apply_changes), NULL);
+  gtk_signal_connect (GTK_OBJECT (tempwid), "clicked",
+		      GTK_SIGNAL_FUNC (bm_close_dialog), (gpointer) dialog);
+  GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT);
+  gtk_widget_show (tempwid);
+
+  tempwid = gtk_button_new_with_label (_("  Cancel  "));
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), tempwid,
+		      TRUE, TRUE, 0);
+  gtk_signal_connect (GTK_OBJECT (tempwid), "clicked",
+		      GTK_SIGNAL_FUNC (bm_close_dialog), (gpointer) dialog);
+  GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT);
+  gtk_widget_grab_focus (tempwid);
+  gtk_widget_show (tempwid);
+#else
+  g_signal_connect (GTK_OBJECT (dialog), "response",
+                    G_CALLBACK (editbm_action), NULL);
+#endif
+
+  gtk_widget_show (dialog);
+
+  build_bookmarks_tree ();
+}
+