Logo Search packages:      
Sourcecode: galeon version File versions

bookmarks-import-druid.c

/*
 *  Copyright (C) 2002  Ricardo Fernández Pascual
 *
 *  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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

/* Allow deprecated for the gnome_entry and gnome_file_entry widget */
#undef GTK_DISABLE_DEPRECATED
#undef GNOME_DISABLE_DEPRECATED

#include <glib/gi18n.h>
#include "bookmarks-import-druid.h"
#include "bookmarks-io.h"
#include "bookmarks-tree-model.h"
#include "bookmarks-tree-view.h"
#include "bookmarks-util.h"
#include "xbel.h"
#include <libgnomeui/gnome-druid.h>
#include <libgnomeui/gnome-druid-page-standard.h>
#include <libgnomeui/gnome-druid-page-edge.h>
#include <libgnomeui/gnome-file-entry.h>
#include <gtk/gtkliststore.h>
#include <gtk/gtktreeview.h>
#include <gtk/gtkcellrenderertext.h>
#include <gtk/gtkscrolledwindow.h>
#include <string.h>

/**
 * Private data
 */
#define GB_IMPORT_DRUID_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), \
                               GB_TYPE_IMPORT_DRUID, GbImportDruidPrivate))


struct _GbImportDruidPrivate {

      GbBookmarkSet *dest;
      GbBookmarkSet *imported;
      
      GtkWidget *window;
      GnomeDruid *druid;

      GtkWidget *location_entry;
      GtkTreeView *location_list;
      GtkListStore *location_model;
      gchar *location;

      GbTreeView *imported_list;
      GbTreeView *current_list;
      GbTreeView *second_current_list;

      GtkWidget *auto_merge_page;   
      GtkWidget *manual_merge_page; 

      gboolean backup_done;
      gchar *backup_filename;
};

/**
 * Private functions, only availble from this file
 */
static void       gb_import_druid_init_widgets        (GbImportDruid *d);
static void       gb_import_druid_init_location_widgets     (GbImportDruid *d);
static void       gb_import_druid_init_merge_widgets  (GbImportDruid *d);
static void       gb_import_druid_finalize_impl       (GObject *o);
static const char *     gb_import_druid_get_string          (GbImportDruid *d, const char *string_id);
static const char *     gb_import_druid_get_string_impl           (GbImportDruid *d, const char *string_id);
static GSList *         gb_import_druid_get_locations       (GbImportDruid *d);
static GSList *         gb_import_druid_get_locations_impl  (GbImportDruid *d);
static GbIO *           gb_import_druid_get_io              (GbImportDruid *d);
static GbIO *           gb_import_druid_get_io_impl         (GbImportDruid *d);
static void             gb_import_druid_page_3_prepare_cb   (GnomeDruidPage *druid_page, 
                                                 GtkWidget *druid,
                                                 GbImportDruid *d);
static void             gb_import_druid_page_5_prepare_cb   (GnomeDruidPage *druid_page, 
                                                 GtkWidget *druid,
                                                 GbImportDruid *d);
static void       gb_import_druid_location_list_selection_changed_cb (GtkTreeSelection *ts, 
                                                          GbImportDruid *d);
static void       gb_import_druid_location_entry_changed_cb (GtkEditable *e, GbImportDruid *d);
static void       gb_import_druid_merge_button_clicked_cb   (GtkButton *b, GbImportDruid *d);



/**
 * ImportDruid object
 */

G_DEFINE_TYPE (GbImportDruid, gb_import_druid, G_TYPE_OBJECT);

static void
gb_import_druid_class_init (GbImportDruidClass *klass)
{
      klass->get_string = gb_import_druid_get_string_impl;
      klass->get_locations = gb_import_druid_get_locations_impl;
      klass->get_io = gb_import_druid_get_io_impl;
      G_OBJECT_CLASS (klass)->finalize = gb_import_druid_finalize_impl;

      g_type_class_add_private (klass, sizeof (GbImportDruidPrivate));
}

static void 
gb_import_druid_init (GbImportDruid *e)
{
      GbImportDruidPrivate *p = GB_IMPORT_DRUID_GET_PRIVATE (e);
      e->priv = p;
      
}

static void
gb_import_druid_finalize_impl (GObject *o)
{
      GbImportDruid *e = GB_IMPORT_DRUID (o);
      GbImportDruidPrivate *p = e->priv;

      if (p->dest)
      {
            g_object_unref (p->dest);
      }

      if (p->imported)
      {
            g_object_unref (p->imported);
      }

      g_free (p->location);
      g_free (p->backup_filename);
      
      G_OBJECT_CLASS (gb_import_druid_parent_class)->finalize (o);

}

static void
gb_import_druid_init_widgets (GbImportDruid *d)
{
      GbImportDruidPrivate *p = d->priv;
      GnomeDruidPage *page;
      GtkWidget *w;

      g_return_if_fail (GB_IS_BOOKMARK_SET (p->dest));
      g_return_if_fail (p->window == NULL);
      
      p->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_window_set_title (GTK_WINDOW (p->window), 
                        gb_import_druid_get_string (d, "window title"));

      g_object_weak_ref (G_OBJECT (p->window), (GWeakNotify) g_object_unref, d);

      p->druid = GNOME_DRUID (gnome_druid_new ());
      gtk_widget_show (GTK_WIDGET (p->druid));
      gtk_container_add (GTK_CONTAINER (p->window), GTK_WIDGET (p->druid));
      gnome_druid_set_show_help (p->druid, FALSE);

      g_signal_connect_object (p->druid, "cancel",
                         G_CALLBACK (gtk_widget_destroy),
                         p->window,
                         G_CONNECT_SWAPPED);

      g_signal_connect_object (p->druid, "destroy",
                         G_CALLBACK (gtk_widget_destroy),
                         p->window,
                         G_CONNECT_SWAPPED);

      /* page 1 */
      page = GNOME_DRUID_PAGE (gnome_druid_page_edge_new (GNOME_EDGE_START));
      gtk_widget_show (GTK_WIDGET (page));
      gnome_druid_page_edge_set_title (GNOME_DRUID_PAGE_EDGE (page), 
                               gb_import_druid_get_string (d, "page 1 title"));
      gnome_druid_append_page (p->druid, page);
      gnome_druid_set_page (p->druid, page);
      gnome_druid_page_edge_set_text (GNOME_DRUID_PAGE_EDGE (page),
                              _("This druid will help you to import a bookmarks file and "
                                "merge its contents in the current bookmark set."));

      /* page 2 */
      page = GNOME_DRUID_PAGE (gnome_druid_page_standard_new ());
      gtk_widget_show (GTK_WIDGET (page));
      gnome_druid_page_standard_set_title (GNOME_DRUID_PAGE_STANDARD (page), 
                                   _("Bookmark file location"));
      gnome_druid_append_page (p->druid, page);
      
      gb_import_druid_init_location_widgets (d);
      w = gtk_scrolled_window_new (NULL, NULL);
      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (w), 
                              GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
      gtk_widget_show (w);
      gtk_container_add (GTK_CONTAINER (w), GTK_WIDGET (p->location_list));

      gnome_druid_page_standard_append_item (GNOME_DRUID_PAGE_STANDARD (page),
                                     _("Found possible locations:"),
                                     w,
                                     _("These locations are typical places where "
                                     "bookmarks can be found."));

      gnome_druid_page_standard_append_item (GNOME_DRUID_PAGE_STANDARD (page),
                                     _("Chosen location:"),
                                     p->location_entry,
                                     _("This is the location that will be used. You "
                                     "can choose one from the list or enter your own."));
      
      /* page 3 */
      page = GNOME_DRUID_PAGE (gnome_druid_page_standard_new ());
      gtk_widget_show (GTK_WIDGET (page));
      p->manual_merge_page = GTK_WIDGET (page);
      gnome_druid_page_standard_set_title (GNOME_DRUID_PAGE_STANDARD (page), 
                                   _("Merge imported bookmarks"));
      gnome_druid_append_page (p->druid, page);
      
      gb_import_druid_init_merge_widgets (d);

      w = gtk_scrolled_window_new (NULL, NULL);
      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (w), 
                              GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
      gtk_widget_show (w);
      gtk_container_add (GTK_CONTAINER (w), GTK_WIDGET (p->imported_list));
      gnome_druid_page_standard_append_item (GNOME_DRUID_PAGE_STANDARD (page),
                                     _("Imported bookmarks:"),
                                     w,
                                     _("These are the bookmarks just imported."));
      gtk_box_set_child_packing   (GTK_BOX (w->parent), w, TRUE, TRUE, 0, GTK_PACK_START);
      gtk_box_set_child_packing   (GTK_BOX (w->parent->parent), w->parent, TRUE, TRUE, 0, GTK_PACK_START);

      w = gtk_scrolled_window_new (NULL, NULL);
      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (w), 
                              GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
      gtk_widget_show (w);
      gtk_container_add (GTK_CONTAINER (w), GTK_WIDGET (p->current_list));
      gnome_druid_page_standard_append_item (GNOME_DRUID_PAGE_STANDARD (page),
                                     _("Current bookmarks:"),
                                     w,
                                     _("These are the bookmarks of your "
                                     "current bookmark set."));
      gtk_box_set_child_packing   (GTK_BOX (w->parent), w, TRUE, TRUE, 0, GTK_PACK_START);
      gtk_box_set_child_packing   (GTK_BOX (w->parent->parent), w->parent, TRUE, TRUE, 0, GTK_PACK_START);

      w = gtk_button_new_with_mnemonic (_("Automatic merge"));
      gtk_widget_show (w);
      gtk_box_pack_start (GTK_BOX (GNOME_DRUID_PAGE_STANDARD (page)->vbox), w, FALSE, FALSE, 0);
      g_signal_connect (w, "clicked",
                    G_CALLBACK (gb_import_druid_merge_button_clicked_cb), d);               

      w = gtk_label_new (_("You can manually merge the two bookmark sets using "
                       "drag & drop and copy & paste.\n"
                       "Alternatively, you can try the Automatic Merger."));
      gtk_widget_show (w);
      gtk_box_pack_start (GTK_BOX (GNOME_DRUID_PAGE_STANDARD (page)->vbox), w, FALSE, FALSE, 0);

      
      g_signal_connect (page, "prepare", G_CALLBACK (gb_import_druid_page_3_prepare_cb), d);

      /* page 4 */
      page = GNOME_DRUID_PAGE (gnome_druid_page_standard_new ());
      p->auto_merge_page = GTK_WIDGET (page);
      gnome_druid_page_standard_set_title (GNOME_DRUID_PAGE_STANDARD (page), 
                                   _("Automatically merged bookmarks"));
      gnome_druid_append_page (p->druid, page);

      w = gtk_scrolled_window_new (NULL, NULL);
      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (w), 
                              GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
      gtk_widget_show (w);
      gtk_container_add (GTK_CONTAINER (w), GTK_WIDGET (p->second_current_list));
      gnome_druid_page_standard_append_item (GNOME_DRUID_PAGE_STANDARD (page),
                                     _("Merged bookmarks:"),
                                     w,
                                     _("This is the resulting bookmark set after merging."));
      gtk_box_set_child_packing   (GTK_BOX (w->parent), w, TRUE, TRUE, 0, GTK_PACK_START);
      gtk_box_set_child_packing   (GTK_BOX (w->parent->parent), w->parent, TRUE, TRUE, 0, GTK_PACK_START);

      /* page 5 */
      page = GNOME_DRUID_PAGE (gnome_druid_page_edge_new (GNOME_EDGE_FINISH));
      gtk_widget_show (GTK_WIDGET (page));
      gnome_druid_page_edge_set_title (GNOME_DRUID_PAGE_EDGE (page), 
                               _("Bookmarks Imported"));
      gnome_druid_append_page (p->druid, page);

      g_signal_connect (page, "prepare", G_CALLBACK (gb_import_druid_page_5_prepare_cb), d);

      /* misc */
      gnome_druid_set_show_help (p->druid, FALSE);
      gtk_button_set_label (GTK_BUTTON (p->druid->cancel), GTK_STOCK_CLOSE);
}

static void
gb_import_druid_init_location_widgets (GbImportDruid *d)
{
      GbImportDruidPrivate *p = d->priv;
      GSList *locs;
      GSList *li;
      GtkTreeSelection *sel;

      p->location_entry = gnome_file_entry_new ("galeon-bookamrks-import-locations",
                                      _("Choose a file to import"));

      /* Use the new file chooser if we can */
      if (g_object_class_find_property (G_OBJECT_GET_CLASS (p->location_entry), 
                                "use_filechooser" ))
      {
            g_object_set (p->location_entry, "use_filechooser", TRUE, NULL);
      }

      gtk_widget_show (p->location_entry);
      g_signal_connect (gnome_entry_gtk_entry (GNOME_ENTRY (gnome_file_entry_gnome_entry 
                                                (GNOME_FILE_ENTRY (p->location_entry)))),
                    "changed", 
                    G_CALLBACK (gb_import_druid_location_entry_changed_cb), d);

      p->location_model = gtk_list_store_new (1, G_TYPE_STRING);
      p->location_list = GTK_TREE_VIEW (gtk_tree_view_new_with_model 
                                (GTK_TREE_MODEL (p->location_model)));
      
      gtk_tree_view_insert_column_with_attributes (p->location_list, -1, _("Location"),
                                         gtk_cell_renderer_text_new (), 
                                         "text", 0,
                                         NULL);
      gtk_tree_view_set_headers_visible (p->location_list, FALSE);
      sel = gtk_tree_view_get_selection (p->location_list);
      gtk_tree_selection_set_mode (sel, GTK_SELECTION_SINGLE);
      
      g_signal_connect (sel, "changed", 
                    G_CALLBACK (gb_import_druid_location_list_selection_changed_cb), d);

      locs = gb_import_druid_get_locations (d);

      for (li = locs; li; li = li->next)
      {
            if (g_file_test (li->data, G_FILE_TEST_IS_REGULAR))
            {
                  GtkTreeIter iter;
                  gtk_list_store_append (p->location_model, &iter);
                  gtk_list_store_set (p->location_model, &iter, 0, li->data, -1);
                  
                  /* make sure something is selected */
                  if (!gtk_tree_selection_get_selected (sel, NULL, NULL))
                  {
                        gtk_tree_selection_select_iter (sel, &iter);
                  }
            }
      }
      
      g_slist_foreach (locs, (GFunc) g_free, NULL);
      g_slist_free (locs);

      gtk_widget_show (GTK_WIDGET (p->location_list));
}

static void
gb_import_druid_init_merge_widgets (GbImportDruid *d)
{
      GbImportDruidPrivate *p = d->priv;

      p->current_list = gb_tree_view_new ();
      gtk_widget_show (GTK_WIDGET (p->current_list));

      p->second_current_list = gb_tree_view_new ();
      gtk_widget_show (GTK_WIDGET (p->second_current_list));

      p->imported_list = gb_tree_view_new ();
      gtk_widget_show (GTK_WIDGET (p->imported_list));
            
}

void
gb_import_druid_show (GbImportDruid *d)
{
      GbImportDruidPrivate *p = d->priv;

      g_return_if_fail (GB_IS_BOOKMARK_SET (p->dest));
      g_return_if_fail (GTK_IS_WINDOW (p->window));
      
      gtk_widget_show (GTK_WIDGET (p->window));
}

void
gb_import_druid_set_dest_bookmark_set (GbImportDruid *d, GbBookmarkSet *bs)
{
      GbImportDruidPrivate *p = d->priv;

      if (p->dest)
      {
            g_signal_handlers_disconnect_matched (p->dest, G_SIGNAL_MATCH_DATA, 0, 0, 
                                          NULL, NULL, d);
            g_object_unref (p->dest);
      }

      p->dest = bs;

      if (bs)
      {
            g_object_ref (bs);
            gb_import_druid_init_widgets (d);
      }

}

static const char *
gb_import_druid_get_string_impl (GbImportDruid *d, const char *string_id)
{
      g_warning ("Should not be reached");
      return NULL;
}

static const char *
gb_import_druid_get_string (GbImportDruid *d, const char *string_id)
{
      return GB_IMPORT_DRUID_GET_CLASS (d)->get_string (d, string_id);
}

static GSList *
gb_import_druid_get_locations_impl (GbImportDruid *d)
{
      g_warning ("Should not be reached");
      return NULL;
}

static GSList *
gb_import_druid_get_locations (GbImportDruid *d)
{
      return GB_IMPORT_DRUID_GET_CLASS (d)->get_locations (d);
}

static GbIO *
gb_import_druid_get_io_impl (GbImportDruid *d)
{
      g_warning ("Should not be reached");
      return NULL;
}

static GbIO *
gb_import_druid_get_io (GbImportDruid *d)
{
      return GB_IMPORT_DRUID_GET_CLASS (d)->get_io (d);
}

static void
gb_import_druid_page_3_prepare_cb (GnomeDruidPage *druid_page, 
                           GtkWidget *druid,
                           GbImportDruid *d)
{
      GbImportDruidPrivate *p = d->priv;

      if (p->location)
      {
            GbIO *io = gb_import_druid_get_io (d);
            if (p->imported)
            {
                  g_object_unref (p->imported);
            }
            
            p->imported = gb_io_load_from_file (io, p->location);
                  
            g_object_unref (io);
      }
            
      if (p->imported)
      {
            GbTreeModel *tm = gb_tree_model_new_for_set (p->imported);
            gb_tree_view_set_model (p->imported_list, tm);
            g_object_unref (tm);
      }
      else
      {
            GbBookmarkSet *dummy_set = gb_bookmark_set_new ();
            GbFolder *dummy_root = gb_folder_new (dummy_set, _("No bookmarks have been imported."));
            GbTreeModel *tm;
            gb_bookmark_set_set_root (dummy_set, dummy_root);
            tm = gb_tree_model_new_for_set (dummy_set);
            gb_tree_view_set_model (p->imported_list, tm);
            g_object_unref (tm);
            g_object_unref (dummy_root);
            p->imported = dummy_set;

            /* TODO: show an error */
      }
      
      if (p->dest)
      {
            GbTreeModel *tm = gb_tree_model_new_for_set (p->dest);
            gb_tree_view_set_model (p->current_list, tm);
            gb_tree_view_set_model (p->second_current_list, tm);
            g_object_unref (tm);

            /* make a backup copy of the current bookmark set */
            if (!p->backup_done)
            {
                  if (p->dest->filename)
                  {
                        GbIO *io = GB_IO (gb_xbel_new ());
                        p->backup_filename = g_strconcat (p->dest->filename, ".bak", NULL);
                        p->backup_done = gb_io_save_to_file (io, p->dest, p->backup_filename);
                        if (!p->backup_done)
                        {
                              g_free (p->backup_filename);
                              p->backup_filename = NULL;
                        }
                  }
            }
      }
}

static gboolean
gb_import_druid_page_5_prepare_cb_ugly_hack (GtkWidget *w, GdkEventAny *event, GbImportDruid *d)
{
      GbImportDruidPrivate *p = d->priv;
      gtk_widget_show (p->druid->next);
      gtk_widget_hide (p->druid->finish);
      return FALSE;
}

static void
gb_import_druid_page_5_prepare_cb (GnomeDruidPage *druid_page, 
                           GtkWidget *druid,
                           GbImportDruid *d)
{
      GbImportDruidPrivate *p = d->priv;
      gchar *s;

      if (p->backup_done)
      {
            s = g_strdup_printf (_("The importing process has finished. For safety, you have a "
                               "copy of your old bookmark set in %s."),
                             p->backup_filename);
      }
      else
      {
            s = g_strdup_printf (_("The importing process has finished."));
      }
      gnome_druid_page_edge_set_text (GNOME_DRUID_PAGE_EDGE (druid_page), s);
      g_free (s);

      /* FIXME: this is very ugly... */
      g_signal_connect (p->druid->finish, "map_event", 
                    G_CALLBACK (gb_import_druid_page_5_prepare_cb_ugly_hack), d);
}

static void
gb_import_druid_location_list_selection_changed_cb (GtkTreeSelection *ts, GbImportDruid *d)
{
      GbImportDruidPrivate *p = d->priv;
      GtkTreeModel *m;
      GtkTreeIter it;
      
      if (gtk_tree_selection_get_selected (ts, &m, &it))
      {
            GValue val = { 0 };
            const gchar *sel;
            
            gtk_tree_model_get_value (m, &it, 0, &val);
            sel = g_value_get_string (&val);

            if (sel)
            {
                  gnome_file_entry_set_filename (GNOME_FILE_ENTRY (p->location_entry), sel);
            }
            g_value_unset (&val);
      }
}

static void
gb_import_druid_location_entry_changed_cb (GtkEditable *e, GbImportDruid *d)
{
      GbImportDruidPrivate *p = d->priv;
      gchar *sel = gtk_editable_get_chars (e, 0, -1);
      g_free (p->location);
      p->location = sel;
}

static void
gb_import_druid_merge_button_clicked_cb (GtkButton *b, GbImportDruid *d)
{
      GbImportDruidPrivate *p = d->priv;
      
      gtk_widget_show (p->auto_merge_page);
      gnome_druid_set_page (p->druid, GNOME_DRUID_PAGE (p->auto_merge_page));

      gb_util_merge_trees (p->dest->root, p->imported->root);
}


Generated by  Doxygen 1.6.0   Back to index