aboutsummaryrefslogtreecommitdiffstats
path: root/lib/toolbar
diff options
context:
space:
mode:
authorMarco Pesenti Gritti <mpeseng@src.gnome.org>2002-12-31 03:29:24 +0800
committerMarco Pesenti Gritti <mpeseng@src.gnome.org>2002-12-31 03:29:24 +0800
commit6876ede98282c7db318089bfefb292aa59e55d48 (patch)
tree76b23252d04da232d0ebf22e53bfe3e022686af9 /lib/toolbar
downloadgsoc2013-epiphany-6876ede98282c7db318089bfefb292aa59e55d48.tar.gz
gsoc2013-epiphany-6876ede98282c7db318089bfefb292aa59e55d48.tar.zst
gsoc2013-epiphany-6876ede98282c7db318089bfefb292aa59e55d48.zip
Initial revision
Diffstat (limited to 'lib/toolbar')
-rw-r--r--lib/toolbar/.cvsignore6
-rw-r--r--lib/toolbar/Makefile.am41
-rw-r--r--lib/toolbar/ephy-tbi-favicon.c188
-rw-r--r--lib/toolbar/ephy-tbi-favicon.h66
-rw-r--r--lib/toolbar/ephy-tbi-location.c205
-rw-r--r--lib/toolbar/ephy-tbi-location.h66
-rw-r--r--lib/toolbar/ephy-tbi-navigation-history.c342
-rw-r--r--lib/toolbar/ephy-tbi-navigation-history.h81
-rw-r--r--lib/toolbar/ephy-tbi-separator.c179
-rw-r--r--lib/toolbar/ephy-tbi-separator.h68
-rw-r--r--lib/toolbar/ephy-tbi-spinner.c188
-rw-r--r--lib/toolbar/ephy-tbi-spinner.h66
-rw-r--r--lib/toolbar/ephy-tbi-std-toolitem.c467
-rw-r--r--lib/toolbar/ephy-tbi-std-toolitem.h86
-rw-r--r--lib/toolbar/ephy-tbi-zoom.c304
-rw-r--r--lib/toolbar/ephy-tbi-zoom.h66
-rw-r--r--lib/toolbar/ephy-toolbar-bonobo-view.c193
-rw-r--r--lib/toolbar/ephy-toolbar-bonobo-view.h75
-rw-r--r--lib/toolbar/ephy-toolbar-editor.c634
-rw-r--r--lib/toolbar/ephy-toolbar-editor.h80
-rw-r--r--lib/toolbar/ephy-toolbar-item-factory.c158
-rw-r--r--lib/toolbar/ephy-toolbar-item-factory.h31
-rw-r--r--lib/toolbar/ephy-toolbar-item.c142
-rw-r--r--lib/toolbar/ephy-toolbar-item.h91
-rw-r--r--lib/toolbar/ephy-toolbar-tree-model.c784
-rw-r--r--lib/toolbar/ephy-toolbar-tree-model.h74
-rw-r--r--lib/toolbar/ephy-toolbar.c420
-rw-r--r--lib/toolbar/ephy-toolbar.h80
28 files changed, 5181 insertions, 0 deletions
diff --git a/lib/toolbar/.cvsignore b/lib/toolbar/.cvsignore
new file mode 100644
index 000000000..20e4cb0c8
--- /dev/null
+++ b/lib/toolbar/.cvsignore
@@ -0,0 +1,6 @@
+Makefile
+Makefile.in
+*.lo
+.deps
+.libs
+*.la
diff --git a/lib/toolbar/Makefile.am b/lib/toolbar/Makefile.am
new file mode 100644
index 000000000..a6affaa04
--- /dev/null
+++ b/lib/toolbar/Makefile.am
@@ -0,0 +1,41 @@
+INCLUDES = \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/lib/widgets \
+ $(WARN_CFLAGS) \
+ $(EPIPHANY_DEPENDENCY_CFLAGS) \
+ -DSHARE_DIR=\"$(pkgdatadir)\" \
+ -DG_DISABLE_DEPRECATED \
+ -DGDK_DISABLE_DEPRECATED \
+ -DGTK_DISABLE_DEPRECATED \
+ -DGDK_PIXBUF_DISABLE_DEPRECATED \
+ -DGNOME_DISABLE_DEPRECATED
+
+noinst_LTLIBRARIES = libephytoolbar.la
+
+libephytoolbar_la_SOURCES = \
+ ephy-toolbar.h \
+ ephy-toolbar.c \
+ ephy-toolbar-item.h \
+ ephy-toolbar-item.c \
+ ephy-toolbar-item-factory.h \
+ ephy-toolbar-item-factory.c \
+ ephy-tbi-zoom.h \
+ ephy-tbi-zoom.c \
+ ephy-tbi-separator.h \
+ ephy-tbi-separator.c \
+ ephy-tbi-favicon.h \
+ ephy-tbi-favicon.c \
+ ephy-tbi-spinner.h \
+ ephy-tbi-spinner.c \
+ ephy-tbi-location.h \
+ ephy-tbi-location.c \
+ ephy-tbi-navigation-history.h \
+ ephy-tbi-navigation-history.c \
+ ephy-tbi-std-toolitem.h \
+ ephy-tbi-std-toolitem.c \
+ ephy-toolbar-bonobo-view.c \
+ ephy-toolbar-bonobo-view.h \
+ ephy-toolbar-tree-model.h \
+ ephy-toolbar-tree-model.c \
+ ephy-toolbar-editor.h \
+ ephy-toolbar-editor.c
diff --git a/lib/toolbar/ephy-tbi-favicon.c b/lib/toolbar/ephy-tbi-favicon.c
new file mode 100644
index 000000000..d072e3ec6
--- /dev/null
+++ b/lib/toolbar/ephy-tbi-favicon.c
@@ -0,0 +1,188 @@
+/*
+ * 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
+
+#include <libgnome/gnome-i18n.h>
+#include <gtk/gtkeventbox.h>
+
+#include "ephy-gobject-misc.h"
+#include "ephy-marshal.h"
+#include "ephy-bonobo-extensions.h"
+#include "ephy-tbi-favicon.h"
+
+#define NOT_IMPLEMENTED g_warning ("not implemented: " G_STRLOC);
+//#define DEBUG_MSG(x) g_print x
+#define DEBUG_MSG(x)
+
+/**
+ * Private data
+ */
+struct _EphyTbiFaviconPrivate
+{
+ GtkWidget *widget;
+};
+
+/**
+ * Private functions, only availble from this file
+ */
+static void ephy_tbi_favicon_class_init (EphyTbiFaviconClass *klass);
+static void ephy_tbi_favicon_init (EphyTbiFavicon *tb);
+static void ephy_tbi_favicon_finalize_impl (GObject *o);
+static GtkWidget * ephy_tbi_favicon_get_widget_impl (EphyTbItem *i);
+static GdkPixbuf * ephy_tbi_favicon_get_icon_impl (EphyTbItem *i);
+static gchar * ephy_tbi_favicon_get_name_human_impl (EphyTbItem *i);
+static gchar * ephy_tbi_favicon_to_string_impl (EphyTbItem *i);
+static gboolean ephy_tbi_favicon_is_unique_impl (EphyTbItem *i);
+static EphyTbItem * ephy_tbi_favicon_clone_impl (EphyTbItem *i);
+static void ephy_tbi_favicon_parse_properties_impl (EphyTbItem *i, const gchar *props);
+static void ephy_tbi_favicon_add_to_bonobo_tb_impl (EphyTbItem *i,
+ BonoboUIComponent *ui,
+ const char *container_path,
+ guint index);
+
+static gpointer ephy_tb_item_class;
+
+/**
+ * TbiFavicon object
+ */
+
+MAKE_GET_TYPE (ephy_tbi_favicon, "EphyTbiFavicon", EphyTbiFavicon, ephy_tbi_favicon_class_init,
+ ephy_tbi_favicon_init, EPHY_TYPE_TB_ITEM);
+
+static void
+ephy_tbi_favicon_class_init (EphyTbiFaviconClass *klass)
+{
+ G_OBJECT_CLASS (klass)->finalize = ephy_tbi_favicon_finalize_impl;
+
+ EPHY_TB_ITEM_CLASS (klass)->get_widget = ephy_tbi_favicon_get_widget_impl;
+ EPHY_TB_ITEM_CLASS (klass)->get_icon = ephy_tbi_favicon_get_icon_impl;
+ EPHY_TB_ITEM_CLASS (klass)->get_name_human = ephy_tbi_favicon_get_name_human_impl;
+ EPHY_TB_ITEM_CLASS (klass)->to_string = ephy_tbi_favicon_to_string_impl;
+ EPHY_TB_ITEM_CLASS (klass)->is_unique = ephy_tbi_favicon_is_unique_impl;
+ EPHY_TB_ITEM_CLASS (klass)->clone = ephy_tbi_favicon_clone_impl;
+ EPHY_TB_ITEM_CLASS (klass)->parse_properties = ephy_tbi_favicon_parse_properties_impl;
+ EPHY_TB_ITEM_CLASS (klass)->add_to_bonobo_tb = ephy_tbi_favicon_add_to_bonobo_tb_impl;
+
+ ephy_tb_item_class = g_type_class_peek_parent (klass);
+}
+
+static void
+ephy_tbi_favicon_init (EphyTbiFavicon *tb)
+{
+ EphyTbiFaviconPrivate *p = g_new0 (EphyTbiFaviconPrivate, 1);
+ tb->priv = p;
+}
+
+EphyTbiFavicon *
+ephy_tbi_favicon_new (void)
+{
+ EphyTbiFavicon *ret = g_object_new (EPHY_TYPE_TBI_FAVICON, NULL);
+ return ret;
+}
+
+static void
+ephy_tbi_favicon_finalize_impl (GObject *o)
+{
+ EphyTbiFavicon *it = EPHY_TBI_FAVICON (o);
+ EphyTbiFaviconPrivate *p = it->priv;
+
+ if (p->widget)
+ {
+ g_object_unref (p->widget);
+ }
+
+ g_free (p);
+
+ DEBUG_MSG (("EphyTbiFavicon finalized\n"));
+
+ G_OBJECT_CLASS (ephy_tb_item_class)->finalize (o);
+}
+
+static GtkWidget *
+ephy_tbi_favicon_get_widget_impl (EphyTbItem *i)
+{
+ EphyTbiFavicon *iz = EPHY_TBI_FAVICON (i);
+ EphyTbiFaviconPrivate *p = iz->priv;
+
+ if (!p->widget)
+ {
+ /* here, we create only the event_box. */
+ p->widget = gtk_event_box_new ();
+ g_object_ref (p->widget);
+ gtk_object_sink (GTK_OBJECT (p->widget));
+ }
+
+ return p->widget;
+}
+
+static GdkPixbuf *
+ephy_tbi_favicon_get_icon_impl (EphyTbItem *i)
+{
+ /* need an icon for this */
+ return NULL;
+}
+
+static gchar *
+ephy_tbi_favicon_get_name_human_impl (EphyTbItem *i)
+{
+ return g_strdup (_("Drag Handle"));
+}
+
+static gchar *
+ephy_tbi_favicon_to_string_impl (EphyTbItem *i)
+{
+ /* if it had any properties, the string should include them */
+ return g_strdup_printf ("%s=favicon", i->id);
+}
+
+static gboolean
+ephy_tbi_favicon_is_unique_impl (EphyTbItem *i)
+{
+ return TRUE;
+}
+
+static EphyTbItem *
+ephy_tbi_favicon_clone_impl (EphyTbItem *i)
+{
+ EphyTbItem *ret = EPHY_TB_ITEM (ephy_tbi_favicon_new ());
+
+ ephy_tb_item_set_id (ret, i->id);
+
+ /* should copy properties too, if any */
+
+ return ret;
+}
+
+static void
+ephy_tbi_favicon_add_to_bonobo_tb_impl (EphyTbItem *i, BonoboUIComponent *ui,
+ const char *container_path, guint index)
+{
+ GtkWidget *w = ephy_tb_item_get_widget (i);
+ gtk_widget_show (w);
+ ephy_bonobo_add_numbered_control (ui, w, index, container_path);
+}
+
+static void
+ephy_tbi_favicon_parse_properties_impl (EphyTbItem *it, const gchar *props)
+{
+ /* we have no properties */
+}
+
diff --git a/lib/toolbar/ephy-tbi-favicon.h b/lib/toolbar/ephy-tbi-favicon.h
new file mode 100644
index 000000000..7cea6f634
--- /dev/null
+++ b/lib/toolbar/ephy-tbi-favicon.h
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+#ifndef EPHY_TBI_FAVICON_H
+#define EPHY_TBI_FAVICON_H
+
+#include "ephy-toolbar-item.h"
+
+G_BEGIN_DECLS
+
+/* object forward declarations */
+
+typedef struct _EphyTbiFavicon EphyTbiFavicon;
+typedef struct _EphyTbiFaviconClass EphyTbiFaviconClass;
+typedef struct _EphyTbiFaviconPrivate EphyTbiFaviconPrivate;
+
+/**
+ * TbiFavicon object
+ */
+
+#define EPHY_TYPE_TBI_FAVICON (ephy_tbi_favicon_get_type())
+#define EPHY_TBI_FAVICON(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EPHY_TYPE_TBI_FAVICON,\
+ EphyTbiFavicon))
+#define EPHY_TBI_FAVICON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EPHY_TYPE_TBI_FAVICON,\
+ EphyTbiFaviconClass))
+#define EPHY_IS_TBI_FAVICON(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EPHY_TYPE_TBI_FAVICON))
+#define EPHY_IS_TBI_FAVICON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EPHY_TYPE_TBI_FAVICON))
+#define EPHY_TBI_FAVICON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_TBI_FAVICON,\
+ EphyTbiFaviconClass))
+
+struct _EphyTbiFaviconClass
+{
+ EphyTbItemClass parent_class;
+};
+
+/* Remember: fields are public read-only */
+struct _EphyTbiFavicon
+{
+ EphyTbItem parent_object;
+
+ EphyTbiFaviconPrivate *priv;
+};
+
+/* this class is abstract */
+
+GType ephy_tbi_favicon_get_type (void);
+EphyTbiFavicon * ephy_tbi_favicon_new (void);
+
+G_END_DECLS
+
+#endif
diff --git a/lib/toolbar/ephy-tbi-location.c b/lib/toolbar/ephy-tbi-location.c
new file mode 100644
index 000000000..0ccbaf83a
--- /dev/null
+++ b/lib/toolbar/ephy-tbi-location.c
@@ -0,0 +1,205 @@
+/*
+ * 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
+
+#include <libgnome/gnome-i18n.h>
+#include "ephy-gobject-misc.h"
+#include "ephy-marshal.h"
+#include "ephy-bonobo-extensions.h"
+#include "ephy-tbi-location.h"
+#include "ephy-location-entry.h"
+
+#define NOT_IMPLEMENTED g_warning ("not implemented: " G_STRLOC);
+//#define DEBUG_MSG(x) g_print x
+#define DEBUG_MSG(x)
+
+/**
+ * Private data
+ */
+struct _EphyTbiLocationPrivate
+{
+ GtkWidget *widget;
+};
+
+/**
+ * Private functions, only availble from this file
+ */
+static void ephy_tbi_location_class_init (EphyTbiLocationClass *klass);
+static void ephy_tbi_location_init (EphyTbiLocation *tb);
+static void ephy_tbi_location_finalize_impl (GObject *o);
+static GtkWidget * ephy_tbi_location_get_widget_impl (EphyTbItem *i);
+static GdkPixbuf * ephy_tbi_location_get_icon_impl (EphyTbItem *i);
+static gchar * ephy_tbi_location_get_name_human_impl (EphyTbItem *i);
+static gchar * ephy_tbi_location_to_string_impl (EphyTbItem *i);
+static gboolean ephy_tbi_location_is_unique_impl (EphyTbItem *i);
+static EphyTbItem * ephy_tbi_location_clone_impl (EphyTbItem *i);
+static void ephy_tbi_location_parse_properties_impl (EphyTbItem *i, const gchar *props);
+static void ephy_tbi_location_add_to_bonobo_tb_impl (EphyTbItem *i,
+ BonoboUIComponent *ui,
+ const char *container_path,
+ guint index);
+
+static gpointer ephy_tb_item_class;
+
+/**
+ * TbiLocation object
+ */
+
+MAKE_GET_TYPE (ephy_tbi_location, "EphyTbiLocation", EphyTbiLocation, ephy_tbi_location_class_init,
+ ephy_tbi_location_init, EPHY_TYPE_TB_ITEM);
+
+static void
+ephy_tbi_location_class_init (EphyTbiLocationClass *klass)
+{
+ G_OBJECT_CLASS (klass)->finalize = ephy_tbi_location_finalize_impl;
+
+ EPHY_TB_ITEM_CLASS (klass)->get_widget = ephy_tbi_location_get_widget_impl;
+ EPHY_TB_ITEM_CLASS (klass)->get_icon = ephy_tbi_location_get_icon_impl;
+ EPHY_TB_ITEM_CLASS (klass)->get_name_human = ephy_tbi_location_get_name_human_impl;
+ EPHY_TB_ITEM_CLASS (klass)->to_string = ephy_tbi_location_to_string_impl;
+ EPHY_TB_ITEM_CLASS (klass)->is_unique = ephy_tbi_location_is_unique_impl;
+ EPHY_TB_ITEM_CLASS (klass)->clone = ephy_tbi_location_clone_impl;
+ EPHY_TB_ITEM_CLASS (klass)->parse_properties = ephy_tbi_location_parse_properties_impl;
+ EPHY_TB_ITEM_CLASS (klass)->add_to_bonobo_tb = ephy_tbi_location_add_to_bonobo_tb_impl;
+
+ ephy_tb_item_class = g_type_class_peek_parent (klass);
+}
+
+static void
+ephy_tbi_location_init (EphyTbiLocation *tb)
+{
+ EphyTbiLocationPrivate *p = g_new0 (EphyTbiLocationPrivate, 1);
+ tb->priv = p;
+}
+
+EphyTbiLocation *
+ephy_tbi_location_new (void)
+{
+ EphyTbiLocation *ret = g_object_new (EPHY_TYPE_TBI_LOCATION, NULL);
+ return ret;
+}
+
+static void
+ephy_tbi_location_finalize_impl (GObject *o)
+{
+ EphyTbiLocation *it = EPHY_TBI_LOCATION (o);
+ EphyTbiLocationPrivate *p = it->priv;
+
+ if (p->widget)
+ {
+ g_object_unref (p->widget);
+ }
+
+ g_free (p);
+
+ DEBUG_MSG (("EphyTbiLocation finalized\n"));
+
+ G_OBJECT_CLASS (ephy_tb_item_class)->finalize (o);
+}
+
+static GtkWidget *
+ephy_tbi_location_get_widget_impl (EphyTbItem *i)
+{
+ EphyTbiLocation *iz = EPHY_TBI_LOCATION (i);
+ EphyTbiLocationPrivate *p = iz->priv;
+
+ if (!p->widget)
+ {
+ p->widget = GTK_WIDGET (ephy_location_entry_new ());
+ g_object_ref (p->widget);
+ gtk_object_sink (GTK_OBJECT (p->widget));
+ }
+
+ return p->widget;
+}
+
+static GdkPixbuf *
+ephy_tbi_location_get_icon_impl (EphyTbItem *i)
+{
+ return NULL;
+}
+
+static gchar *
+ephy_tbi_location_get_name_human_impl (EphyTbItem *i)
+{
+ return g_strdup (_("Location entry"));
+}
+
+static gchar *
+ephy_tbi_location_to_string_impl (EphyTbItem *i)
+{
+ /* if it had any properties, the string should include them */
+ return g_strdup_printf ("%s=location", i->id);
+}
+
+static gboolean
+ephy_tbi_location_is_unique_impl (EphyTbItem *i)
+{
+ return TRUE;
+}
+
+static EphyTbItem *
+ephy_tbi_location_clone_impl (EphyTbItem *i)
+{
+ EphyTbItem *ret = EPHY_TB_ITEM (ephy_tbi_location_new ());
+
+ ephy_tb_item_set_id (ret, i->id);
+
+ /* should copy properties too, if any */
+ /* the location value is not copied, not sure if it should... */
+
+ return ret;
+}
+
+static void
+ephy_tbi_location_add_to_bonobo_tb_impl (EphyTbItem *i, BonoboUIComponent *uic,
+ const char *container_path, guint index)
+{
+ GtkWidget *w = ephy_tb_item_get_widget (i);
+ BonoboControl *control;
+ char *xml_string, *control_path;
+
+ gtk_widget_show (w);
+
+ g_return_if_fail (BONOBO_IS_UI_COMPONENT (uic));
+ g_return_if_fail (container_path != NULL);
+
+ xml_string = g_strdup_printf ("<control name=\"location\" behavior=\"expandable\"/>");
+
+ bonobo_ui_component_set (uic, container_path, xml_string, NULL);
+
+ g_free (xml_string);
+
+ control_path = g_strconcat (container_path, "/location", NULL);
+
+ control = bonobo_control_new (w);
+ bonobo_ui_component_object_set (uic, control_path, BONOBO_OBJREF (control), NULL);
+ bonobo_object_unref (control);
+
+ g_free (control_path);
+}
+
+static void
+ephy_tbi_location_parse_properties_impl (EphyTbItem *it, const gchar *props)
+{
+ /* we have no properties */
+}
+
diff --git a/lib/toolbar/ephy-tbi-location.h b/lib/toolbar/ephy-tbi-location.h
new file mode 100644
index 000000000..9188463f6
--- /dev/null
+++ b/lib/toolbar/ephy-tbi-location.h
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+#ifndef EPHY_TBI_LOCATION_H
+#define EPHY_TBI_LOCATION_H
+
+#include "ephy-toolbar-item.h"
+
+G_BEGIN_DECLS
+
+/* object forward declarations */
+
+typedef struct _EphyTbiLocation EphyTbiLocation;
+typedef struct _EphyTbiLocationClass EphyTbiLocationClass;
+typedef struct _EphyTbiLocationPrivate EphyTbiLocationPrivate;
+
+/**
+ * TbiLocation object
+ */
+
+#define EPHY_TYPE_TBI_LOCATION (ephy_tbi_location_get_type())
+#define EPHY_TBI_LOCATION(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EPHY_TYPE_TBI_LOCATION,\
+ EphyTbiLocation))
+#define EPHY_TBI_LOCATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EPHY_TYPE_TBI_LOCATION,\
+ EphyTbiLocationClass))
+#define EPHY_IS_TBI_LOCATION(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EPHY_TYPE_TBI_LOCATION))
+#define EPHY_IS_TBI_LOCATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EPHY_TYPE_TBI_LOCATION))
+#define EPHY_TBI_LOCATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_TBI_LOCATION,\
+ EphyTbiLocationClass))
+
+struct _EphyTbiLocationClass
+{
+ EphyTbItemClass parent_class;
+};
+
+/* Remember: fields are public read-only */
+struct _EphyTbiLocation
+{
+ EphyTbItem parent_object;
+
+ EphyTbiLocationPrivate *priv;
+};
+
+/* this class is abstract */
+
+GType ephy_tbi_location_get_type (void);
+EphyTbiLocation * ephy_tbi_location_new (void);
+
+G_END_DECLS
+
+#endif
diff --git a/lib/toolbar/ephy-tbi-navigation-history.c b/lib/toolbar/ephy-tbi-navigation-history.c
new file mode 100644
index 000000000..c6edc9865
--- /dev/null
+++ b/lib/toolbar/ephy-tbi-navigation-history.c
@@ -0,0 +1,342 @@
+/*
+ * 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
+
+#include <libgnome/gnome-i18n.h>
+#include <bonobo/bonobo-ui-toolbar-button-item.h>
+#include <bonobo/bonobo-property-bag.h>
+#include <gtk/gtktogglebutton.h>
+#include <gtk/gtkstock.h>
+#include <string.h>
+
+#include "ephy-tbi-navigation-history.h"
+#include "ephy-gobject-misc.h"
+#include "ephy-marshal.h"
+#include "ephy-bonobo-extensions.h"
+
+#define NOT_IMPLEMENTED g_warning ("not implemented: " G_STRLOC);
+//#define DEBUG_MSG(x) g_print x
+#define DEBUG_MSG(x)
+
+/**
+ * Private data
+ */
+struct _EphyTbiNavigationHistoryPrivate
+{
+ GtkWidget *widget;
+
+ EphyTbiNavigationHistoryDirection direction;
+};
+
+enum
+{
+ TOOLBAR_ITEM_STYLE_PROP,
+ TOOLBAR_ITEM_ORIENTATION_PROP,
+ TOOLBAR_ITEM_PRIORITY_PROP
+};
+
+/**
+ * Private functions, only availble from this file
+ */
+static void ephy_tbi_navigation_history_class_init (EphyTbiNavigationHistoryClass *klass);
+static void ephy_tbi_navigation_history_init (EphyTbiNavigationHistory *tb);
+static void ephy_tbi_navigation_history_finalize_impl (GObject *o);
+static GtkWidget * ephy_tbi_navigation_history_get_widget_impl (EphyTbItem *i);
+static GdkPixbuf * ephy_tbi_navigation_history_get_icon_impl (EphyTbItem *i);
+static gchar * ephy_tbi_navigation_history_get_name_human_impl (EphyTbItem *i);
+static gchar * ephy_tbi_navigation_history_to_string_impl (EphyTbItem *i);
+static gboolean ephy_tbi_navigation_history_is_unique_impl (EphyTbItem *i);
+static EphyTbItem * ephy_tbi_navigation_history_clone_impl (EphyTbItem *i);
+static void ephy_tbi_navigation_history_parse_properties_impl (EphyTbItem *i, const gchar *props);
+static void ephy_tbi_navigation_history_add_to_bonobo_tb_impl (EphyTbItem *i,
+ BonoboUIComponent *ui,
+ const char *container_path,
+ guint index);
+
+static gpointer ephy_tb_item_class;
+
+/**
+ * TbiNavigationHistory object
+ */
+
+MAKE_GET_TYPE (ephy_tbi_navigation_history, "EphyTbiNavigationHistory", EphyTbiNavigationHistory,
+ ephy_tbi_navigation_history_class_init,
+ ephy_tbi_navigation_history_init, EPHY_TYPE_TB_ITEM);
+
+static void
+ephy_tbi_navigation_history_class_init (EphyTbiNavigationHistoryClass *klass)
+{
+ G_OBJECT_CLASS (klass)->finalize = ephy_tbi_navigation_history_finalize_impl;
+
+ EPHY_TB_ITEM_CLASS (klass)->get_widget = ephy_tbi_navigation_history_get_widget_impl;
+ EPHY_TB_ITEM_CLASS (klass)->get_icon = ephy_tbi_navigation_history_get_icon_impl;
+ EPHY_TB_ITEM_CLASS (klass)->get_name_human = ephy_tbi_navigation_history_get_name_human_impl;
+ EPHY_TB_ITEM_CLASS (klass)->to_string = ephy_tbi_navigation_history_to_string_impl;
+ EPHY_TB_ITEM_CLASS (klass)->is_unique = ephy_tbi_navigation_history_is_unique_impl;
+ EPHY_TB_ITEM_CLASS (klass)->clone = ephy_tbi_navigation_history_clone_impl;
+ EPHY_TB_ITEM_CLASS (klass)->parse_properties = ephy_tbi_navigation_history_parse_properties_impl;
+ EPHY_TB_ITEM_CLASS (klass)->add_to_bonobo_tb = ephy_tbi_navigation_history_add_to_bonobo_tb_impl;
+
+ ephy_tb_item_class = g_type_class_peek_parent (klass);
+}
+
+static void
+ephy_tbi_navigation_history_init (EphyTbiNavigationHistory *tb)
+{
+ EphyTbiNavigationHistoryPrivate *p = g_new0 (EphyTbiNavigationHistoryPrivate, 1);
+ tb->priv = p;
+
+ p->direction = EPHY_TBI_NAVIGATION_HISTORY_BACK;
+}
+
+EphyTbiNavigationHistory *
+ephy_tbi_navigation_history_new (void)
+{
+ EphyTbiNavigationHistory *ret = g_object_new (EPHY_TYPE_TBI_NAVIGATION_HISTORY, NULL);
+ return ret;
+}
+
+static void
+ephy_tbi_navigation_history_finalize_impl (GObject *o)
+{
+ EphyTbiNavigationHistory *it = EPHY_TBI_NAVIGATION_HISTORY (o);
+ EphyTbiNavigationHistoryPrivate *p = it->priv;
+
+ if (p->widget)
+ {
+ g_object_unref (p->widget);
+ }
+
+ g_free (p);
+
+ DEBUG_MSG (("EphyTbiNavigationHistory finalized\n"));
+
+ G_OBJECT_CLASS (ephy_tb_item_class)->finalize (o);
+}
+
+static GtkWidget *
+ephy_tbi_navigation_history_get_widget_impl (EphyTbItem *i)
+{
+ EphyTbiNavigationHistory *iz = EPHY_TBI_NAVIGATION_HISTORY (i);
+ EphyTbiNavigationHistoryPrivate *p = iz->priv;
+
+ DEBUG_MSG (("in ephy_tbi_navigation_history_get_widget_impl\n"));
+ if (!p->widget)
+ {
+ DEBUG_MSG (("in ephy_tbi_navigation_history_get_widget_impl, really\n"));
+
+ p->widget = gtk_toggle_button_new ();
+ gtk_button_set_relief (GTK_BUTTON (p->widget), GTK_RELIEF_NONE);
+
+ gtk_container_add (GTK_CONTAINER (p->widget),
+ gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT));
+
+ g_object_ref (p->widget);
+ gtk_object_sink (GTK_OBJECT (p->widget));
+ }
+
+ return p->widget;
+}
+
+static GdkPixbuf *
+ephy_tbi_navigation_history_get_icon_impl (EphyTbItem *i)
+{
+ return NULL;
+}
+
+static gchar *
+ephy_tbi_navigation_history_get_name_human_impl (EphyTbItem *i)
+{
+ EphyTbiNavigationHistoryPrivate *p = EPHY_TBI_NAVIGATION_HISTORY (i)->priv;
+ const gchar *ret;
+
+ switch (p->direction)
+ {
+ case EPHY_TBI_NAVIGATION_HISTORY_BACK:
+ ret = _("Back History");
+ break;
+ case EPHY_TBI_NAVIGATION_HISTORY_FORWARD:
+ ret = _("Forward History");
+ break;
+ case EPHY_TBI_NAVIGATION_HISTORY_UP:
+ ret = _("Up Several Levels");
+ break;
+ default:
+ g_assert_not_reached ();
+ ret = "unknown";
+ }
+
+ return g_strdup (ret);
+}
+
+static gchar *
+ephy_tbi_navigation_history_to_string_impl (EphyTbItem *i)
+{
+ EphyTbiNavigationHistoryPrivate *p = EPHY_TBI_NAVIGATION_HISTORY (i)->priv;
+
+ /* if it had any properties, the string should include them */
+ const char *sdir;
+
+ switch (p->direction)
+ {
+ case EPHY_TBI_NAVIGATION_HISTORY_BACK:
+ sdir = "back";
+ break;
+ case EPHY_TBI_NAVIGATION_HISTORY_FORWARD:
+ sdir = "forward";
+ break;
+ case EPHY_TBI_NAVIGATION_HISTORY_UP:
+ sdir = "up";
+ break;
+ default:
+ g_assert_not_reached ();
+ sdir = "unknown";
+ }
+
+ return g_strdup_printf ("%s=navigation_history(direction=%s)", i->id, sdir);
+}
+
+static gboolean
+ephy_tbi_navigation_history_is_unique_impl (EphyTbItem *i)
+{
+ return TRUE;
+}
+
+static EphyTbItem *
+ephy_tbi_navigation_history_clone_impl (EphyTbItem *i)
+{
+ EphyTbiNavigationHistoryPrivate *p = EPHY_TBI_NAVIGATION_HISTORY (i)->priv;
+ EphyTbItem *ret = EPHY_TB_ITEM (ephy_tbi_navigation_history_new ());
+
+ ephy_tb_item_set_id (ret, i->id);
+
+ /* should copy properties too, if any */
+ ephy_tbi_navigation_history_set_direction (EPHY_TBI_NAVIGATION_HISTORY (ret), p->direction);
+
+ return ret;
+}
+
+static void
+ephy_tbi_navigation_history_property_set_cb (BonoboPropertyBag *bag,
+ const BonoboArg *arg,
+ guint arg_id,
+ CORBA_Environment *ev,
+ gpointer user_data)
+{
+ BonoboControl *control;
+ BonoboUIToolbarItem *item;
+ GtkOrientation orientation;
+ BonoboUIToolbarItemStyle style;
+
+ control = BONOBO_CONTROL (user_data);
+ item = BONOBO_UI_TOOLBAR_ITEM (bonobo_control_get_widget (control));
+
+ switch (arg_id) {
+ case TOOLBAR_ITEM_ORIENTATION_PROP:
+ orientation = BONOBO_ARG_GET_INT (arg);
+ bonobo_ui_toolbar_item_set_orientation (item, orientation);
+
+ if (GTK_WIDGET (item)->parent) {
+ gtk_widget_queue_resize (GTK_WIDGET (item)->parent);
+ }
+ break;
+ case TOOLBAR_ITEM_STYLE_PROP:
+ style = BONOBO_ARG_GET_INT (arg);
+ bonobo_ui_toolbar_item_set_style (item, style);
+ break;
+ }
+}
+
+static void
+ephy_tbi_navigation_history_add_to_bonobo_tb_impl (EphyTbItem *i, BonoboUIComponent *ui,
+ const char *container_path, guint index)
+{
+ BonoboPropertyBag *pb;
+ BonoboControl *wrapper;
+ BonoboUIToolbarItem *item;
+ GtkWidget *button;
+
+ DEBUG_MSG (("in ephy_tbi_navigation_history_add_to_bonobo_tb_impl\n"));
+
+ item = BONOBO_UI_TOOLBAR_ITEM (bonobo_ui_toolbar_item_new ());
+
+ button = ephy_tb_item_get_widget (i);
+ gtk_container_add (GTK_CONTAINER (item), button);
+ gtk_widget_show_all (GTK_WIDGET (item));
+
+ wrapper = ephy_bonobo_add_numbered_control (ui, GTK_WIDGET (item), index, container_path);
+
+ pb = bonobo_property_bag_new
+ (NULL, ephy_tbi_navigation_history_property_set_cb, wrapper);
+ bonobo_property_bag_add (pb, "style",
+ TOOLBAR_ITEM_STYLE_PROP,
+ BONOBO_ARG_INT, NULL, NULL,
+ Bonobo_PROPERTY_WRITEABLE);
+ bonobo_property_bag_add (pb, "orientation",
+ TOOLBAR_ITEM_ORIENTATION_PROP,
+ BONOBO_ARG_INT, NULL, NULL,
+ Bonobo_PROPERTY_WRITEABLE);
+ bonobo_control_set_properties (wrapper, BONOBO_OBJREF (pb), NULL);
+ bonobo_object_unref (pb);
+}
+
+static void
+ephy_tbi_navigation_history_parse_properties_impl (EphyTbItem *it, const gchar *props)
+{
+ EphyTbiNavigationHistory *a = EPHY_TBI_NAVIGATION_HISTORY (it);
+
+ /* yes, this is quite hacky, but works */
+
+ /* we have aproperty, the direction */
+ const gchar *direc_prop;
+
+ direc_prop = strstr (props, "direction=");
+ if (direc_prop)
+ {
+ direc_prop += strlen ("direction=");
+ if (!strncmp (direc_prop, "back", 4))
+ {
+ ephy_tbi_navigation_history_set_direction (a, EPHY_TBI_NAVIGATION_HISTORY_BACK);
+ }
+ else if (!strncmp (direc_prop, "forward", 4))
+ {
+ ephy_tbi_navigation_history_set_direction (a, EPHY_TBI_NAVIGATION_HISTORY_FORWARD);
+ }
+ else if (!strncmp (direc_prop, "up", 2))
+ {
+ ephy_tbi_navigation_history_set_direction (a, EPHY_TBI_NAVIGATION_HISTORY_UP);
+ }
+ }
+}
+
+void
+ephy_tbi_navigation_history_set_direction (EphyTbiNavigationHistory *a, EphyTbiNavigationHistoryDirection d)
+{
+ EphyTbiNavigationHistoryPrivate *p = a->priv;
+
+ g_return_if_fail (d == EPHY_TBI_NAVIGATION_HISTORY_UP
+ || d == EPHY_TBI_NAVIGATION_HISTORY_BACK
+ || d == EPHY_TBI_NAVIGATION_HISTORY_FORWARD);
+
+ p->direction = d;
+
+}
+
diff --git a/lib/toolbar/ephy-tbi-navigation-history.h b/lib/toolbar/ephy-tbi-navigation-history.h
new file mode 100644
index 000000000..29cb6c32a
--- /dev/null
+++ b/lib/toolbar/ephy-tbi-navigation-history.h
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+#ifndef EPHY_TBI_NAVIGATION_HISTORY_H
+#define EPHY_TBI_NAVIGATION_HISTORY_H
+
+#include "ephy-toolbar-item.h"
+
+G_BEGIN_DECLS
+
+/* object forward declarations */
+
+typedef struct _EphyTbiNavigationHistory EphyTbiNavigationHistory;
+typedef struct _EphyTbiNavigationHistoryClass EphyTbiNavigationHistoryClass;
+typedef struct _EphyTbiNavigationHistoryPrivate EphyTbiNavigationHistoryPrivate;
+
+/**
+ * TbiNavigationHistory object
+ */
+
+#define EPHY_TYPE_TBI_NAVIGATION_HISTORY (ephy_tbi_navigation_history_get_type())
+#define EPHY_TBI_NAVIGATION_HISTORY(object) (G_TYPE_CHECK_INSTANCE_CAST((object), \
+ EPHY_TYPE_TBI_NAVIGATION_HISTORY,\
+ EphyTbiNavigationHistory))
+#define EPHY_TBI_NAVIGATION_HISTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \
+ EPHY_TYPE_TBI_NAVIGATION_HISTORY,\
+ EphyTbiNavigationHistoryClass))
+#define EPHY_IS_TBI_NAVIGATION_HISTORY(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), \
+ EPHY_TYPE_TBI_NAVIGATION_HISTORY))
+#define EPHY_IS_TBI_NAVIGATION_HISTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), \
+ EPHY_TYPE_TBI_NAVIGATION_HISTORY))
+#define EPHY_TBI_NAVIGATION_HISTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \
+ EPHY_TYPE_TBI_NAVIGATION_HISTORY,\
+ EphyTbiNavigationHistoryClass))
+typedef enum
+{
+ EPHY_TBI_NAVIGATION_HISTORY_UP,
+ EPHY_TBI_NAVIGATION_HISTORY_BACK,
+ EPHY_TBI_NAVIGATION_HISTORY_FORWARD
+} EphyTbiNavigationHistoryDirection;
+
+
+struct _EphyTbiNavigationHistoryClass
+{
+ EphyTbItemClass parent_class;
+};
+
+/* Remember: fields are public read-only */
+struct _EphyTbiNavigationHistory
+{
+ EphyTbItem parent_object;
+
+ EphyTbiNavigationHistoryPrivate *priv;
+};
+
+/* this class is abstract */
+
+GType ephy_tbi_navigation_history_get_type (void);
+EphyTbiNavigationHistory *ephy_tbi_navigation_history_new (void);
+void ephy_tbi_navigation_history_set_direction (EphyTbiNavigationHistory *a,
+ EphyTbiNavigationHistoryDirection d);
+
+G_END_DECLS
+
+#endif
+
diff --git a/lib/toolbar/ephy-tbi-separator.c b/lib/toolbar/ephy-tbi-separator.c
new file mode 100644
index 000000000..43f69bd96
--- /dev/null
+++ b/lib/toolbar/ephy-tbi-separator.c
@@ -0,0 +1,179 @@
+/*
+ * 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
+
+#include <libgnome/gnome-i18n.h>
+#include <gtk/gtkstock.h>
+
+#include "ephy-tbi-separator.h"
+#include "ephy-gobject-misc.h"
+#include "ephy-marshal.h"
+#include "ephy-bonobo-extensions.h"
+
+#define NOT_IMPLEMENTED g_warning ("not implemented: " G_STRLOC);
+//#define DEBUG_MSG(x) g_print x
+#define DEBUG_MSG(x)
+
+/**
+ * Private data
+ */
+struct _EphyTbiSeparatorPrivate
+{
+ GtkWidget *widget;
+};
+
+/**
+ * Private functions, only availble from this file
+ */
+static void ephy_tbi_separator_class_init (EphyTbiSeparatorClass *klass);
+static void ephy_tbi_separator_init (EphyTbiSeparator *tb);
+static void ephy_tbi_separator_finalize_impl (GObject *o);
+static GtkWidget * ephy_tbi_separator_get_widget_impl (EphyTbItem *i);
+static GdkPixbuf * ephy_tbi_separator_get_icon_impl (EphyTbItem *i);
+static gchar * ephy_tbi_separator_get_name_human_impl (EphyTbItem *i);
+static gchar * ephy_tbi_separator_to_string_impl (EphyTbItem *i);
+static gboolean ephy_tbi_separator_is_unique_impl (EphyTbItem *i);
+static EphyTbItem * ephy_tbi_separator_clone_impl (EphyTbItem *i);
+static void ephy_tbi_separator_parse_properties_impl(EphyTbItem *i, const gchar *props);
+static void ephy_tbi_separator_add_to_bonobo_tb_impl(EphyTbItem *i,
+ BonoboUIComponent *ui,
+ const char *container_path,
+ guint index);
+
+static gpointer ephy_tb_item_class;
+
+/**
+ * TbiSeparator object
+ */
+
+MAKE_GET_TYPE (ephy_tbi_separator, "EphyTbiSeparator", EphyTbiSeparator, ephy_tbi_separator_class_init,
+ ephy_tbi_separator_init, EPHY_TYPE_TB_ITEM);
+
+static void
+ephy_tbi_separator_class_init (EphyTbiSeparatorClass *klass)
+{
+ G_OBJECT_CLASS (klass)->finalize = ephy_tbi_separator_finalize_impl;
+
+ EPHY_TB_ITEM_CLASS (klass)->get_widget = ephy_tbi_separator_get_widget_impl;
+ EPHY_TB_ITEM_CLASS (klass)->get_icon = ephy_tbi_separator_get_icon_impl;
+ EPHY_TB_ITEM_CLASS (klass)->get_name_human = ephy_tbi_separator_get_name_human_impl;
+ EPHY_TB_ITEM_CLASS (klass)->to_string = ephy_tbi_separator_to_string_impl;
+ EPHY_TB_ITEM_CLASS (klass)->is_unique = ephy_tbi_separator_is_unique_impl;
+ EPHY_TB_ITEM_CLASS (klass)->clone = ephy_tbi_separator_clone_impl;
+ EPHY_TB_ITEM_CLASS (klass)->parse_properties = ephy_tbi_separator_parse_properties_impl;
+ EPHY_TB_ITEM_CLASS (klass)->add_to_bonobo_tb = ephy_tbi_separator_add_to_bonobo_tb_impl;
+
+ ephy_tb_item_class = g_type_class_peek_parent (klass);
+}
+
+static void
+ephy_tbi_separator_init (EphyTbiSeparator *tb)
+{
+ EphyTbiSeparatorPrivate *p = g_new0 (EphyTbiSeparatorPrivate, 1);
+ tb->priv = p;
+}
+
+EphyTbiSeparator *
+ephy_tbi_separator_new (void)
+{
+ EphyTbiSeparator *ret = g_object_new (EPHY_TYPE_TBI_SEPARATOR, NULL);
+ return ret;
+}
+
+static void
+ephy_tbi_separator_finalize_impl (GObject *o)
+{
+ EphyTbiSeparator *it = EPHY_TBI_SEPARATOR (o);
+ EphyTbiSeparatorPrivate *p = it->priv;
+
+ if (p->widget)
+ {
+ g_object_unref (p->widget);
+ }
+
+ g_free (p);
+
+ DEBUG_MSG (("EphyTbiSeparator finalized\n"));
+
+ G_OBJECT_CLASS (ephy_tb_item_class)->finalize (o);
+}
+
+static GtkWidget *
+ephy_tbi_separator_get_widget_impl (EphyTbItem *i)
+{
+ return NULL;
+}
+
+static GdkPixbuf *
+ephy_tbi_separator_get_icon_impl (EphyTbItem *i)
+{
+ return NULL;
+}
+
+static gchar *
+ephy_tbi_separator_get_name_human_impl (EphyTbItem *i)
+{
+ return g_strdup (_("Separator"));
+}
+
+static gchar *
+ephy_tbi_separator_to_string_impl (EphyTbItem *i)
+{
+ /* if it had any properties, the string should include them */
+ return g_strdup_printf ("%s=separator", i->id);
+}
+
+static gboolean
+ephy_tbi_separator_is_unique_impl (EphyTbItem *i)
+{
+ return FALSE;
+}
+
+static EphyTbItem *
+ephy_tbi_separator_clone_impl (EphyTbItem *i)
+{
+ EphyTbItem *ret = EPHY_TB_ITEM (ephy_tbi_separator_new ());
+
+ ephy_tb_item_set_id (ret, i->id);
+
+ /* should copy properties too, if any */
+
+ return ret;
+}
+
+static void
+ephy_tbi_separator_add_to_bonobo_tb_impl (EphyTbItem *i, BonoboUIComponent *ui,
+ const char *container_path, guint index)
+{
+ static gint hack = 0;
+ gchar *xml;
+
+ xml = g_strdup_printf ("<separator name=\"sep%d\"/>", ++hack);
+ bonobo_ui_component_set (ui, container_path, xml, NULL);
+ g_free (xml);
+}
+
+static void
+ephy_tbi_separator_parse_properties_impl (EphyTbItem *it, const gchar *props)
+{
+ /* we have no properties */
+}
+
diff --git a/lib/toolbar/ephy-tbi-separator.h b/lib/toolbar/ephy-tbi-separator.h
new file mode 100644
index 000000000..754d85fec
--- /dev/null
+++ b/lib/toolbar/ephy-tbi-separator.h
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+#ifndef EPHY_TBI_SEPARATOR_H
+#define EPHY_TBI_SEPARATOR_H
+
+#include "ephy-toolbar-item.h"
+
+G_BEGIN_DECLS
+
+/* object forward declarations */
+
+typedef struct _EphyTbiSeparator EphyTbiSeparator;
+typedef struct _EphyTbiSeparatorClass EphyTbiSeparatorClass;
+typedef struct _EphyTbiSeparatorPrivate EphyTbiSeparatorPrivate;
+
+/**
+ * TbiSeparator object
+ */
+
+#define EPHY_TYPE_TBI_SEPARATOR (ephy_tbi_separator_get_type())
+#define EPHY_TBI_SEPARATOR(object) (G_TYPE_CHECK_INSTANCE_CAST((object), \
+ EPHY_TYPE_TBI_SEPARATOR,\
+ EphyTbiSeparator))
+#define EPHY_TBI_SEPARATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EPHY_TYPE_TBI_SEPARATOR,\
+ EphyTbiSeparatorClass))
+#define EPHY_IS_TBI_SEPARATOR(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), \
+ EPHY_TYPE_TBI_SEPARATOR))
+#define EPHY_IS_TBI_SEPARATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EPHY_TYPE_TBI_SEPARATOR))
+#define EPHY_TBI_SEPARATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_TBI_SEPARATOR,\
+ EphyTbiSeparatorClass))
+
+struct _EphyTbiSeparatorClass
+{
+ EphyTbItemClass parent_class;
+};
+
+/* Remember: fields are public read-only */
+struct _EphyTbiSeparator
+{
+ EphyTbItem parent_object;
+
+ EphyTbiSeparatorPrivate *priv;
+};
+
+/* this class is abstract */
+
+GType ephy_tbi_separator_get_type (void);
+EphyTbiSeparator * ephy_tbi_separator_new (void);
+
+G_END_DECLS
+
+#endif
diff --git a/lib/toolbar/ephy-tbi-spinner.c b/lib/toolbar/ephy-tbi-spinner.c
new file mode 100644
index 000000000..6f37764ec
--- /dev/null
+++ b/lib/toolbar/ephy-tbi-spinner.c
@@ -0,0 +1,188 @@
+/*
+ * 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
+
+#include <libgnome/gnome-i18n.h>
+#include <gtk/gtkhbox.h>
+
+#include "ephy-tbi-spinner.h"
+#include "ephy-gobject-misc.h"
+#include "ephy-marshal.h"
+#include "ephy-bonobo-extensions.h"
+
+#define NOT_IMPLEMENTED g_warning ("not implemented: " G_STRLOC);
+//#define DEBUG_MSG(x) g_print x
+#define DEBUG_MSG(x)
+
+/**
+ * Private data
+ */
+struct _EphyTbiSpinnerPrivate
+{
+ GtkWidget *widget;
+};
+
+/**
+ * Private functions, only availble from this file
+ */
+static void ephy_tbi_spinner_class_init (EphyTbiSpinnerClass *klass);
+static void ephy_tbi_spinner_init (EphyTbiSpinner *tb);
+static void ephy_tbi_spinner_finalize_impl (GObject *o);
+static GtkWidget * ephy_tbi_spinner_get_widget_impl (EphyTbItem *i);
+static GdkPixbuf * ephy_tbi_spinner_get_icon_impl (EphyTbItem *i);
+static gchar * ephy_tbi_spinner_get_name_human_impl (EphyTbItem *i);
+static gchar * ephy_tbi_spinner_to_string_impl (EphyTbItem *i);
+static gboolean ephy_tbi_spinner_is_unique_impl (EphyTbItem *i);
+static EphyTbItem * ephy_tbi_spinner_clone_impl (EphyTbItem *i);
+static void ephy_tbi_spinner_parse_properties_impl (EphyTbItem *i, const gchar *props);
+static void ephy_tbi_spinner_add_to_bonobo_tb_impl (EphyTbItem *i,
+ BonoboUIComponent *ui,
+ const char *container_path,
+ guint index);
+
+static gpointer ephy_tb_item_class;
+
+/**
+ * TbiSpinner object
+ */
+
+MAKE_GET_TYPE (ephy_tbi_spinner, "EphyTbiSpinner", EphyTbiSpinner, ephy_tbi_spinner_class_init,
+ ephy_tbi_spinner_init, EPHY_TYPE_TB_ITEM);
+
+static void
+ephy_tbi_spinner_class_init (EphyTbiSpinnerClass *klass)
+{
+ G_OBJECT_CLASS (klass)->finalize = ephy_tbi_spinner_finalize_impl;
+
+ EPHY_TB_ITEM_CLASS (klass)->get_widget = ephy_tbi_spinner_get_widget_impl;
+ EPHY_TB_ITEM_CLASS (klass)->get_icon = ephy_tbi_spinner_get_icon_impl;
+ EPHY_TB_ITEM_CLASS (klass)->get_name_human = ephy_tbi_spinner_get_name_human_impl;
+ EPHY_TB_ITEM_CLASS (klass)->to_string = ephy_tbi_spinner_to_string_impl;
+ EPHY_TB_ITEM_CLASS (klass)->is_unique = ephy_tbi_spinner_is_unique_impl;
+ EPHY_TB_ITEM_CLASS (klass)->clone = ephy_tbi_spinner_clone_impl;
+ EPHY_TB_ITEM_CLASS (klass)->parse_properties = ephy_tbi_spinner_parse_properties_impl;
+ EPHY_TB_ITEM_CLASS (klass)->add_to_bonobo_tb = ephy_tbi_spinner_add_to_bonobo_tb_impl;
+
+ ephy_tb_item_class = g_type_class_peek_parent (klass);
+}
+
+static void
+ephy_tbi_spinner_init (EphyTbiSpinner *tb)
+{
+ EphyTbiSpinnerPrivate *p = g_new0 (EphyTbiSpinnerPrivate, 1);
+ tb->priv = p;
+}
+
+EphyTbiSpinner *
+ephy_tbi_spinner_new (void)
+{
+ EphyTbiSpinner *ret = g_object_new (EPHY_TYPE_TBI_SPINNER, NULL);
+ return ret;
+}
+
+static void
+ephy_tbi_spinner_finalize_impl (GObject *o)
+{
+ EphyTbiSpinner *it = EPHY_TBI_SPINNER (o);
+ EphyTbiSpinnerPrivate *p = it->priv;
+
+ if (p->widget)
+ {
+ g_object_unref (p->widget);
+ }
+
+ g_free (p);
+
+ DEBUG_MSG (("EphyTbiSpinner finalized\n"));
+
+ G_OBJECT_CLASS (ephy_tb_item_class)->finalize (o);
+}
+
+static GtkWidget *
+ephy_tbi_spinner_get_widget_impl (EphyTbItem *i)
+{
+ EphyTbiSpinner *iz = EPHY_TBI_SPINNER (i);
+ EphyTbiSpinnerPrivate *p = iz->priv;
+
+ if (!p->widget)
+ {
+ /* here, we create only a box */
+ p->widget = gtk_hbox_new (FALSE, 0);
+ g_object_ref (p->widget);
+ gtk_object_sink (GTK_OBJECT (p->widget));
+ }
+
+ return p->widget;
+}
+
+static GdkPixbuf *
+ephy_tbi_spinner_get_icon_impl (EphyTbItem *i)
+{
+ /* need an icon for this */
+ return NULL;
+}
+
+static gchar *
+ephy_tbi_spinner_get_name_human_impl (EphyTbItem *i)
+{
+ return g_strdup (_("Spinner"));
+}
+
+static gchar *
+ephy_tbi_spinner_to_string_impl (EphyTbItem *i)
+{
+ /* if it had any properties, the string should include them */
+ return g_strdup_printf ("%s=spinner", i->id);
+}
+
+static gboolean
+ephy_tbi_spinner_is_unique_impl (EphyTbItem *i)
+{
+ return TRUE;
+}
+
+static EphyTbItem *
+ephy_tbi_spinner_clone_impl (EphyTbItem *i)
+{
+ EphyTbItem *ret = EPHY_TB_ITEM (ephy_tbi_spinner_new ());
+
+ ephy_tb_item_set_id (ret, i->id);
+
+ /* should copy properties too, if any */
+
+ return ret;
+}
+
+static void
+ephy_tbi_spinner_add_to_bonobo_tb_impl (EphyTbItem *i, BonoboUIComponent *ui,
+ const char *container_path, guint index)
+{
+ GtkWidget *w = ephy_tb_item_get_widget (i);
+ gtk_widget_show (w);
+ ephy_bonobo_add_numbered_control (ui, w, index, container_path);
+}
+
+static void
+ephy_tbi_spinner_parse_properties_impl (EphyTbItem *it, const gchar *props)
+{
+ /* we have no properties */
+}
+
diff --git a/lib/toolbar/ephy-tbi-spinner.h b/lib/toolbar/ephy-tbi-spinner.h
new file mode 100644
index 000000000..1bb04f277
--- /dev/null
+++ b/lib/toolbar/ephy-tbi-spinner.h
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+#ifndef EPHY_TBI_SPINNER_H
+#define EPHY_TBI_SPINNER_H
+
+#include "ephy-toolbar-item.h"
+
+G_BEGIN_DECLS
+
+/* object forward declarations */
+
+typedef struct _EphyTbiSpinner EphyTbiSpinner;
+typedef struct _EphyTbiSpinnerClass EphyTbiSpinnerClass;
+typedef struct _EphyTbiSpinnerPrivate EphyTbiSpinnerPrivate;
+
+/**
+ * TbiSpinner object
+ */
+
+#define EPHY_TYPE_TBI_SPINNER (ephy_tbi_spinner_get_type())
+#define EPHY_TBI_SPINNER(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EPHY_TYPE_TBI_SPINNER,\
+ EphyTbiSpinner))
+#define EPHY_TBI_SPINNER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EPHY_TYPE_TBI_SPINNER,\
+ EphyTbiSpinnerClass))
+#define EPHY_IS_TBI_SPINNER(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EPHY_TYPE_TBI_SPINNER))
+#define EPHY_IS_TBI_SPINNER_CLASS(klass)(G_TYPE_CHECK_CLASS_TYPE((klass), EPHY_TYPE_TBI_SPINNER))
+#define EPHY_TBI_SPINNER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_TBI_SPINNER,\
+ EphyTbiSpinnerClass))
+
+struct _EphyTbiSpinnerClass
+{
+ EphyTbItemClass parent_class;
+};
+
+/* Remember: fields are public read-only */
+struct _EphyTbiSpinner
+{
+ EphyTbItem parent_object;
+
+ EphyTbiSpinnerPrivate *priv;
+};
+
+/* this class is abstract */
+
+GType ephy_tbi_spinner_get_type (void);
+EphyTbiSpinner * ephy_tbi_spinner_new (void);
+
+G_END_DECLS
+
+#endif
diff --git a/lib/toolbar/ephy-tbi-std-toolitem.c b/lib/toolbar/ephy-tbi-std-toolitem.c
new file mode 100644
index 000000000..deb468ecb
--- /dev/null
+++ b/lib/toolbar/ephy-tbi-std-toolitem.c
@@ -0,0 +1,467 @@
+/*
+ * 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
+
+#include <libgnome/gnome-i18n.h>
+#include <bonobo/bonobo-ui-toolbar-button-item.h>
+#include <bonobo/bonobo-property-bag.h>
+#include <gtk/gtkstock.h>
+#include <string.h>
+
+#include "ephy-tbi-std-toolitem.h"
+#include "ephy-gobject-misc.h"
+#include "ephy-marshal.h"
+#include "ephy-bonobo-extensions.h"
+
+#define NOT_IMPLEMENTED g_warning ("not implemented: " G_STRLOC);
+//#define DEBUG_MSG(x) g_print x
+#define DEBUG_MSG(x)
+
+/**
+ * Private data
+ */
+struct _EphyTbiStdToolitemPrivate
+{
+ GtkWidget *widget;
+
+ EphyTbiStdToolitemItem item;
+};
+
+
+/**
+ * Private functions, only availble from this file
+ */
+static void ephy_tbi_std_toolitem_class_init (EphyTbiStdToolitemClass *klass);
+static void ephy_tbi_std_toolitem_init (EphyTbiStdToolitem *tb);
+static void ephy_tbi_std_toolitem_finalize_impl (GObject *o);
+static GtkWidget * ephy_tbi_std_toolitem_get_widget_impl (EphyTbItem *i);
+static GdkPixbuf * ephy_tbi_std_toolitem_get_icon_impl (EphyTbItem *i);
+static gchar * ephy_tbi_std_toolitem_get_name_human_impl (EphyTbItem *i);
+static gchar * ephy_tbi_std_toolitem_to_string_impl (EphyTbItem *i);
+static gboolean ephy_tbi_std_toolitem_is_unique_impl (EphyTbItem *i);
+static EphyTbItem * ephy_tbi_std_toolitem_clone_impl (EphyTbItem *i);
+static void ephy_tbi_std_toolitem_parse_properties_impl (EphyTbItem *i, const gchar *props);
+static void ephy_tbi_std_toolitem_add_to_bonobo_tb_impl (EphyTbItem *i,
+ BonoboUIComponent *ui,
+ const char *container_path,
+ guint index);
+
+static gpointer ephy_tb_item_class;
+
+/**
+ * TbiStdToolitem object
+ */
+
+MAKE_GET_TYPE (ephy_tbi_std_toolitem, "EphyTbiStdToolitem", EphyTbiStdToolitem,
+ ephy_tbi_std_toolitem_class_init,
+ ephy_tbi_std_toolitem_init, EPHY_TYPE_TB_ITEM);
+
+static void
+ephy_tbi_std_toolitem_class_init (EphyTbiStdToolitemClass *klass)
+{
+ G_OBJECT_CLASS (klass)->finalize = ephy_tbi_std_toolitem_finalize_impl;
+
+ EPHY_TB_ITEM_CLASS (klass)->get_widget = ephy_tbi_std_toolitem_get_widget_impl;
+ EPHY_TB_ITEM_CLASS (klass)->get_icon = ephy_tbi_std_toolitem_get_icon_impl;
+ EPHY_TB_ITEM_CLASS (klass)->get_name_human = ephy_tbi_std_toolitem_get_name_human_impl;
+ EPHY_TB_ITEM_CLASS (klass)->to_string = ephy_tbi_std_toolitem_to_string_impl;
+ EPHY_TB_ITEM_CLASS (klass)->is_unique = ephy_tbi_std_toolitem_is_unique_impl;
+ EPHY_TB_ITEM_CLASS (klass)->clone = ephy_tbi_std_toolitem_clone_impl;
+ EPHY_TB_ITEM_CLASS (klass)->parse_properties = ephy_tbi_std_toolitem_parse_properties_impl;
+ EPHY_TB_ITEM_CLASS (klass)->add_to_bonobo_tb = ephy_tbi_std_toolitem_add_to_bonobo_tb_impl;
+
+ ephy_tb_item_class = g_type_class_peek_parent (klass);
+}
+
+static void
+ephy_tbi_std_toolitem_init (EphyTbiStdToolitem *tb)
+{
+ EphyTbiStdToolitemPrivate *p = g_new0 (EphyTbiStdToolitemPrivate, 1);
+ tb->priv = p;
+
+ p->item = EPHY_TBI_STD_TOOLITEM_BACK;
+}
+
+EphyTbiStdToolitem *
+ephy_tbi_std_toolitem_new (void)
+{
+ EphyTbiStdToolitem *ret = g_object_new (EPHY_TYPE_TBI_STD_TOOLITEM, NULL);
+ return ret;
+}
+
+static void
+ephy_tbi_std_toolitem_finalize_impl (GObject *o)
+{
+ EphyTbiStdToolitem *it = EPHY_TBI_STD_TOOLITEM (o);
+ EphyTbiStdToolitemPrivate *p = it->priv;
+
+ if (p->widget)
+ {
+ g_object_unref (p->widget);
+ }
+
+ g_free (p);
+
+ DEBUG_MSG (("EphyTbiStdToolitem finalized\n"));
+
+ G_OBJECT_CLASS (ephy_tb_item_class)->finalize (o);
+}
+
+static GtkWidget *
+ephy_tbi_std_toolitem_get_widget_impl (EphyTbItem *i)
+{
+ /* no widget avaible ... */
+ return NULL;
+}
+
+static GdkPixbuf *
+ephy_tbi_std_toolitem_get_icon_impl (EphyTbItem *i)
+{
+ EphyTbiStdToolitemPrivate *p = EPHY_TBI_STD_TOOLITEM (i)->priv;
+
+ static GdkPixbuf *pb_up = NULL;
+ static GdkPixbuf *pb_back = NULL;
+ static GdkPixbuf *pb_forward = NULL;
+ static GdkPixbuf *pb_stop = NULL;
+ static GdkPixbuf *pb_reload = NULL;
+ static GdkPixbuf *pb_home = NULL;
+ static GdkPixbuf *pb_go = NULL;
+ static GdkPixbuf *pb_new = NULL;
+
+ if (!pb_up)
+ {
+ /* what's the easier way? */
+ GtkWidget *b = gtk_spin_button_new_with_range (0, 1, 0.5);
+ pb_up = gtk_widget_render_icon (b,
+ GTK_STOCK_GO_UP,
+ GTK_ICON_SIZE_SMALL_TOOLBAR,
+ NULL);
+ pb_back = gtk_widget_render_icon (b,
+ GTK_STOCK_GO_BACK,
+ GTK_ICON_SIZE_SMALL_TOOLBAR,
+ NULL);
+ pb_forward = gtk_widget_render_icon (b,
+ GTK_STOCK_GO_FORWARD,
+ GTK_ICON_SIZE_SMALL_TOOLBAR,
+ NULL);
+ pb_stop = gtk_widget_render_icon (b,
+ GTK_STOCK_STOP,
+ GTK_ICON_SIZE_SMALL_TOOLBAR,
+ NULL);
+ pb_reload = gtk_widget_render_icon (b,
+ GTK_STOCK_REFRESH,
+ GTK_ICON_SIZE_SMALL_TOOLBAR,
+ NULL);
+ pb_home = gtk_widget_render_icon (b,
+ GTK_STOCK_HOME,
+ GTK_ICON_SIZE_SMALL_TOOLBAR,
+ NULL);
+ pb_go = gtk_widget_render_icon (b,
+ GTK_STOCK_JUMP_TO,
+ GTK_ICON_SIZE_SMALL_TOOLBAR,
+ NULL);
+ pb_new = gtk_widget_render_icon (b,
+ GTK_STOCK_NEW,
+ GTK_ICON_SIZE_SMALL_TOOLBAR,
+ NULL);
+ gtk_widget_destroy (b);
+ }
+
+ switch (p->item)
+ {
+ case EPHY_TBI_STD_TOOLITEM_BACK:
+ return g_object_ref (pb_back);
+ break;
+ case EPHY_TBI_STD_TOOLITEM_FORWARD:
+ return g_object_ref (pb_forward);
+ break;
+ case EPHY_TBI_STD_TOOLITEM_UP:
+ return g_object_ref (pb_up);
+ break;
+ case EPHY_TBI_STD_TOOLITEM_STOP:
+ return g_object_ref (pb_stop);
+ break;
+ case EPHY_TBI_STD_TOOLITEM_RELOAD:
+ return g_object_ref (pb_reload);
+ break;
+ case EPHY_TBI_STD_TOOLITEM_HOME:
+ return g_object_ref (pb_home);
+ break;
+ case EPHY_TBI_STD_TOOLITEM_GO:
+ return g_object_ref (pb_go);
+ break;
+ case EPHY_TBI_STD_TOOLITEM_NEW:
+ return g_object_ref (pb_new);
+ break;
+ default:
+ g_assert_not_reached ();
+ return NULL;
+ }
+}
+
+static gchar *
+ephy_tbi_std_toolitem_get_name_human_impl (EphyTbItem *i)
+{
+ EphyTbiStdToolitemPrivate *p = EPHY_TBI_STD_TOOLITEM (i)->priv;
+ const gchar *ret;
+
+ switch (p->item)
+ {
+ case EPHY_TBI_STD_TOOLITEM_BACK:
+ ret = _("Back");
+ break;
+ case EPHY_TBI_STD_TOOLITEM_FORWARD:
+ ret = _("Forward");
+ break;
+ case EPHY_TBI_STD_TOOLITEM_UP:
+ ret = _("Up");
+ break;
+ case EPHY_TBI_STD_TOOLITEM_STOP:
+ ret = _("Stop");
+ break;
+ case EPHY_TBI_STD_TOOLITEM_RELOAD:
+ ret = _("Reload");
+ break;
+ case EPHY_TBI_STD_TOOLITEM_HOME:
+ ret = _("Home");
+ break;
+ case EPHY_TBI_STD_TOOLITEM_GO:
+ ret = _("Go");
+ break;
+ case EPHY_TBI_STD_TOOLITEM_NEW:
+ ret = _("New");
+ break;
+ default:
+ g_assert_not_reached ();
+ ret = "unknown";
+ }
+
+ return g_strdup (ret);
+}
+
+static gchar *
+ephy_tbi_std_toolitem_to_string_impl (EphyTbItem *i)
+{
+ EphyTbiStdToolitemPrivate *p = EPHY_TBI_STD_TOOLITEM (i)->priv;
+
+ /* if it had any properties, the string should include them */
+ const char *sitem;
+
+ switch (p->item)
+ {
+ case EPHY_TBI_STD_TOOLITEM_BACK:
+ sitem = "back";
+ break;
+ case EPHY_TBI_STD_TOOLITEM_FORWARD:
+ sitem = "forward";
+ break;
+ case EPHY_TBI_STD_TOOLITEM_UP:
+ sitem = "up";
+ break;
+ case EPHY_TBI_STD_TOOLITEM_STOP:
+ sitem = "stop";
+ break;
+ case EPHY_TBI_STD_TOOLITEM_RELOAD:
+ sitem = "reload";
+ break;
+ case EPHY_TBI_STD_TOOLITEM_HOME:
+ sitem = "home";
+ break;
+ case EPHY_TBI_STD_TOOLITEM_GO:
+ sitem = "go";
+ break;
+ case EPHY_TBI_STD_TOOLITEM_NEW:
+ sitem = "new";
+ break;
+ default:
+ g_assert_not_reached ();
+ sitem = "unknown";
+ }
+
+ return g_strdup_printf ("%s=std_toolitem(item=%s)", i->id, sitem);
+}
+
+static gboolean
+ephy_tbi_std_toolitem_is_unique_impl (EphyTbItem *i)
+{
+ return TRUE;
+}
+
+static EphyTbItem *
+ephy_tbi_std_toolitem_clone_impl (EphyTbItem *i)
+{
+ EphyTbiStdToolitemPrivate *p = EPHY_TBI_STD_TOOLITEM (i)->priv;
+
+ EphyTbItem *ret = EPHY_TB_ITEM (ephy_tbi_std_toolitem_new ());
+
+ ephy_tb_item_set_id (ret, i->id);
+
+ /* should copy properties too, if any */
+ ephy_tbi_std_toolitem_set_item (EPHY_TBI_STD_TOOLITEM (ret), p->item);
+
+ return ret;
+}
+
+
+static void
+ephy_tbi_std_toolitem_add_to_bonobo_tb_impl (EphyTbItem *i, BonoboUIComponent *ui,
+ const char *container_path, guint index)
+{
+ EphyTbiStdToolitemPrivate *p = EPHY_TBI_STD_TOOLITEM (i)->priv;
+ gchar *xml_item;
+
+ switch (p->item)
+ {
+ case EPHY_TBI_STD_TOOLITEM_BACK:
+ xml_item = g_strdup_printf
+ ("<toolitem name=\"Back\" "
+ "label=\"%s\" "
+ "pixtype=\"stock\" pixname=\"gtk-go-back\" "
+ "priority=\"1\" "
+ "verb=\"GoBack\"/>", _("Back"));;
+ break;
+ case EPHY_TBI_STD_TOOLITEM_FORWARD:
+ xml_item = g_strdup_printf
+ ("<toolitem name=\"Forward\" "
+ "label=\"%s\" "
+ "pixtype=\"stock\" pixname=\"gtk-go-forward\" "
+ "verb=\"GoForward\"/>", _("Forward"));
+ break;
+ case EPHY_TBI_STD_TOOLITEM_UP:
+ xml_item = g_strdup_printf
+ ("<toolitem name=\"Up\" "
+ "label=\"%s\" "
+ "pixtype=\"stock\" pixname=\"gtk-go-up\" "
+ "verb=\"GoUp\"/>", _("Up"));;
+ break;
+ case EPHY_TBI_STD_TOOLITEM_STOP:
+ xml_item = g_strdup_printf
+ ("<toolitem name=\"Stop\" "
+ "label=\"%s\" "
+ "pixtype=\"stock\" pixname=\"gtk-stop\" "
+ "verb=\"GoStop\"/>", _("Stop"));
+ break;
+ case EPHY_TBI_STD_TOOLITEM_RELOAD:
+ xml_item = g_strdup_printf
+ ("<toolitem name=\"Reload\" "
+ "label=\"%s\" "
+ "pixtype=\"stock\" pixname=\"gtk-refresh\" "
+ "verb=\"GoReload\"/>", _("Reload"));
+ break;
+ case EPHY_TBI_STD_TOOLITEM_HOME:
+ xml_item = g_strdup_printf
+ ("<toolitem name=\"Home\" "
+ "label=\"%s\" "
+ "pixtype=\"stock\" pixname=\"gtk-home\" "
+ "priority=\"1\" "
+ "verb=\"GoHome\"/>", _("Home"));;
+ break;
+ case EPHY_TBI_STD_TOOLITEM_GO:
+ xml_item = g_strdup_printf
+ ("<toolitem name=\"Go\" "
+ "label=\"%s\" "
+ "pixtype=\"stock\" pixname=\"gtk-jump-to\" "
+ "verb=\"GoGo\"/>", _("Go"));;
+ break;
+ case EPHY_TBI_STD_TOOLITEM_NEW:
+ xml_item = g_strdup_printf
+ ("<toolitem name=\"New\" "
+ "label=\"%s\" "
+ "pixtype=\"stock\" pixname=\"gtk-new\" "
+ "verb=\"FileNew\"/>", _("New"));;
+ break;
+
+ default:
+ g_assert_not_reached ();
+ xml_item = g_strdup ("");
+ }
+
+ bonobo_ui_component_set (ui, container_path, xml_item, NULL);
+ g_free (xml_item);
+}
+
+static void
+ephy_tbi_std_toolitem_parse_properties_impl (EphyTbItem *it, const gchar *props)
+{
+ EphyTbiStdToolitem *a = EPHY_TBI_STD_TOOLITEM (it);
+
+ /* yes, this is quite hacky, but works */
+
+ /* we have one property */
+ const gchar *item_prop;
+
+ item_prop = strstr (props, "item=");
+ if (item_prop)
+ {
+ item_prop += strlen ("item=");
+ if (!strncmp (item_prop, "back", 4))
+ {
+ ephy_tbi_std_toolitem_set_item (a, EPHY_TBI_STD_TOOLITEM_BACK);
+ }
+ else if (!strncmp (item_prop, "forward", 4))
+ {
+ ephy_tbi_std_toolitem_set_item (a, EPHY_TBI_STD_TOOLITEM_FORWARD);
+ }
+ else if (!strncmp (item_prop, "up", 2))
+ {
+ ephy_tbi_std_toolitem_set_item (a, EPHY_TBI_STD_TOOLITEM_UP);
+ }
+ else if (!strncmp (item_prop, "stop", 4))
+ {
+ ephy_tbi_std_toolitem_set_item (a, EPHY_TBI_STD_TOOLITEM_STOP);
+ }
+ else if (!strncmp (item_prop, "home", 4))
+ {
+ ephy_tbi_std_toolitem_set_item (a, EPHY_TBI_STD_TOOLITEM_HOME);
+ }
+ else if (!strncmp (item_prop, "go", 2))
+ {
+ ephy_tbi_std_toolitem_set_item (a, EPHY_TBI_STD_TOOLITEM_GO);
+ }
+ else if (!strncmp (item_prop, "reload", 6))
+ {
+ ephy_tbi_std_toolitem_set_item (a, EPHY_TBI_STD_TOOLITEM_RELOAD);
+ }
+ else if (!strncmp (item_prop, "new", 3))
+ {
+ ephy_tbi_std_toolitem_set_item (a, EPHY_TBI_STD_TOOLITEM_NEW);
+ }
+
+ }
+}
+
+void
+ephy_tbi_std_toolitem_set_item (EphyTbiStdToolitem *a, EphyTbiStdToolitemItem i)
+{
+ EphyTbiStdToolitemPrivate *p = a->priv;
+
+ g_return_if_fail (i == EPHY_TBI_STD_TOOLITEM_UP
+ || i == EPHY_TBI_STD_TOOLITEM_BACK
+ || i == EPHY_TBI_STD_TOOLITEM_FORWARD
+ || i == EPHY_TBI_STD_TOOLITEM_STOP
+ || i == EPHY_TBI_STD_TOOLITEM_RELOAD
+ || i == EPHY_TBI_STD_TOOLITEM_GO
+ || i == EPHY_TBI_STD_TOOLITEM_HOME
+ || i == EPHY_TBI_STD_TOOLITEM_NEW);
+
+ p->item = i;
+}
+
diff --git a/lib/toolbar/ephy-tbi-std-toolitem.h b/lib/toolbar/ephy-tbi-std-toolitem.h
new file mode 100644
index 000000000..67073041f
--- /dev/null
+++ b/lib/toolbar/ephy-tbi-std-toolitem.h
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+#ifndef EPHY_TBI_STD_TOOLITEM_H
+#define EPHY_TBI_STD_TOOLITEM_H
+
+#include "ephy-toolbar-item.h"
+
+G_BEGIN_DECLS
+
+/* object forward declarations */
+
+typedef struct _EphyTbiStdToolitem EphyTbiStdToolitem;
+typedef struct _EphyTbiStdToolitemClass EphyTbiStdToolitemClass;
+typedef struct _EphyTbiStdToolitemPrivate EphyTbiStdToolitemPrivate;
+
+/**
+ * TbiStdToolitem object
+ */
+
+#define EPHY_TYPE_TBI_STD_TOOLITEM (ephy_tbi_std_toolitem_get_type())
+#define EPHY_TBI_STD_TOOLITEM(object) (G_TYPE_CHECK_INSTANCE_CAST((object), \
+ EPHY_TYPE_TBI_STD_TOOLITEM,\
+ EphyTbiStdToolitem))
+#define EPHY_TBI_STD_TOOLITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \
+ EPHY_TYPE_TBI_STD_TOOLITEM,\
+ EphyTbiStdToolitemClass))
+#define EPHY_IS_TBI_STD_TOOLITEM(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), \
+ EPHY_TYPE_TBI_STD_TOOLITEM))
+#define EPHY_IS_TBI_STD_TOOLITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), \
+ EPHY_TYPE_TBI_STD_TOOLITEM))
+#define EPHY_TBI_STD_TOOLITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \
+ EPHY_TYPE_TBI_STD_TOOLITEM,\
+ EphyTbiStdToolitemClass))
+typedef enum
+{
+ EPHY_TBI_STD_TOOLITEM_BACK,
+ EPHY_TBI_STD_TOOLITEM_FORWARD,
+ EPHY_TBI_STD_TOOLITEM_UP,
+ EPHY_TBI_STD_TOOLITEM_STOP,
+ EPHY_TBI_STD_TOOLITEM_RELOAD,
+ EPHY_TBI_STD_TOOLITEM_HOME,
+ EPHY_TBI_STD_TOOLITEM_GO,
+ EPHY_TBI_STD_TOOLITEM_NEW
+} EphyTbiStdToolitemItem;
+
+
+struct _EphyTbiStdToolitemClass
+{
+ EphyTbItemClass parent_class;
+};
+
+/* Remember: fields are public read-only */
+struct _EphyTbiStdToolitem
+{
+ EphyTbItem parent_object;
+
+ EphyTbiStdToolitemPrivate *priv;
+};
+
+/* this class is abstract */
+
+GType ephy_tbi_std_toolitem_get_type (void);
+EphyTbiStdToolitem * ephy_tbi_std_toolitem_new (void);
+void ephy_tbi_std_toolitem_set_item (EphyTbiStdToolitem *sit,
+ EphyTbiStdToolitemItem it);
+
+G_END_DECLS
+
+#endif
+
diff --git a/lib/toolbar/ephy-tbi-zoom.c b/lib/toolbar/ephy-tbi-zoom.c
new file mode 100644
index 000000000..578799b24
--- /dev/null
+++ b/lib/toolbar/ephy-tbi-zoom.c
@@ -0,0 +1,304 @@
+/*
+ * 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
+
+#include <libgnome/gnome-i18n.h>
+#include <gtk/gtkspinbutton.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkstock.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkvbox.h>
+#include <string.h>
+
+#include "ephy-tbi-zoom.h"
+#include "ephy-prefs.h"
+#include "eel-gconf-extensions.h"
+#include "ephy-gobject-misc.h"
+#include "ephy-marshal.h"
+#include "ephy-bonobo-extensions.h"
+
+#define NOT_IMPLEMENTED g_warning ("not implemented: " G_STRLOC);
+//#define DEBUG_MSG(x) g_print x
+#define DEBUG_MSG(x)
+
+/**
+ * Private data
+ */
+struct _EphyTbiZoomPrivate
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ GtkWidget *hbox;
+ GtkWidget *vbox;
+ guint notification;
+};
+
+enum
+{
+ TOOLBAR_ITEM_STYLE_PROP,
+ TOOLBAR_ITEM_ORIENTATION_PROP,
+ TOOLBAR_ITEM_WANT_LABEL_PROP
+};
+
+/**
+ * Private functions, only availble from this file
+ */
+static void ephy_tbi_zoom_class_init (EphyTbiZoomClass *klass);
+static void ephy_tbi_zoom_init (EphyTbiZoom *tb);
+static void ephy_tbi_zoom_finalize_impl (GObject *o);
+static GtkWidget * ephy_tbi_zoom_get_widget_impl (EphyTbItem *i);
+static GdkPixbuf * ephy_tbi_zoom_get_icon_impl (EphyTbItem *i);
+static gchar * ephy_tbi_zoom_get_name_human_impl (EphyTbItem *i);
+static gchar * ephy_tbi_zoom_to_string_impl (EphyTbItem *i);
+static gboolean ephy_tbi_zoom_is_unique_impl (EphyTbItem *i);
+static EphyTbItem * ephy_tbi_zoom_clone_impl (EphyTbItem *i);
+static void ephy_tbi_zoom_parse_properties_impl (EphyTbItem *i, const gchar *props);
+static void ephy_tbi_zoom_add_to_bonobo_tb_impl (EphyTbItem *i,
+ BonoboUIComponent *ui,
+ const char *container_path,
+ guint index);
+static void ephy_tbi_zoom_setup_label (EphyTbiZoom *it);
+static void ephy_tbi_zoom_notification_cb (GConfClient* client,
+ guint cnxn_id,
+ GConfEntry *entry,
+ gpointer user_data);
+
+
+static gpointer ephy_tb_item_class;
+
+/**
+ * TbiZoom object
+ */
+
+MAKE_GET_TYPE (ephy_tbi_zoom, "EphyTbiZoom", EphyTbiZoom, ephy_tbi_zoom_class_init,
+ ephy_tbi_zoom_init, EPHY_TYPE_TB_ITEM);
+
+static void
+ephy_tbi_zoom_class_init (EphyTbiZoomClass *klass)
+{
+ G_OBJECT_CLASS (klass)->finalize = ephy_tbi_zoom_finalize_impl;
+
+ EPHY_TB_ITEM_CLASS (klass)->get_widget = ephy_tbi_zoom_get_widget_impl;
+ EPHY_TB_ITEM_CLASS (klass)->get_icon = ephy_tbi_zoom_get_icon_impl;
+ EPHY_TB_ITEM_CLASS (klass)->get_name_human = ephy_tbi_zoom_get_name_human_impl;
+ EPHY_TB_ITEM_CLASS (klass)->to_string = ephy_tbi_zoom_to_string_impl;
+ EPHY_TB_ITEM_CLASS (klass)->is_unique = ephy_tbi_zoom_is_unique_impl;
+ EPHY_TB_ITEM_CLASS (klass)->clone = ephy_tbi_zoom_clone_impl;
+ EPHY_TB_ITEM_CLASS (klass)->parse_properties = ephy_tbi_zoom_parse_properties_impl;
+ EPHY_TB_ITEM_CLASS (klass)->add_to_bonobo_tb = ephy_tbi_zoom_add_to_bonobo_tb_impl;
+
+ ephy_tb_item_class = g_type_class_peek_parent (klass);
+}
+
+static void
+ephy_tbi_zoom_init (EphyTbiZoom *tbi)
+{
+ EphyTbiZoomPrivate *p = g_new0 (EphyTbiZoomPrivate, 1);
+ tbi->priv = p;
+
+ p->notification = eel_gconf_notification_add (CONF_DESKTOP_TOOLBAR_STYLE,
+ ephy_tbi_zoom_notification_cb,
+ tbi);
+}
+
+EphyTbiZoom *
+ephy_tbi_zoom_new (void)
+{
+ EphyTbiZoom *ret = g_object_new (EPHY_TYPE_TBI_ZOOM, NULL);
+ return ret;
+}
+
+static void
+ephy_tbi_zoom_finalize_impl (GObject *o)
+{
+ EphyTbiZoom *it = EPHY_TBI_ZOOM (o);
+ EphyTbiZoomPrivate *p = it->priv;
+
+ if (p->widget)
+ {
+ g_object_unref (p->widget);
+ }
+
+ if (p->label)
+ {
+ g_object_unref (p->label);
+ }
+
+ if (p->vbox)
+ {
+ g_object_unref (p->vbox);
+ }
+
+ if (p->hbox)
+ {
+ g_object_unref (p->hbox);
+ }
+
+ if (p->notification)
+ {
+ eel_gconf_notification_remove (p->notification);
+ }
+
+ g_free (p);
+
+ DEBUG_MSG (("EphyTbiZoom finalized\n"));
+
+ G_OBJECT_CLASS (ephy_tb_item_class)->finalize (o);
+}
+
+static GtkWidget *
+ephy_tbi_zoom_get_widget_impl (EphyTbItem *i)
+{
+ EphyTbiZoom *iz = EPHY_TBI_ZOOM (i);
+ EphyTbiZoomPrivate *p = iz->priv;
+
+ if (!p->widget)
+ {
+ p->widget = gtk_spin_button_new_with_range (1, 999, 10);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (p->widget), 100);
+ g_object_ref (p->widget);
+ gtk_object_sink (GTK_OBJECT (p->widget));
+ p->label = gtk_label_new (_("Zoom"));
+ g_object_ref (p->label);
+ gtk_object_sink (GTK_OBJECT (p->label));
+ p->vbox = gtk_vbox_new (FALSE, 0);
+ g_object_ref (p->vbox);
+ gtk_object_sink (GTK_OBJECT (p->vbox));
+ p->hbox = gtk_hbox_new (FALSE, 0);
+ g_object_ref (p->hbox);
+ gtk_object_sink (GTK_OBJECT (p->hbox));
+
+ gtk_box_pack_start_defaults (GTK_BOX (p->hbox), p->vbox);
+ gtk_box_pack_start_defaults (GTK_BOX (p->vbox), p->widget);
+ gtk_widget_show (p->vbox);
+ gtk_widget_show (p->hbox);
+ }
+
+ return p->widget;
+}
+
+static GdkPixbuf *
+ephy_tbi_zoom_get_icon_impl (EphyTbItem *i)
+{
+ static GdkPixbuf *pb = NULL;
+ if (!pb)
+ {
+ /* what's the easier way? */
+ GtkWidget *b = gtk_spin_button_new_with_range (0, 1, 0.5);
+ pb = gtk_widget_render_icon (b,
+ GTK_STOCK_ZOOM_IN,
+ GTK_ICON_SIZE_SMALL_TOOLBAR,
+ NULL);
+ gtk_widget_destroy (b);
+ }
+ return g_object_ref (pb);
+}
+
+static gchar *
+ephy_tbi_zoom_get_name_human_impl (EphyTbItem *i)
+{
+ return g_strdup (_("Zoom"));
+}
+
+static gchar *
+ephy_tbi_zoom_to_string_impl (EphyTbItem *i)
+{
+ /* if it had any properties, the string should include them */
+ return g_strdup_printf ("%s=zoom", i->id);
+}
+
+static gboolean
+ephy_tbi_zoom_is_unique_impl (EphyTbItem *i)
+{
+ return TRUE;
+}
+
+static EphyTbItem *
+ephy_tbi_zoom_clone_impl (EphyTbItem *i)
+{
+ EphyTbItem *ret = EPHY_TB_ITEM (ephy_tbi_zoom_new ());
+
+ ephy_tb_item_set_id (ret, i->id);
+
+ /* should copy properties too, if any */
+ /* the zoom value is not copied, not sure if it should... */
+
+ return ret;
+}
+
+static void
+ephy_tbi_zoom_add_to_bonobo_tb_impl (EphyTbItem *i, BonoboUIComponent *ui,
+ const char *container_path, guint index)
+{
+ GtkWidget *w = ephy_tb_item_get_widget (i);
+ EphyTbiZoomPrivate *p = EPHY_TBI_ZOOM (i)->priv;
+ gtk_widget_show (w);
+ ephy_bonobo_add_numbered_control (ui, p->hbox, index, container_path);
+ ephy_tbi_zoom_setup_label (EPHY_TBI_ZOOM (i));
+}
+
+static void
+ephy_tbi_zoom_parse_properties_impl (EphyTbItem *it, const gchar *props)
+{
+ /* we have no properties */
+}
+
+static void
+ephy_tbi_zoom_setup_label (EphyTbiZoom *it)
+{
+ EphyTbiZoomPrivate *p = it->priv;
+ gchar *style = eel_gconf_get_string (CONF_DESKTOP_TOOLBAR_STYLE);
+ ephy_tb_item_get_widget (EPHY_TB_ITEM (it));
+
+ g_object_ref (p->label);
+ if (p->label->parent)
+ {
+ gtk_container_remove (GTK_CONTAINER (p->label->parent), p->label);
+ }
+
+ if (!strcmp (style, "both_horiz") || !strcmp (style, "text"))
+ {
+ gtk_widget_show (p->label);
+ gtk_box_pack_start_defaults (GTK_BOX (p->hbox), p->label);
+ }
+ else if (!strcmp (style, "both"))
+ {
+ gtk_widget_show (p->label);
+ gtk_box_pack_start_defaults (GTK_BOX (p->vbox), p->label);
+ }
+ else
+ {
+ gtk_widget_hide (p->label);
+ }
+
+ g_free (style);
+ g_object_unref (p->label);
+}
+
+static void
+ephy_tbi_zoom_notification_cb (GConfClient* client,
+ guint cnxn_id,
+ GConfEntry *entry,
+ gpointer user_data)
+{
+ ephy_tbi_zoom_setup_label (user_data);
+}
+
diff --git a/lib/toolbar/ephy-tbi-zoom.h b/lib/toolbar/ephy-tbi-zoom.h
new file mode 100644
index 000000000..03f0ed61e
--- /dev/null
+++ b/lib/toolbar/ephy-tbi-zoom.h
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+#ifndef EPHY_TBI_ZOOM_H
+#define EPHY_TBI_ZOOM_H
+
+#include "ephy-toolbar-item.h"
+
+G_BEGIN_DECLS
+
+/* object forward declarations */
+
+typedef struct _EphyTbiZoom EphyTbiZoom;
+typedef struct _EphyTbiZoomClass EphyTbiZoomClass;
+typedef struct _EphyTbiZoomPrivate EphyTbiZoomPrivate;
+
+/**
+ * TbiZoom object
+ */
+
+#define EPHY_TYPE_TBI_ZOOM (ephy_tbi_zoom_get_type())
+#define EPHY_TBI_ZOOM(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EPHY_TYPE_TBI_ZOOM,\
+ EphyTbiZoom))
+#define EPHY_TBI_ZOOM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EPHY_TYPE_TBI_ZOOM,\
+ EphyTbiZoomClass))
+#define EPHY_IS_TBI_ZOOM(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EPHY_TYPE_TBI_ZOOM))
+#define EPHY_IS_TBI_ZOOM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EPHY_TYPE_TBI_ZOOM))
+#define EPHY_TBI_ZOOM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_TBI_ZOOM,\
+ EphyTbiZoomClass))
+
+struct _EphyTbiZoomClass
+{
+ EphyTbItemClass parent_class;
+};
+
+/* Remember: fields are public read-only */
+struct _EphyTbiZoom
+{
+ EphyTbItem parent_object;
+
+ EphyTbiZoomPrivate *priv;
+};
+
+/* this class is abstract */
+
+GType ephy_tbi_zoom_get_type (void);
+EphyTbiZoom * ephy_tbi_zoom_new (void);
+
+G_END_DECLS
+
+#endif
diff --git a/lib/toolbar/ephy-toolbar-bonobo-view.c b/lib/toolbar/ephy-toolbar-bonobo-view.c
new file mode 100644
index 000000000..a22356e1e
--- /dev/null
+++ b/lib/toolbar/ephy-toolbar-bonobo-view.c
@@ -0,0 +1,193 @@
+/*
+ * 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
+
+#include <libgnome/gnome-i18n.h>
+
+#include "ephy-gobject-misc.h"
+#include "ephy-marshal.h"
+#include "ephy-toolbar-bonobo-view.h"
+#include "ephy-bonobo-extensions.h"
+
+#define NOT_IMPLEMENTED g_warning ("not implemented: " G_STRLOC);
+//#define DEBUG_MSG(x) g_print x
+#define DEBUG_MSG(x)
+
+/**
+ * Private data
+ */
+struct _EphyTbBonoboViewPrivate
+{
+ EphyToolbar *tb;
+ BonoboUIComponent *ui;
+ gchar *path;
+};
+
+/**
+ * Private functions, only availble from this file
+ */
+static void ephy_tb_bonobo_view_class_init (EphyTbBonoboViewClass *klass);
+static void ephy_tb_bonobo_view_init (EphyTbBonoboView *tb);
+static void ephy_tb_bonobo_view_finalize_impl (GObject *o);
+static void ephy_tb_bonobo_view_rebuild (EphyTbBonoboView *tbv);
+static void ephy_tb_bonobo_view_tb_changed (EphyToolbar *tb, EphyTbBonoboView *tbv);
+
+static gpointer g_object_class;
+
+/**
+ * TbBonoboView object
+ */
+
+MAKE_GET_TYPE (ephy_tb_bonobo_view, "EphyTbBonoboView", EphyTbBonoboView, ephy_tb_bonobo_view_class_init,
+ ephy_tb_bonobo_view_init, G_TYPE_OBJECT);
+
+static void
+ephy_tb_bonobo_view_class_init (EphyTbBonoboViewClass *klass)
+{
+ G_OBJECT_CLASS (klass)->finalize = ephy_tb_bonobo_view_finalize_impl;
+
+ g_object_class = g_type_class_peek_parent (klass);
+}
+
+static void
+ephy_tb_bonobo_view_init (EphyTbBonoboView *tb)
+{
+ EphyTbBonoboViewPrivate *p = g_new0 (EphyTbBonoboViewPrivate, 1);
+ tb->priv = p;
+}
+
+static void
+ephy_tb_bonobo_view_finalize_impl (GObject *o)
+{
+ EphyTbBonoboView *tbv = EPHY_TB_BONOBO_VIEW (o);
+ EphyTbBonoboViewPrivate *p = tbv->priv;
+
+ if (p->tb)
+ {
+ g_signal_handlers_disconnect_matched (p->tb, G_SIGNAL_MATCH_DATA, 0, 0,
+ NULL, NULL, tbv);
+ g_object_unref (p->tb);
+ }
+ if (p->ui)
+ {
+ g_object_unref (p->ui);
+ }
+ if (p->path)
+ {
+ g_free (p->path);
+ }
+
+ g_free (p);
+
+ DEBUG_MSG (("EphyTbBonoboView finalized\n"));
+
+ G_OBJECT_CLASS (g_object_class)->finalize (o);
+}
+
+EphyTbBonoboView *
+ephy_tb_bonobo_view_new (void)
+{
+ EphyTbBonoboView *ret = g_object_new (EPHY_TYPE_TB_BONOBO_VIEW, NULL);
+ return ret;
+}
+
+void
+ephy_tb_bonobo_view_set_toolbar (EphyTbBonoboView *tbv, EphyToolbar *tb)
+{
+ EphyTbBonoboViewPrivate *p = tbv->priv;
+
+ if (p->tb)
+ {
+ g_signal_handlers_disconnect_matched (p->tb, G_SIGNAL_MATCH_DATA, 0, 0,
+ NULL, NULL, tbv);
+ g_object_unref (p->tb);
+ }
+
+ p->tb = g_object_ref (tb);
+ g_signal_connect (p->tb, "changed", G_CALLBACK (ephy_tb_bonobo_view_tb_changed), tbv);
+
+ if (p->ui)
+ {
+ ephy_tb_bonobo_view_rebuild (tbv);
+ }
+}
+
+static void
+ephy_tb_bonobo_view_tb_changed (EphyToolbar *tb, EphyTbBonoboView *tbv)
+{
+ EphyTbBonoboViewPrivate *p = tbv->priv;
+ if (p->ui)
+ {
+ ephy_tb_bonobo_view_rebuild (tbv);
+ }
+}
+
+void
+ephy_tb_bonobo_view_set_path (EphyTbBonoboView *tbv,
+ BonoboUIComponent *ui,
+ const gchar *path)
+{
+ EphyTbBonoboViewPrivate *p = tbv->priv;
+
+ if (p->ui)
+ {
+ g_object_unref (p->ui);
+ }
+
+ if (p->path)
+ {
+ g_free (p->path);
+ }
+
+ p->ui = g_object_ref (ui);
+ p->path = g_strdup (path);
+
+ if (p->tb)
+ {
+ ephy_tb_bonobo_view_rebuild (tbv);
+ }
+}
+
+static void
+ephy_tb_bonobo_view_rebuild (EphyTbBonoboView *tbv)
+{
+ EphyTbBonoboViewPrivate *p = tbv->priv;
+ GSList *items;
+ GSList *li;
+ uint index = 0;
+
+ g_return_if_fail (EPHY_IS_TOOLBAR (p->tb));
+ g_return_if_fail (BONOBO_IS_UI_COMPONENT (p->ui));
+ g_return_if_fail (p->path);
+
+ DEBUG_MSG (("Rebuilding EphyTbBonoboView\n"));
+
+ ephy_bonobo_clear_path (p->ui, p->path);
+
+ items = (GSList *) ephy_toolbar_get_item_list (p->tb);
+ for (li = items; li; li = li->next)
+ {
+ ephy_tb_item_add_to_bonobo_tb (li->data, p->ui, p->path, index++);
+ }
+
+ DEBUG_MSG (("Rebuilt EphyTbBonoboView\n"));
+}
+
diff --git a/lib/toolbar/ephy-toolbar-bonobo-view.h b/lib/toolbar/ephy-toolbar-bonobo-view.h
new file mode 100644
index 000000000..a914fc201
--- /dev/null
+++ b/lib/toolbar/ephy-toolbar-bonobo-view.h
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+#ifndef EPHY_TOOLBAR_BONOBO_VIEW_H
+#define EPHY_TOOLBAR_BONOBO_VIEW_H
+
+#include <glib-object.h>
+
+#include <bonobo/bonobo-ui-component.h>
+
+#include "ephy-toolbar.h"
+
+G_BEGIN_DECLS
+
+/* object forward declarations */
+
+typedef struct _EphyTbBonoboView EphyTbBonoboView;
+typedef struct _EphyTbBonoboViewClass EphyTbBonoboViewClass;
+typedef struct _EphyTbBonoboViewPrivate EphyTbBonoboViewPrivate;
+
+/**
+ * TbBonoboView object
+ */
+
+#define EPHY_TYPE_TB_BONOBO_VIEW (ephy_tb_bonobo_view_get_type())
+#define EPHY_TB_BONOBO_VIEW(object) (G_TYPE_CHECK_INSTANCE_CAST((object), \
+ EPHY_TYPE_TB_BONOBO_VIEW,\
+ EphyTbBonoboView))
+#define EPHY_TB_BONOBO_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EPHY_TYPE_TB_BONOBO_VIEW,\
+ EphyTbBonoboViewClass))
+#define EPHY_IS_TB_BONOBO_VIEW(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), \
+ EPHY_TYPE_TB_BONOBO_VIEW))
+#define EPHY_IS_TB_BONOBO_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EPHY_TYPE_TB_BONOBO_VIEW))
+#define EPHY_TB_BONOBO_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_TB_BONOBO_VIEW,\
+ EphyTbBonoboViewClass))
+
+struct _EphyTbBonoboViewClass
+{
+ GObjectClass parent_class;
+};
+
+/* Remember: fields are public read-only */
+struct _EphyTbBonoboView
+{
+ GObject parent_object;
+
+ EphyTbBonoboViewPrivate *priv;
+};
+
+/* this class is abstract */
+
+GType ephy_tb_bonobo_view_get_type (void);
+EphyTbBonoboView * ephy_tb_bonobo_view_new (void);
+void ephy_tb_bonobo_view_set_toolbar (EphyTbBonoboView *tbv, EphyToolbar *tb);
+void ephy_tb_bonobo_view_set_path (EphyTbBonoboView *tbv,
+ BonoboUIComponent *ui,
+ const gchar *path);
+
+#endif
+
diff --git a/lib/toolbar/ephy-toolbar-editor.c b/lib/toolbar/ephy-toolbar-editor.c
new file mode 100644
index 000000000..e44767bad
--- /dev/null
+++ b/lib/toolbar/ephy-toolbar-editor.c
@@ -0,0 +1,634 @@
+/*
+ * 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
+
+#include <libgnome/gnome-i18n.h>
+
+#include "ephy-gobject-misc.h"
+#include "ephy-marshal.h"
+#include "ephy-toolbar-editor.h"
+#include "ephy-toolbar-tree-model.h"
+#include "ephy-glade.h"
+
+#define NOT_IMPLEMENTED g_warning ("not implemented: " G_STRLOC);
+//#define DEBUG_MSG(x) g_print x
+#define DEBUG_MSG(x)
+
+/**
+ * Private data
+ */
+struct _EphyTbEditorPrivate
+{
+ EphyToolbar *tb;
+ EphyToolbar *available;
+
+ gchar *tb_undo_string;
+ gchar *available_undo_string;
+
+ gboolean in_toolbar_changed;
+
+ GtkWidget *window;
+ GtkWidget *available_view;
+ GtkWidget *current_view;
+ GtkWidget *close_button;
+ GtkWidget *undo_button;
+ GtkWidget *revert_button;
+ GtkWidget *up_button;
+ GtkWidget *down_button;
+ GtkWidget *left_button;
+ GtkWidget *right_button;
+};
+
+/**
+ * Private functions, only available from this file
+ */
+static void ephy_tb_editor_class_init (EphyTbEditorClass *klass);
+static void ephy_tb_editor_init (EphyTbEditor *tbe);
+static void ephy_tb_editor_finalize_impl (GObject *o);
+static void ephy_tb_editor_init_widgets (EphyTbEditor *tbe);
+static void ephy_tb_editor_set_treeview_toolbar (EphyTbEditor *tbe,
+ GtkTreeView *tv, EphyToolbar *tb);
+static void ephy_tb_editor_setup_treeview (EphyTbEditor *tbe, GtkTreeView *tv);
+static EphyTbItem * ephy_tb_editor_get_selected (EphyTbEditor *tbe, GtkTreeView *tv);
+static gint ephy_tb_editor_get_selected_index (EphyTbEditor *tbe, GtkTreeView *tv);
+static void ephy_tb_editor_select_index (EphyTbEditor *tbe, GtkTreeView *tv,
+ gint index);
+static void ephy_tb_editor_remove_used_items (EphyTbEditor *tbe);
+
+static void ephy_tb_editor_undo_clicked_cb (GtkWidget *b, EphyTbEditor *tbe);
+static void ephy_tb_editor_close_clicked_cb (GtkWidget *b, EphyTbEditor *tbe);
+static void ephy_tb_editor_up_clicked_cb (GtkWidget *b, EphyTbEditor *tbe);
+static void ephy_tb_editor_down_clicked_cb (GtkWidget *b, EphyTbEditor *tbe);
+static void ephy_tb_editor_left_clicked_cb (GtkWidget *b, EphyTbEditor *tbe);
+static void ephy_tb_editor_right_clicked_cb (GtkWidget *b, EphyTbEditor *tbe);
+static void ephy_tb_editor_toolbar_changed_cb (EphyToolbar *tb, EphyTbEditor *tbe);
+static gboolean ephy_tb_editor_treeview_button_press_event_cb (GtkWidget *widget,
+ GdkEventButton *event,
+ EphyTbEditor *tbe);
+
+
+static gpointer g_object_class;
+
+/* treeview dnd */
+enum
+{
+ TARGET_GTK_TREE_MODEL_ROW
+};
+static GtkTargetEntry tree_view_row_targets[] = {
+ { "GTK_TREE_MODEL_ROW", GTK_TARGET_SAME_APP, TARGET_GTK_TREE_MODEL_ROW }
+};
+
+/**
+ * TbEditor object
+ */
+
+MAKE_GET_TYPE (ephy_tb_editor, "EphyTbEditor", EphyTbEditor, ephy_tb_editor_class_init,
+ ephy_tb_editor_init, G_TYPE_OBJECT);
+
+static void
+ephy_tb_editor_class_init (EphyTbEditorClass *klass)
+{
+ G_OBJECT_CLASS (klass)->finalize = ephy_tb_editor_finalize_impl;
+
+ g_object_class = g_type_class_peek_parent (klass);
+}
+
+static void
+ephy_tb_editor_init (EphyTbEditor *tb)
+{
+ EphyTbEditorPrivate *p = g_new0 (EphyTbEditorPrivate, 1);
+ tb->priv = p;
+
+ ephy_tb_editor_init_widgets (tb);
+}
+
+static void
+update_arrows_sensitivity (EphyTbEditor *tbe)
+{
+ GtkTreeSelection *selection;
+ gboolean current_sel;
+ gboolean avail_sel;
+ gboolean first = FALSE;
+ gboolean last = FALSE;
+ GtkTreeModel *tm;
+ GtkTreeIter iter;
+ GtkTreePath *path;
+
+ selection = gtk_tree_view_get_selection
+ (GTK_TREE_VIEW (tbe->priv->current_view));
+ current_sel = gtk_tree_selection_get_selected (selection, &tm, &iter);
+ if (current_sel)
+ {
+ path = gtk_tree_model_get_path (tm, &iter);
+ first = !gtk_tree_path_prev (path);
+ last = !gtk_tree_model_iter_next (tm, &iter);
+ }
+
+ selection = gtk_tree_view_get_selection
+ (GTK_TREE_VIEW (tbe->priv->available_view));
+ avail_sel = gtk_tree_selection_get_selected (selection, &tm, &iter);
+
+ gtk_widget_set_sensitive (tbe->priv->right_button,
+ avail_sel);
+ gtk_widget_set_sensitive (tbe->priv->left_button,
+ current_sel);
+ gtk_widget_set_sensitive (tbe->priv->up_button,
+ current_sel && !first);
+ gtk_widget_set_sensitive (tbe->priv->down_button,
+ current_sel && !last);
+}
+
+static void
+ephy_tb_editor_treeview_selection_changed_cb (GtkTreeSelection *selection,
+ EphyTbEditor *tbe)
+{
+ update_arrows_sensitivity (tbe);
+}
+
+static void
+ephy_tb_editor_init_widgets (EphyTbEditor *tbe)
+{
+ EphyTbEditorPrivate *p = tbe->priv;
+
+ GladeXML *gxml = ephy_glade_widget_new ("toolbar-editor.glade", "toolbar-editor-dialog",
+ NULL, tbe);
+ p->window = glade_xml_get_widget (gxml, "toolbar-editor-dialog");
+ p->available_view = glade_xml_get_widget (gxml, "toolbar-editor-available-view");
+ p->current_view = glade_xml_get_widget (gxml, "toolbar-editor-current-view");
+ p->close_button = glade_xml_get_widget (gxml, "toolbar-editor-close-button");
+ p->undo_button = glade_xml_get_widget (gxml, "toolbar-editor-undo-button");
+ p->revert_button = glade_xml_get_widget (gxml, "toolbar-editor-revert-button");
+ p->up_button = glade_xml_get_widget (gxml, "toolbar-editor-up-button");
+ p->down_button = glade_xml_get_widget (gxml, "toolbar-editor-down-button");
+ p->left_button = glade_xml_get_widget (gxml, "toolbar-editor-left-button");
+ p->right_button = glade_xml_get_widget (gxml, "toolbar-editor-right-button");
+ g_object_unref (gxml);
+
+ g_signal_connect_swapped (p->window, "delete_event", G_CALLBACK (g_object_unref), tbe);
+ g_signal_connect (p->undo_button, "clicked", G_CALLBACK (ephy_tb_editor_undo_clicked_cb), tbe);
+ g_signal_connect (p->close_button, "clicked", G_CALLBACK (ephy_tb_editor_close_clicked_cb), tbe);
+ g_signal_connect (p->up_button, "clicked", G_CALLBACK (ephy_tb_editor_up_clicked_cb), tbe);
+ g_signal_connect (p->down_button, "clicked", G_CALLBACK (ephy_tb_editor_down_clicked_cb), tbe);
+ g_signal_connect (p->left_button, "clicked", G_CALLBACK (ephy_tb_editor_left_clicked_cb), tbe);
+ g_signal_connect (p->right_button, "clicked", G_CALLBACK (ephy_tb_editor_right_clicked_cb), tbe);
+
+ ephy_tb_editor_setup_treeview (tbe, GTK_TREE_VIEW (p->current_view));
+ ephy_tb_editor_setup_treeview (tbe, GTK_TREE_VIEW (p->available_view));
+}
+
+static void
+ephy_tb_editor_undo_clicked_cb (GtkWidget *b, EphyTbEditor *tbe)
+{
+ EphyTbEditorPrivate *p = tbe->priv;
+ if (p->available_undo_string && p->available)
+ {
+ ephy_toolbar_parse (p->available, p->available_undo_string);
+ }
+
+ if (p->tb_undo_string && p->tb)
+ {
+ ephy_toolbar_parse (p->tb, p->tb_undo_string);
+ }
+}
+
+static void
+ephy_tb_editor_close_clicked_cb (GtkWidget *b, EphyTbEditor *tbe)
+{
+ gtk_widget_hide (tbe->priv->window);
+ g_object_unref (tbe);
+}
+
+static void
+ephy_tb_editor_up_clicked_cb (GtkWidget *b, EphyTbEditor *tbe)
+{
+ EphyTbEditorPrivate *p = tbe->priv;
+ EphyTbItem *item = ephy_tb_editor_get_selected (tbe, GTK_TREE_VIEW (p->current_view));
+ gint index = ephy_tb_editor_get_selected_index (tbe, GTK_TREE_VIEW (p->current_view));
+ if (item && index > 0)
+ {
+ g_object_ref (item);
+ ephy_toolbar_remove_item (p->tb, item);
+ ephy_toolbar_add_item (p->tb, item, index - 1);
+ ephy_tb_editor_select_index (tbe, GTK_TREE_VIEW (p->current_view), index - 1);
+ g_object_unref (item);
+ }
+}
+
+static void
+ephy_tb_editor_down_clicked_cb (GtkWidget *b, EphyTbEditor *tbe)
+{
+ EphyTbEditorPrivate *p = tbe->priv;
+ EphyTbItem *item = ephy_tb_editor_get_selected (tbe, GTK_TREE_VIEW (p->current_view));
+ gint index = ephy_tb_editor_get_selected_index (tbe, GTK_TREE_VIEW (p->current_view));
+ if (item)
+ {
+ g_object_ref (item);
+ ephy_toolbar_remove_item (p->tb, item);
+ ephy_toolbar_add_item (p->tb, item, index + 1);
+ ephy_tb_editor_select_index (tbe, GTK_TREE_VIEW (p->current_view), index + 1);
+ g_object_unref (item);
+ }
+}
+
+static void
+ephy_tb_editor_left_clicked_cb (GtkWidget *b, EphyTbEditor *tbe)
+{
+ EphyTbEditorPrivate *p = tbe->priv;
+ EphyTbItem *item = ephy_tb_editor_get_selected (tbe, GTK_TREE_VIEW (p->current_view));
+ /* probably is better not allowing reordering the available_view */
+ gint index = ephy_tb_editor_get_selected_index (tbe, GTK_TREE_VIEW (p->available_view));
+ if (item)
+ {
+ g_object_ref (item);
+ ephy_toolbar_remove_item (p->tb, item);
+ if (ephy_tb_item_is_unique (item))
+ {
+ ephy_toolbar_add_item (p->available, item, index);
+ }
+ g_object_unref (item);
+ }
+}
+
+static void
+ephy_tb_editor_right_clicked_cb (GtkWidget *b, EphyTbEditor *tbe)
+{
+ EphyTbEditorPrivate *p = tbe->priv;
+ EphyTbItem *item = ephy_tb_editor_get_selected (tbe, GTK_TREE_VIEW (p->available_view));
+ gint index = ephy_tb_editor_get_selected_index (tbe, GTK_TREE_VIEW (p->current_view));
+ if (item)
+ {
+ if (ephy_tb_item_is_unique (item))
+ {
+ g_object_ref (item);
+ ephy_toolbar_remove_item (p->available, item);
+ }
+ else
+ {
+ item = ephy_tb_item_clone (item);
+ }
+ ephy_toolbar_add_item (p->tb, item, index);
+ ephy_tb_editor_select_index (tbe, GTK_TREE_VIEW (p->current_view), index);
+ g_object_unref (item);
+ }
+}
+
+static EphyTbItem *
+ephy_tb_editor_get_selected (EphyTbEditor *tbe, GtkTreeView *tv)
+{
+ GtkTreeSelection *sel = gtk_tree_view_get_selection (tv);
+ GtkTreeModel *tm;
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected (sel, &tm, &iter))
+ {
+ EphyTbItem *ret;
+ g_return_val_if_fail (EPHY_IS_TB_TREE_MODEL (tm), NULL);
+ ret = ephy_tb_tree_model_item_from_iter (EPHY_TB_TREE_MODEL (tm), &iter);
+ return ret;
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+static gint
+ephy_tb_editor_get_selected_index (EphyTbEditor *tbe, GtkTreeView *tv)
+{
+ GtkTreeSelection *sel = gtk_tree_view_get_selection (tv);
+ GtkTreeModel *tm;
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected (sel, &tm, &iter))
+ {
+ GtkTreePath *p = gtk_tree_model_get_path (tm, &iter);
+ if (p)
+ {
+ gint ret = gtk_tree_path_get_depth (p) > 0 ? gtk_tree_path_get_indices (p)[0] : -1;
+ gtk_tree_path_free (p);
+ return ret;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+static void
+ephy_tb_editor_select_index (EphyTbEditor *tbe, GtkTreeView *tv, gint index)
+{
+ GtkTreeSelection *sel = gtk_tree_view_get_selection (tv);
+ GtkTreePath *p = gtk_tree_path_new ();
+ GtkTreeModel *tm = gtk_tree_view_get_model (tv);
+ gint max = gtk_tree_model_iter_n_children (tm, NULL);
+
+ if (index < 0 || index >= max)
+ {
+ index = max - 1;
+ }
+
+ gtk_tree_path_append_index (p, index);
+ gtk_tree_selection_select_path (sel, p);
+ gtk_tree_path_free (p);
+}
+
+static void
+ephy_tb_editor_finalize_impl (GObject *o)
+{
+ EphyTbEditor *tbe = EPHY_TB_EDITOR (o);
+ EphyTbEditorPrivate *p = tbe->priv;
+
+ if (p->tb)
+ {
+ g_signal_handlers_disconnect_matched (p->tb, G_SIGNAL_MATCH_DATA, 0, 0,
+ NULL, NULL, tbe);
+
+ g_object_unref (p->tb);
+ }
+ if (p->available)
+ {
+ g_signal_handlers_disconnect_matched (p->available, G_SIGNAL_MATCH_DATA, 0, 0,
+ NULL, NULL, tbe);
+ g_object_unref (p->available);
+ }
+
+ if (p->window)
+ {
+ gtk_widget_destroy (p->window);
+ }
+
+ g_free (p->tb_undo_string);
+ g_free (p->available_undo_string);
+
+ g_free (p);
+
+ DEBUG_MSG (("EphyTbEditor finalized\n"));
+
+ G_OBJECT_CLASS (g_object_class)->finalize (o);
+}
+
+EphyTbEditor *
+ephy_tb_editor_new (void)
+{
+ EphyTbEditor *ret = g_object_new (EPHY_TYPE_TB_EDITOR, NULL);
+ return ret;
+}
+
+void
+ephy_tb_editor_set_toolbar (EphyTbEditor *tbe, EphyToolbar *tb)
+{
+ EphyTbEditorPrivate *p = tbe->priv;
+
+ if (p->tb)
+ {
+ g_signal_handlers_disconnect_matched (p->tb, G_SIGNAL_MATCH_DATA, 0, 0,
+ NULL, NULL, tbe);
+ g_object_unref (p->tb);
+ }
+ p->tb = g_object_ref (tb);
+
+ g_free (p->tb_undo_string);
+ p->tb_undo_string = ephy_toolbar_to_string (p->tb);
+
+ if (p->available)
+ {
+ ephy_tb_editor_remove_used_items (tbe);
+ }
+
+ g_signal_connect (p->tb, "changed", G_CALLBACK (ephy_tb_editor_toolbar_changed_cb), tbe);
+
+ ephy_tb_editor_set_treeview_toolbar (tbe, GTK_TREE_VIEW (p->current_view), p->tb);
+
+ gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (p->current_view),
+ GDK_BUTTON1_MASK,
+ tree_view_row_targets,
+ G_N_ELEMENTS (tree_view_row_targets),
+ GDK_ACTION_MOVE);
+ gtk_tree_view_enable_model_drag_dest (GTK_TREE_VIEW (p->current_view),
+ tree_view_row_targets,
+ G_N_ELEMENTS (tree_view_row_targets),
+ GDK_ACTION_COPY);
+}
+
+void
+ephy_tb_editor_set_available (EphyTbEditor *tbe, EphyToolbar *tb)
+{
+ EphyTbEditorPrivate *p = tbe->priv;
+
+ if (p->available)
+ {
+ g_signal_handlers_disconnect_matched (p->available, G_SIGNAL_MATCH_DATA, 0, 0,
+ NULL, NULL, tbe);
+ g_object_unref (p->available);
+ }
+ p->available = g_object_ref (tb);
+
+ g_free (p->available_undo_string);
+ p->available_undo_string = ephy_toolbar_to_string (p->available);
+
+ ephy_toolbar_set_fixed_order (p->available, TRUE);
+
+ if (p->tb)
+ {
+ ephy_tb_editor_remove_used_items (tbe);
+ }
+
+ ephy_tb_editor_set_treeview_toolbar (tbe, GTK_TREE_VIEW (p->available_view), p->available);
+
+ gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (p->available_view),
+ GDK_BUTTON1_MASK,
+ tree_view_row_targets,
+ G_N_ELEMENTS (tree_view_row_targets),
+ GDK_ACTION_COPY);
+ gtk_tree_view_enable_model_drag_dest (GTK_TREE_VIEW (p->available_view),
+ tree_view_row_targets,
+ G_N_ELEMENTS (tree_view_row_targets),
+ GDK_ACTION_MOVE);
+}
+
+void
+ephy_tb_editor_set_parent (EphyTbEditor *tbe, GtkWidget *parent)
+{
+ gtk_window_set_transient_for (GTK_WINDOW (tbe->priv->window),
+ GTK_WINDOW (parent));
+}
+
+void
+ephy_tb_editor_show (EphyTbEditor *tbe)
+{
+ gtk_window_present (GTK_WINDOW (tbe->priv->window));
+}
+
+static void
+ephy_tb_editor_set_treeview_toolbar (EphyTbEditor *tbe, GtkTreeView *tv, EphyToolbar *tb)
+{
+ EphyTbTreeModel *tm = ephy_tb_tree_model_new ();
+ ephy_tb_tree_model_set_toolbar (tm, tb);
+ gtk_tree_view_set_model (tv, GTK_TREE_MODEL (tm));
+ g_object_unref (tm);
+}
+
+static void
+ephy_tb_editor_setup_treeview (EphyTbEditor *tbe, GtkTreeView *tv)
+{
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+ GtkTreeSelection *selection;
+
+ selection = gtk_tree_view_get_selection (tv);
+ column = gtk_tree_view_column_new ();
+ renderer = gtk_cell_renderer_pixbuf_new ();
+
+ gtk_tree_view_column_pack_start (column, renderer, FALSE);
+ gtk_tree_view_column_set_attributes (column, renderer,
+ "pixbuf", EPHY_TB_TREE_MODEL_COL_ICON,
+ NULL);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
+ gtk_tree_view_column_set_attributes (column, renderer,
+ "text", EPHY_TB_TREE_MODEL_COL_NAME,
+ NULL);
+ gtk_tree_view_column_set_title (column, "Name");
+ gtk_tree_view_column_set_resizable (column, TRUE);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (tv), column);
+
+ g_signal_connect (tv, "button-press-event",
+ G_CALLBACK (ephy_tb_editor_treeview_button_press_event_cb), tbe);
+ g_signal_connect (selection, "changed",
+ G_CALLBACK (ephy_tb_editor_treeview_selection_changed_cb), tbe);
+}
+
+EphyToolbar *
+ephy_tb_editor_get_toolbar (EphyTbEditor *tbe)
+{
+ EphyTbEditorPrivate *p;
+
+ g_return_val_if_fail (EPHY_IS_TB_EDITOR (tbe), NULL);
+
+ p = tbe->priv;
+
+ return p->tb;
+}
+
+EphyToolbar *
+ephy_tb_editor_get_available (EphyTbEditor *tbe)
+{
+ EphyTbEditorPrivate *p;
+
+ g_return_val_if_fail (EPHY_IS_TB_EDITOR (tbe), NULL);
+
+ p = tbe->priv;
+
+ return p->available;
+}
+
+
+static void
+ephy_tb_editor_remove_used_items (EphyTbEditor *tbe)
+{
+ EphyTbEditorPrivate *p = tbe->priv;
+ const GSList *current_items;
+ const GSList *li;
+
+ g_return_if_fail (EPHY_IS_TOOLBAR (p->tb));
+ g_return_if_fail (EPHY_IS_TOOLBAR (p->available));
+
+ current_items = ephy_toolbar_get_item_list (p->tb);
+ for (li = current_items; li; li = li->next)
+ {
+ EphyTbItem *i = li->data;
+ if (ephy_tb_item_is_unique (i))
+ {
+ EphyTbItem *j = ephy_toolbar_get_item_by_id (p->available, i->id);
+ if (j)
+ {
+ ephy_toolbar_remove_item (p->available, j);
+ }
+ }
+ }
+}
+
+static void
+ephy_tb_editor_toolbar_changed_cb (EphyToolbar *tb, EphyTbEditor *tbe)
+{
+ EphyTbEditorPrivate *p = tbe->priv;
+
+ if (p->in_toolbar_changed)
+ {
+ return;
+ }
+
+ if (p->tb && p->available)
+ {
+ p->in_toolbar_changed = TRUE;
+ ephy_tb_editor_remove_used_items (tbe);
+ p->in_toolbar_changed = FALSE;
+ }
+}
+
+static gboolean
+ephy_tb_editor_treeview_button_press_event_cb (GtkWidget *widget,
+ GdkEventButton *event,
+ EphyTbEditor *tbe)
+{
+ EphyTbEditorPrivate *p = tbe->priv;
+
+ if (event->window != gtk_tree_view_get_bin_window (GTK_TREE_VIEW (widget)))
+ {
+ return FALSE;
+ }
+
+ if (event->type == GDK_2BUTTON_PRESS)
+ {
+ if (widget == p->current_view)
+ {
+ ephy_tb_editor_left_clicked_cb (NULL, tbe);
+ }
+ else if (widget == p->available_view)
+ {
+ ephy_tb_editor_right_clicked_cb (NULL, tbe);
+ }
+ else
+ {
+ g_assert_not_reached ();
+ }
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+GtkButton *
+ephy_tb_editor_get_revert_button (EphyTbEditor *tbe)
+{
+ EphyTbEditorPrivate *p;
+ g_return_val_if_fail (EPHY_IS_TB_EDITOR (tbe), NULL);
+ p = tbe->priv;
+ g_return_val_if_fail (GTK_IS_BUTTON (p->revert_button), NULL);
+
+ return GTK_BUTTON (p->revert_button);
+
+}
+
diff --git a/lib/toolbar/ephy-toolbar-editor.h b/lib/toolbar/ephy-toolbar-editor.h
new file mode 100644
index 000000000..97ee10e7a
--- /dev/null
+++ b/lib/toolbar/ephy-toolbar-editor.h
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+#ifndef EPHY_TOOLBAR_EDITOR_H
+#define EPHY_TOOLBAR_EDITOR_H
+
+#include <glib-object.h>
+#include <gtk/gtkbutton.h>
+
+#include "ephy-toolbar.h"
+
+G_BEGIN_DECLS
+
+/* object forward declarations */
+
+typedef struct _EphyTbEditor EphyTbEditor;
+typedef struct _EphyTbEditorClass EphyTbEditorClass;
+typedef struct _EphyTbEditorPrivate EphyTbEditorPrivate;
+
+/**
+ * TbEditor object
+ */
+
+#define EPHY_TYPE_TB_EDITOR (ephy_tb_editor_get_type())
+#define EPHY_TB_EDITOR(object) (G_TYPE_CHECK_INSTANCE_CAST((object), \
+ EPHY_TYPE_TB_EDITOR,\
+ EphyTbEditor))
+#define EPHY_TB_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EPHY_TYPE_TB_EDITOR,\
+ EphyTbEditorClass))
+#define EPHY_IS_TB_EDITOR(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), \
+ EPHY_TYPE_TB_EDITOR))
+#define EPHY_IS_TB_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EPHY_TYPE_TB_EDITOR))
+#define EPHY_TB_EDITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_TB_EDITOR,\
+ EphyTbEditorClass))
+
+struct _EphyTbEditorClass
+{
+ GObjectClass parent_class;
+};
+
+/* Remember: fields are public read-only */
+struct _EphyTbEditor
+{
+ GObject parent_object;
+
+ EphyTbEditorPrivate *priv;
+};
+
+/* this class is abstract */
+
+GType ephy_tb_editor_get_type (void);
+EphyTbEditor * ephy_tb_editor_new (void);
+void ephy_tb_editor_set_toolbar (EphyTbEditor *tbe, EphyToolbar *tb);
+EphyToolbar * ephy_tb_editor_get_toolbar (EphyTbEditor *tbe);
+void ephy_tb_editor_set_available (EphyTbEditor *tbe, EphyToolbar *tb);
+EphyToolbar * ephy_tb_editor_get_available (EphyTbEditor *tbe);
+void ephy_tb_editor_set_parent (EphyTbEditor *tbe, GtkWidget *parent);
+void ephy_tb_editor_show (EphyTbEditor *tbe);
+/* the revert button is hidden initially */
+GtkButton * ephy_tb_editor_get_revert_button (EphyTbEditor *tbe);
+
+G_END_DECLS
+
+#endif
+
diff --git a/lib/toolbar/ephy-toolbar-item-factory.c b/lib/toolbar/ephy-toolbar-item-factory.c
new file mode 100644
index 000000000..1637100ae
--- /dev/null
+++ b/lib/toolbar/ephy-toolbar-item-factory.c
@@ -0,0 +1,158 @@
+/*
+ * 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
+
+#include "ephy-toolbar-item-factory.h"
+#include <string.h>
+
+#include "ephy-tbi-zoom.h"
+#include "ephy-tbi-separator.h"
+#include "ephy-tbi-favicon.h"
+#include "ephy-tbi-spinner.h"
+#include "ephy-tbi-location.h"
+#include "ephy-tbi-navigation-history.h"
+#include "ephy-tbi-std-toolitem.h"
+
+#define NOT_IMPLEMENTED g_warning ("not implemented: " G_STRLOC);
+//#define DEBUG_MSG(x) g_print x
+#define DEBUG_MSG(x)
+
+typedef EphyTbItem *(EphyTbItemConstructor) (void);
+
+typedef struct
+{
+ const char *type_name;
+ EphyTbItemConstructor *constructor;
+} EphyTbItemTypeInfo;
+
+static EphyTbItemTypeInfo ephy_tb_item_known_types[] =
+{
+ { "std_toolitem", (EphyTbItemConstructor *) ephy_tbi_std_toolitem_new },
+ { "navigation_history", (EphyTbItemConstructor *) ephy_tbi_navigation_history_new },
+ { "zoom", (EphyTbItemConstructor *) ephy_tbi_zoom_new },
+ { "location", (EphyTbItemConstructor *) ephy_tbi_location_new },
+ { "spinner", (EphyTbItemConstructor *) ephy_tbi_spinner_new },
+ { "favicon", (EphyTbItemConstructor *) ephy_tbi_favicon_new },
+ { "separator", (EphyTbItemConstructor *) ephy_tbi_separator_new },
+ { NULL, NULL }
+};
+
+EphyTbItem *
+ephy_toolbar_item_create_from_string (const gchar *str)
+{
+ EphyTbItem *ret = NULL;
+ gchar *type;
+ gchar *props;
+ gchar *id;
+ const gchar *rest;
+ const gchar *lpar;
+ const gchar *rpar;
+ const gchar *eq;
+ int i;
+
+ rest = str;
+
+ eq = strchr (rest, '=');
+ if (eq)
+ {
+ id = g_strndup (rest, eq - rest);
+ rest = eq + 1;
+ }
+ else
+ {
+ id = NULL;
+ }
+
+ lpar = strchr (rest, '(');
+ if (lpar)
+ {
+ type = g_strndup (rest, lpar - rest);
+ rest = lpar + 1;
+
+ rpar = strchr (rest, ')');
+ if (rpar)
+ {
+ props = g_strndup (rest, rpar - rest);
+ rest = rpar + 1;
+ }
+ else
+ {
+ props = g_strdup (rest);
+ }
+ }
+ else
+ {
+ type = g_strdup (rest);
+ props = NULL;
+ }
+
+ DEBUG_MSG (("ephytoolbar_item_create_from_string id=%s type=%s props=%s\n", id, type, props));
+
+ for (i = 0; ephy_tb_item_known_types[i].type_name; ++i)
+ {
+ if (!strcmp (type, ephy_tb_item_known_types[i].type_name))
+ {
+ ret = ephy_tb_item_known_types[i].constructor ();
+ if (id)
+ {
+ ephy_tb_item_set_id (ret, id);
+ }
+ if (props)
+ {
+ ephy_tb_item_parse_properties (ret, props);
+ }
+ }
+ }
+
+ if (!ret)
+ {
+ g_warning ("Error creating toolbar item of type %s", type);
+ }
+
+ if (id)
+ {
+ g_free (id);
+ }
+ if (type)
+ {
+ g_free (type);
+ }
+ if (props)
+ {
+ g_free (props);
+ }
+
+ return ret;
+}
+
+GSList *
+ephy_toolbar_list_item_types (void)
+{
+ int i;
+ GSList *ret = NULL;
+ for (i = 0; ephy_tb_item_known_types[i].type_name; ++i)
+ {
+ ret = g_slist_prepend (ret,
+ (gchar *) ephy_tb_item_known_types[i].type_name);
+ }
+ return ret;
+}
+
diff --git a/lib/toolbar/ephy-toolbar-item-factory.h b/lib/toolbar/ephy-toolbar-item-factory.h
new file mode 100644
index 000000000..e86179399
--- /dev/null
+++ b/lib/toolbar/ephy-toolbar-item-factory.h
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+#ifndef EPHY_TOOLBAR_ITEM_FACTORY_H
+#define EPHY_TOOLBAR_ITEM_FACTORY_H
+
+#include "ephy-toolbar-item.h"
+
+G_BEGIN_DECLS
+
+EphyTbItem * ephy_toolbar_item_create_from_string (const gchar *str);
+GSList * ephy_toolbar_list_item_types (void);
+
+G_END_DECLS
+
+#endif
diff --git a/lib/toolbar/ephy-toolbar-item.c b/lib/toolbar/ephy-toolbar-item.c
new file mode 100644
index 000000000..f9c452f02
--- /dev/null
+++ b/lib/toolbar/ephy-toolbar-item.c
@@ -0,0 +1,142 @@
+/*
+ * 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
+
+#include <libgnome/gnome-i18n.h>
+
+#include "ephy-gobject-misc.h"
+#include "ephy-marshal.h"
+#include "ephy-toolbar-item.h"
+
+#define NOT_IMPLEMENTED g_warning ("not implemented: " G_STRLOC);
+//#define DEBUG_MSG(x) g_print x
+#define DEBUG_MSG(x)
+
+/**
+ * Private data
+ */
+struct _EphyTbItemPrivate
+{
+};
+
+/**
+ * Private functions, only availble from this file
+ */
+static void ephy_tb_item_class_init (EphyTbItemClass *klass);
+static void ephy_tb_item_init (EphyTbItem *tb);
+static void ephy_tb_item_finalize_impl (GObject *o);
+
+static gpointer g_object_class;
+
+/**
+ * TbItem object
+ */
+
+MAKE_GET_TYPE (ephy_tb_item, "EphyTbItem", EphyTbItem, ephy_tb_item_class_init,
+ ephy_tb_item_init, G_TYPE_OBJECT);
+
+static void
+ephy_tb_item_class_init (EphyTbItemClass *klass)
+{
+ G_OBJECT_CLASS (klass)->finalize = ephy_tb_item_finalize_impl;
+
+ g_object_class = g_type_class_peek_parent (klass);
+}
+
+static void
+ephy_tb_item_init (EphyTbItem *it)
+{
+ EphyTbItemPrivate *p = g_new0 (EphyTbItemPrivate, 1);
+ it->priv = p;
+ it->id = g_strdup ("");
+}
+
+static void
+ephy_tb_item_finalize_impl (GObject *o)
+{
+ EphyTbItem *it = EPHY_TB_ITEM (o);
+ EphyTbItemPrivate *p = it->priv;
+
+ g_free (it->id);
+ g_free (p);
+
+ DEBUG_MSG (("EphyTbItem finalized\n"));
+
+ G_OBJECT_CLASS (g_object_class)->finalize (o);
+}
+
+GtkWidget *
+ephy_tb_item_get_widget (EphyTbItem *i)
+{
+ return EPHY_TB_ITEM_GET_CLASS (i)->get_widget (i);
+}
+
+GdkPixbuf *
+ephy_tb_item_get_icon (EphyTbItem *i)
+{
+ return EPHY_TB_ITEM_GET_CLASS (i)->get_icon (i);
+}
+
+gchar *
+ephy_tb_item_get_name_human (EphyTbItem *i)
+{
+ return EPHY_TB_ITEM_GET_CLASS (i)->get_name_human (i);
+}
+
+gchar *
+ephy_tb_item_to_string (EphyTbItem *i)
+{
+ return EPHY_TB_ITEM_GET_CLASS (i)->to_string (i);
+}
+
+gboolean
+ephy_tb_item_is_unique (EphyTbItem *i)
+{
+ return EPHY_TB_ITEM_GET_CLASS (i)->is_unique (i);
+}
+
+EphyTbItem *
+ephy_tb_item_clone (EphyTbItem *i)
+{
+ return EPHY_TB_ITEM_GET_CLASS (i)->clone (i);
+}
+
+void
+ephy_tb_item_add_to_bonobo_tb (EphyTbItem *i, BonoboUIComponent *ui,
+ const char *container_path, guint index)
+{
+ EPHY_TB_ITEM_GET_CLASS (i)->add_to_bonobo_tb (i, ui, container_path, index);
+}
+
+void
+ephy_tb_item_set_id (EphyTbItem *i, const gchar *id)
+{
+ g_return_if_fail (EPHY_IS_TB_ITEM (i));
+
+ g_free (i->id);
+ i->id = g_strdup (id);
+}
+
+void
+ephy_tb_item_parse_properties (EphyTbItem *i, const gchar *props)
+{
+ EPHY_TB_ITEM_GET_CLASS (i)->parse_properties (i, props);
+}
diff --git a/lib/toolbar/ephy-toolbar-item.h b/lib/toolbar/ephy-toolbar-item.h
new file mode 100644
index 000000000..29e46697f
--- /dev/null
+++ b/lib/toolbar/ephy-toolbar-item.h
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+#ifndef EPHY_TOOLBAR_ITEM_H
+#define EPHY_TOOLBAR_ITEM_H
+
+#include <glib-object.h>
+
+#include <bonobo/bonobo-ui-component.h>
+#include <gtk/gtkwidget.h>
+
+G_BEGIN_DECLS
+
+/* object forward declarations */
+
+typedef struct _EphyTbItem EphyTbItem;
+typedef struct _EphyTbItemClass EphyTbItemClass;
+typedef struct _EphyTbItemPrivate EphyTbItemPrivate;
+
+/**
+ * TbItem object
+ */
+
+#define EPHY_TYPE_TB_ITEM (ephy_tb_item_get_type())
+#define EPHY_TB_ITEM(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EPHY_TYPE_TB_ITEM,\
+ EphyTbItem))
+#define EPHY_TB_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EPHY_TYPE_TB_ITEM,\
+ EphyTbItemClass))
+#define EPHY_IS_TB_ITEM(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EPHY_TYPE_TB_ITEM))
+#define EPHY_IS_TB_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EPHY_TYPE_TB_ITEM))
+#define EPHY_TB_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_TB_ITEM,\
+ EphyTbItemClass))
+
+struct _EphyTbItemClass
+{
+ GObjectClass parent_class;
+
+ /* virtual */
+ GtkWidget * (*get_widget) (EphyTbItem *it);
+ GdkPixbuf * (*get_icon) (EphyTbItem *it);
+ gchar * (*get_name_human) (EphyTbItem *it);
+ gchar * (*to_string) (EphyTbItem *it);
+ gboolean (*is_unique) (EphyTbItem *it);
+ void (*add_to_bonobo_tb) (EphyTbItem *it, BonoboUIComponent *ui,
+ const char *container_path, guint index);
+ EphyTbItem * (*clone) (EphyTbItem *it);
+ void (*parse_properties) (EphyTbItem *it, const gchar *props);
+};
+
+/* Remember: fields are public read-only */
+struct _EphyTbItem
+{
+ GObject parent_object;
+
+ gchar *id;
+
+ EphyTbItemPrivate *priv;
+};
+
+/* this class is abstract */
+
+GType ephy_tb_item_get_type (void);
+GtkWidget * ephy_tb_item_get_widget (EphyTbItem *i);
+GdkPixbuf * ephy_tb_item_get_icon (EphyTbItem *i);
+gchar * ephy_tb_item_get_name_human (EphyTbItem *i);
+gchar * ephy_tb_item_to_string (EphyTbItem *i);
+gboolean ephy_tb_item_is_unique (EphyTbItem *i);
+void ephy_tb_item_add_to_bonobo_tb (EphyTbItem *i, BonoboUIComponent *ui,
+ const char *container_path, guint index);
+EphyTbItem * ephy_tb_item_clone (EphyTbItem *i);
+void ephy_tb_item_set_id (EphyTbItem *i, const gchar *id);
+void ephy_tb_item_parse_properties (EphyTbItem *i, const gchar *props);
+
+G_END_DECLS
+
+#endif
diff --git a/lib/toolbar/ephy-toolbar-tree-model.c b/lib/toolbar/ephy-toolbar-tree-model.c
new file mode 100644
index 000000000..91acba952
--- /dev/null
+++ b/lib/toolbar/ephy-toolbar-tree-model.c
@@ -0,0 +1,784 @@
+/*
+ * Copyright (C) 2002 Ricardo Fernándezs Pascual <ric@users.sourceforge.net>
+ *
+ * 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
+
+#include <gtk/gtktreednd.h>
+#include <glib-object.h>
+#include <string.h>
+
+#include "ephy-toolbar-tree-model.h"
+
+#define NOT_IMPLEMENTED g_warning ("not implemented: " G_STRLOC);
+//#define DEBUG_MSG(x) g_print x
+#define DEBUG_MSG(x)
+
+#define VALID_ITER(iter, tb_tree_model) (iter!= NULL && iter->user_data != NULL \
+ && tb_tree_model->stamp == iter->stamp)
+
+/**
+ * Private data
+ */
+struct _EphyTbTreeModelPrivate
+{
+ EphyToolbar *tb;
+ GSList *curr_items;
+};
+
+/**
+ * Private functions
+ */
+static void ephy_tb_tree_model_init (EphyTbTreeModel *tb_tree_model);
+static void ephy_tb_tree_model_class_init (EphyTbTreeModelClass *tb_tree_model_class);
+static void ephy_tb_tree_model_tb_tree_model_init (GtkTreeModelIface *iface);
+static void ephy_tb_tree_model_drag_source_init (GtkTreeDragSourceIface *iface);
+static void ephy_tb_tree_model_drag_dest_init (GtkTreeDragDestIface *iface);
+static void ephy_tb_tree_model_finalize_impl (GObject *object);
+static guint ephy_tb_tree_model_get_flags_impl (GtkTreeModel *tb_tree_model);
+static gint ephy_tb_tree_model_get_n_columns_impl (GtkTreeModel *tb_tree_model);
+static GType ephy_tb_tree_model_get_column_type_impl (GtkTreeModel *tb_tree_model,
+ gint index);
+static gboolean ephy_tb_tree_model_get_iter_impl (GtkTreeModel *tb_tree_model,
+ GtkTreeIter *iter,
+ GtkTreePath *path);
+static GtkTreePath * ephy_tb_tree_model_get_path_impl (GtkTreeModel *tb_tree_model,
+ GtkTreeIter *iter);
+static void ephy_tb_tree_model_get_value_impl (GtkTreeModel *tb_tree_model,
+ GtkTreeIter *iter,
+ gint column,
+ GValue *value);
+static gboolean ephy_tb_tree_model_iter_next_impl (GtkTreeModel *tb_tree_model,
+ GtkTreeIter *iter);
+static gboolean ephy_tb_tree_model_iter_children_impl (GtkTreeModel *tb_tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *parent);
+static gboolean ephy_tb_tree_model_iter_has_child_impl (GtkTreeModel *tb_tree_model,
+ GtkTreeIter *iter);
+static gint ephy_tb_tree_model_iter_n_children_impl (GtkTreeModel *tb_tree_model,
+ GtkTreeIter *iter);
+static gboolean ephy_tb_tree_model_iter_nth_child_impl (GtkTreeModel *tb_tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *parent,
+ gint n);
+static gboolean ephy_tb_tree_model_iter_parent_impl (GtkTreeModel *tb_tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *child);
+
+/* DND interfaces */
+static gboolean ephy_tb_tree_model_drag_data_delete_impl(GtkTreeDragSource *drag_source,
+ GtkTreePath *path);
+static gboolean ephy_tb_tree_model_drag_data_get_impl (GtkTreeDragSource *drag_source,
+ GtkTreePath *path,
+ GtkSelectionData *selection_data);
+static gboolean ephy_tb_tree_model_drag_data_received_impl (GtkTreeDragDest *drag_dest,
+ GtkTreePath *dest,
+ GtkSelectionData *selection_data);
+static gboolean ephy_tb_tree_model_row_drop_possible_impl (GtkTreeDragDest *drag_dest,
+ GtkTreePath *dest_path,
+ GtkSelectionData *selection_data);
+
+/* helper functions */
+static void ephy_tb_tree_model_toolbar_changed_cb (EphyToolbar *tb, EphyTbTreeModel *tm);
+static void ephy_tb_tree_model_update (EphyTbTreeModel *tm);
+
+
+static GObjectClass *parent_class = NULL;
+
+GtkType
+ephy_tb_tree_model_get_type (void)
+{
+ static GType tb_tree_model_type = 0;
+
+ if (!tb_tree_model_type)
+ {
+ static const GTypeInfo tb_tree_model_info =
+ {
+ sizeof (EphyTbTreeModelClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) ephy_tb_tree_model_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (EphyTbTreeModel),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) ephy_tb_tree_model_init
+ };
+
+ static const GInterfaceInfo tb_gtk_tree_model_info =
+ {
+ (GInterfaceInitFunc) ephy_tb_tree_model_tb_tree_model_init,
+ NULL,
+ NULL
+ };
+
+ static const GInterfaceInfo drag_source_info =
+ {
+ (GInterfaceInitFunc) ephy_tb_tree_model_drag_source_init,
+ NULL,
+ NULL
+ };
+
+ static const GInterfaceInfo drag_dest_info =
+ {
+ (GInterfaceInitFunc) ephy_tb_tree_model_drag_dest_init,
+ NULL,
+ NULL
+ };
+
+ tb_tree_model_type = g_type_register_static (G_TYPE_OBJECT, "EphyTbTreeModel",
+ &tb_tree_model_info, 0);
+
+ g_type_add_interface_static (tb_tree_model_type,
+ GTK_TYPE_TREE_MODEL,
+ &tb_gtk_tree_model_info);
+ g_type_add_interface_static (tb_tree_model_type,
+ GTK_TYPE_TREE_DRAG_SOURCE,
+ &drag_source_info);
+ g_type_add_interface_static (tb_tree_model_type,
+ GTK_TYPE_TREE_DRAG_DEST,
+ &drag_dest_info);
+ }
+
+ return tb_tree_model_type;
+}
+
+static void
+ephy_tb_tree_model_class_init (EphyTbTreeModelClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ object_class = (GObjectClass *) class;
+
+ object_class->finalize = ephy_tb_tree_model_finalize_impl;
+}
+
+static void
+ephy_tb_tree_model_tb_tree_model_init (GtkTreeModelIface *iface)
+{
+ iface->get_flags = ephy_tb_tree_model_get_flags_impl;
+ iface->get_n_columns = ephy_tb_tree_model_get_n_columns_impl;
+ iface->get_column_type = ephy_tb_tree_model_get_column_type_impl;
+ iface->get_iter = ephy_tb_tree_model_get_iter_impl;
+ iface->get_path = ephy_tb_tree_model_get_path_impl;
+ iface->get_value = ephy_tb_tree_model_get_value_impl;
+ iface->iter_next = ephy_tb_tree_model_iter_next_impl;
+ iface->iter_children = ephy_tb_tree_model_iter_children_impl;
+ iface->iter_has_child = ephy_tb_tree_model_iter_has_child_impl;
+ iface->iter_n_children = ephy_tb_tree_model_iter_n_children_impl;
+ iface->iter_nth_child = ephy_tb_tree_model_iter_nth_child_impl;
+ iface->iter_parent = ephy_tb_tree_model_iter_parent_impl;
+}
+
+static void
+ephy_tb_tree_model_drag_source_init (GtkTreeDragSourceIface *iface)
+{
+ iface->drag_data_delete = ephy_tb_tree_model_drag_data_delete_impl;
+ iface->drag_data_get = ephy_tb_tree_model_drag_data_get_impl;
+}
+
+static void
+ephy_tb_tree_model_drag_dest_init (GtkTreeDragDestIface *iface)
+{
+ iface->drag_data_received = ephy_tb_tree_model_drag_data_received_impl;
+ iface->row_drop_possible = ephy_tb_tree_model_row_drop_possible_impl;
+}
+
+static void
+ephy_tb_tree_model_init (EphyTbTreeModel *tb_tree_model)
+{
+ EphyTbTreeModelPrivate *p = g_new0 (EphyTbTreeModelPrivate, 1);
+ tb_tree_model->priv = p;
+
+ do
+ {
+ tb_tree_model->stamp = g_random_int ();
+ }
+ while (tb_tree_model->stamp == 0);
+}
+
+EphyTbTreeModel *
+ephy_tb_tree_model_new (void)
+{
+ EphyTbTreeModel *ret = EPHY_TB_TREE_MODEL (g_object_new (EPHY_TYPE_TB_TREE_MODEL, NULL));
+ return ret;
+}
+
+
+void
+ephy_tb_tree_model_set_toolbar (EphyTbTreeModel *tm, EphyToolbar *tb)
+{
+ EphyTbTreeModelPrivate *p;
+
+ g_return_if_fail (EPHY_IS_TB_TREE_MODEL (tm));
+ g_return_if_fail (EPHY_IS_TOOLBAR (tb));
+
+ p = tm->priv;
+
+ if (p->tb)
+ {
+ g_signal_handlers_disconnect_matched (p->tb, G_SIGNAL_MATCH_DATA, 0, 0,
+ NULL, NULL, tm);
+ g_object_unref (p->tb);
+ }
+
+ p->tb = g_object_ref (tb);
+ g_signal_connect (p->tb, "changed", G_CALLBACK (ephy_tb_tree_model_toolbar_changed_cb), tm);
+
+ ephy_tb_tree_model_update (tm);
+}
+
+static void
+ephy_tb_tree_model_finalize_impl (GObject *object)
+{
+ EphyTbTreeModel *tm = EPHY_TB_TREE_MODEL (object);
+ EphyTbTreeModelPrivate *p = tm->priv;
+
+ DEBUG_MSG (("Finalizing a EphyTbTreeModel\n"));
+
+ if (p->tb)
+ {
+ g_signal_handlers_disconnect_matched (p->tb, G_SIGNAL_MATCH_DATA, 0, 0,
+ NULL, NULL, tm);
+ g_object_unref (p->tb);
+ }
+
+ g_slist_foreach (p->curr_items, (GFunc) g_object_unref, NULL);
+ g_slist_free (p->curr_items);
+ g_free (p);
+
+ (* parent_class->finalize) (object);
+}
+
+/* fulfill the GtkTreeModel requirements */
+
+static guint
+ephy_tb_tree_model_get_flags_impl (GtkTreeModel *tb_tree_model)
+{
+ return 0;
+}
+
+static gint
+ephy_tb_tree_model_get_n_columns_impl (GtkTreeModel *tb_tree_model)
+{
+ return EPHY_TB_TREE_MODEL_NUM_COLUMS;
+}
+
+static GType
+ephy_tb_tree_model_get_column_type_impl (GtkTreeModel *tb_tree_model,
+ gint index)
+{
+ g_return_val_if_fail (EPHY_IS_TB_TREE_MODEL (tb_tree_model), G_TYPE_INVALID);
+ g_return_val_if_fail ((index < EPHY_TB_TREE_MODEL_NUM_COLUMS) && (index >= 0), G_TYPE_INVALID);
+
+ switch (index)
+ {
+ case EPHY_TB_TREE_MODEL_COL_ICON:
+ return GDK_TYPE_PIXBUF;
+ break;
+ case EPHY_TB_TREE_MODEL_COL_NAME:
+ return G_TYPE_STRING;
+ break;
+ default:
+ g_assert_not_reached ();
+ return G_TYPE_INVALID;
+ break;
+ }
+}
+
+static gboolean
+ephy_tb_tree_model_get_iter_impl (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreePath *path)
+{
+ EphyTbTreeModel *tb_tree_model = (EphyTbTreeModel *) tree_model;
+ EphyTbTreeModelPrivate *p;
+ GSList *li;
+ gint i;
+
+ g_return_val_if_fail (EPHY_IS_TB_TREE_MODEL (tb_tree_model), FALSE);
+ g_return_val_if_fail (gtk_tree_path_get_depth (path) > 0, FALSE);
+
+ p = tb_tree_model->priv;
+ i = gtk_tree_path_get_indices (path)[0];
+ li = g_slist_nth (p->curr_items, i);
+
+ if (!li)
+ {
+ return FALSE;
+ }
+
+ iter->stamp = tb_tree_model->stamp;
+ iter->user_data = li;
+
+ return TRUE;
+}
+
+static GtkTreePath *
+ephy_tb_tree_model_get_path_impl (GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ EphyTbTreeModel *tb_tree_model = (EphyTbTreeModel *) tree_model;
+ EphyTbTreeModelPrivate *p;
+ gint i;
+
+ g_return_val_if_fail (EPHY_IS_TB_TREE_MODEL (tb_tree_model), NULL);
+ g_return_val_if_fail (iter != NULL, NULL);
+ g_return_val_if_fail (iter->user_data != NULL, NULL);
+ g_return_val_if_fail (iter->stamp == tb_tree_model->stamp, NULL);
+
+ p = tb_tree_model->priv;
+
+ i = g_slist_position (p->curr_items, iter->user_data);
+ if (i < 0)
+ {
+ return NULL;
+ }
+ else
+ {
+ GtkTreePath *retval;
+ retval = gtk_tree_path_new ();
+ gtk_tree_path_append_index (retval, i);
+ return retval;
+ }
+}
+
+
+static void
+ephy_tb_tree_model_get_value_impl (GtkTreeModel *tb_tree_model,
+ GtkTreeIter *iter,
+ gint column,
+ GValue *value)
+{
+ EphyTbItem *it;
+ GdkPixbuf *pb;
+ gchar *s;
+
+ g_return_if_fail (EPHY_IS_TB_TREE_MODEL (tb_tree_model));
+ g_return_if_fail (iter != NULL);
+ g_return_if_fail (iter->stamp == EPHY_TB_TREE_MODEL (tb_tree_model)->stamp);
+ g_return_if_fail (EPHY_IS_TB_ITEM (((GSList *) iter->user_data)->data));
+ g_return_if_fail (column < EPHY_TB_TREE_MODEL_NUM_COLUMS);
+
+ it = ((GSList *) iter->user_data)->data;
+
+ switch (column) {
+ case EPHY_TB_TREE_MODEL_COL_ICON:
+ g_value_init (value, GDK_TYPE_PIXBUF);
+ pb = ephy_tb_item_get_icon (it);
+ g_value_set_object (value, pb);
+ break;
+ case EPHY_TB_TREE_MODEL_COL_NAME:
+ g_value_init (value, G_TYPE_STRING);
+ s = ephy_tb_item_get_name_human (it);
+ g_value_set_string_take_ownership (value, s);
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+}
+
+static gboolean
+ephy_tb_tree_model_iter_next_impl (GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ g_return_val_if_fail (EPHY_IS_TB_TREE_MODEL (tree_model), FALSE);
+ g_return_val_if_fail (EPHY_TB_TREE_MODEL (tree_model)->stamp == iter->stamp, FALSE);
+
+ iter->user_data = ((GSList *) (iter->user_data))->next;
+ return (iter->user_data != NULL);
+}
+
+static gboolean
+ephy_tb_tree_model_iter_children_impl (GtkTreeModel *tb_tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *parent)
+{
+ if (parent)
+ {
+ /* this is a list, nodes have no children */
+ return FALSE;
+ }
+ else
+ {
+ /* but if parent == NULL we return the list itself as children of the
+ * "root"
+ */
+ EphyTbTreeModel *tm = EPHY_TB_TREE_MODEL (tb_tree_model);
+ EphyTbTreeModelPrivate *p = tm->priv;
+
+ iter->stamp = tm->stamp;
+ iter->user_data = p->curr_items;
+ return (p->curr_items != NULL);
+ }
+}
+
+static gboolean
+ephy_tb_tree_model_iter_has_child_impl (GtkTreeModel *tb_tree_model,
+ GtkTreeIter *iter)
+{
+ return FALSE;
+}
+
+static gint
+ephy_tb_tree_model_iter_n_children_impl (GtkTreeModel *tb_tree_model,
+ GtkTreeIter *iter)
+{
+ EphyTbTreeModel *tm = (EphyTbTreeModel *) tb_tree_model;
+ EphyTbTreeModelPrivate *p;
+ g_return_val_if_fail (EPHY_IS_TB_TREE_MODEL (tm), -1);
+
+ p = tm->priv;
+
+ if (iter == NULL)
+ {
+ return g_slist_length (p->curr_items);
+ }
+
+ g_return_val_if_fail (tm->stamp == iter->stamp, -1);
+ return 0;
+}
+
+static gboolean
+ephy_tb_tree_model_iter_nth_child_impl (GtkTreeModel *tb_tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *parent,
+ gint n)
+{
+ EphyTbTreeModel *tm = (EphyTbTreeModel *) tb_tree_model;
+ EphyTbTreeModelPrivate *p;
+ g_return_val_if_fail (EPHY_IS_TB_TREE_MODEL (tm), FALSE);
+
+ p = tm->priv;
+
+ if (parent)
+ {
+ return FALSE;
+ }
+ else
+ {
+ GSList *li = g_slist_nth (p->curr_items, n);
+
+ if (li)
+ {
+ iter->stamp = tm->stamp;
+ iter->user_data = li;
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+}
+
+static gboolean
+ephy_tb_tree_model_iter_parent_impl (GtkTreeModel *tb_tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *child)
+{
+ return FALSE;
+}
+
+
+
+/* DND */
+
+
+static gboolean
+ephy_tb_tree_model_drag_data_delete_impl (GtkTreeDragSource *drag_source,
+ GtkTreePath *path)
+{
+ GtkTreeIter iter;
+ EphyTbTreeModel *tm;
+
+ g_return_val_if_fail (EPHY_IS_TB_TREE_MODEL (drag_source), FALSE);
+
+ tm = EPHY_TB_TREE_MODEL (drag_source);
+
+ DEBUG_MSG (("in ephy_tb_tree_model_drag_data_delete_impl\n"));
+
+ if (ephy_tb_tree_model_get_iter_impl (GTK_TREE_MODEL (tm), &iter, path))
+ {
+ EphyTbTreeModelPrivate *p = tm->priv;
+ EphyTbItem *it = ephy_tb_tree_model_item_from_iter (tm, &iter);
+ EphyTbItem *delete_hack;
+ if ((delete_hack = g_object_get_data (G_OBJECT (tm),
+ "gul-toolbar-tree-model-dnd-delete-hack")) != NULL)
+ {
+ g_return_val_if_fail (EPHY_IS_TB_ITEM (delete_hack), FALSE);
+ g_object_ref (delete_hack);
+
+ g_object_set_data (G_OBJECT (tm),
+ "gul-toolbar-tree-model-dnd-delete-hack", NULL);
+
+ if (!strcmp (delete_hack->id, it->id))
+ {
+ g_object_unref (delete_hack);
+ return FALSE;
+ }
+ g_object_unref (delete_hack);
+ }
+
+ ephy_toolbar_remove_item (p->tb, it);
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+static gboolean
+ephy_tb_tree_model_drag_data_get_impl (GtkTreeDragSource *drag_source,
+ GtkTreePath *path,
+ GtkSelectionData *selection_data)
+{
+ g_return_val_if_fail (EPHY_IS_TB_TREE_MODEL (drag_source), FALSE);
+
+ /* Note that we don't need to handle the GTK_TB_TREE_MODEL_ROW
+ * target, because the default handler does it for us, but
+ * we do anyway for the convenience of someone maybe overriding the
+ * default handler.
+ */
+
+ if (gtk_tree_set_row_drag_data (selection_data,
+ GTK_TREE_MODEL (drag_source),
+ path))
+ {
+ return TRUE;
+ }
+ else
+ {
+ /* to string ? */
+ }
+
+ return FALSE;
+}
+
+
+static gboolean
+ephy_tb_tree_model_drag_data_received_impl (GtkTreeDragDest *drag_dest,
+ GtkTreePath *dest,
+ GtkSelectionData *selection_data)
+{
+ EphyTbTreeModel *tbm;
+ GtkTreeModel *src_model = NULL;
+ GtkTreePath *src_path = NULL;
+
+ g_return_val_if_fail (EPHY_IS_TB_TREE_MODEL (drag_dest), FALSE);
+ g_return_val_if_fail (gtk_tree_path_get_depth (dest) == 1, FALSE);
+
+ tbm = EPHY_TB_TREE_MODEL (drag_dest);
+
+ DEBUG_MSG (("in ephy_tb_tree_model_drag_data_received_impl\n"));
+
+ if (gtk_tree_get_row_drag_data (selection_data,
+ &src_model,
+ &src_path)
+ && EPHY_IS_TB_TREE_MODEL (src_model))
+ {
+ /* copy the item */
+
+ GtkTreeIter src_iter;
+ EphyTbItem *it;
+ int idx = gtk_tree_path_get_indices (dest)[0];
+
+ if (!gtk_tree_model_get_iter (src_model,
+ &src_iter,
+ src_path))
+ {
+ gtk_tree_path_free (src_path);
+ return FALSE;
+ }
+ gtk_tree_path_free (src_path);
+
+ if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (drag_dest),
+ "gtk-tree-model-drop-append")))
+ {
+ ++idx;
+ }
+
+ it = ephy_tb_item_clone (EPHY_TB_ITEM (((GSList *)src_iter.user_data)->data));
+ ephy_toolbar_add_item (tbm->priv->tb, it, idx);
+
+ /* hack */
+ if (src_model == GTK_TREE_MODEL (drag_dest)
+ && ephy_toolbar_get_check_unique (EPHY_TB_TREE_MODEL (src_model)->priv->tb)
+ && ephy_tb_item_is_unique (it))
+ {
+ g_object_set_data_full (G_OBJECT (src_model),
+ "gul-toolbar-tree-model-dnd-delete-hack", it,
+ g_object_unref);
+ }
+ else
+ {
+ g_object_unref (it);
+ }
+
+ g_object_set_data (G_OBJECT (drag_dest), "gtk-tree-model-drop-append", NULL);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+ephy_tb_tree_model_row_drop_possible_impl (GtkTreeDragDest *drag_dest,
+ GtkTreePath *dest_path,
+ GtkSelectionData *selection_data)
+{
+ GtkTreeModel *src_model = NULL;
+ GtkTreePath *src_path = NULL;
+ gboolean retval = FALSE;
+ EphyTbTreeModel *tm;
+ EphyTbTreeModelPrivate *p;
+
+ g_return_val_if_fail (EPHY_IS_TB_TREE_MODEL (drag_dest), FALSE);
+ tm = EPHY_TB_TREE_MODEL (drag_dest);
+ p = tm->priv;
+
+ if (gtk_tree_path_get_depth (dest_path) != 1)
+ {
+ return FALSE;
+ }
+ if (!gtk_tree_get_row_drag_data (selection_data,
+ &src_model,
+ &src_path))
+ {
+ return FALSE;
+ }
+
+ /* can drop before any existing node, or before one past any existing. */
+
+ retval = (gtk_tree_path_get_indices (dest_path)[0] <= (gint) g_slist_length (p->curr_items));
+
+ gtk_tree_path_free (src_path);
+
+ return retval;
+}
+
+
+EphyTbItem *
+ephy_tb_tree_model_item_from_iter (EphyTbTreeModel *tm, GtkTreeIter *iter)
+{
+ return iter ? EPHY_TB_ITEM (((GSList *) iter->user_data)->data) : NULL;
+}
+
+static void
+ephy_tb_tree_model_toolbar_changed_cb (EphyToolbar *tb, EphyTbTreeModel *tm)
+{
+ ephy_tb_tree_model_update (tm);
+}
+
+static void
+ephy_tb_tree_model_update (EphyTbTreeModel *tm)
+{
+ EphyTbTreeModelPrivate *p;
+ GSList *new_items;
+ GSList *old_items;
+ GSList *li;
+ GSList *lj;
+ int i;
+
+ g_return_if_fail (EPHY_IS_TB_TREE_MODEL (tm));
+ p = tm->priv;
+ g_return_if_fail (EPHY_IS_TOOLBAR (p->tb));
+
+ old_items = p->curr_items;
+ new_items = g_slist_copy ((GSList *) ephy_toolbar_get_item_list (p->tb));
+ g_slist_foreach (new_items, (GFunc) g_object_ref, NULL);
+ p->curr_items = new_items;
+
+ li = new_items;
+ lj = old_items;
+ i = 0;
+
+ while (li && lj)
+ {
+ if (li->data == lj->data)
+ {
+ li = li->next;
+ lj = lj->next;
+ ++i;
+ }
+ else if (lj->next && lj->next->data == li->data)
+ {
+ GtkTreePath *p = gtk_tree_path_new ();
+ gtk_tree_path_append_index (p, i);
+ gtk_tree_model_row_deleted (GTK_TREE_MODEL (tm), p);
+ gtk_tree_path_free (p);
+ lj = lj->next;
+ }
+ else if (li->next && li->next->data == lj->data)
+ {
+ GtkTreePath *p = gtk_tree_path_new ();
+ GtkTreeIter iter;
+ iter.stamp = tm->stamp;
+ iter.user_data = li;
+ gtk_tree_path_append_index (p, i);
+ gtk_tree_model_row_inserted (GTK_TREE_MODEL (tm), p, &iter);
+ gtk_tree_path_free (p);
+ li = li->next;
+ ++i;
+ }
+ else
+ {
+ GtkTreePath *p = gtk_tree_path_new ();
+ GtkTreeIter iter;
+ iter.stamp = tm->stamp;
+ iter.user_data = li;
+ gtk_tree_path_append_index (p, i);
+ gtk_tree_model_row_deleted (GTK_TREE_MODEL (tm), p);
+ gtk_tree_model_row_inserted (GTK_TREE_MODEL (tm), p, &iter);
+ gtk_tree_path_free (p);
+ lj = lj->next;
+ li = li->next;
+ ++i;
+ }
+ }
+
+ while (li)
+ {
+ GtkTreePath *p = gtk_tree_path_new ();
+ GtkTreeIter iter;
+ iter.stamp = tm->stamp;
+ iter.user_data = li;
+ gtk_tree_path_append_index (p, i);
+ gtk_tree_model_row_inserted (GTK_TREE_MODEL (tm), p, &iter);
+ gtk_tree_path_free (p);
+ li = li->next;
+ ++i;
+ }
+
+ while (lj)
+ {
+ GtkTreePath *p = gtk_tree_path_new ();
+ gtk_tree_path_append_index (p, i);
+ gtk_tree_model_row_deleted (GTK_TREE_MODEL (tm), p);
+ gtk_tree_path_free (p);
+ lj = lj->next;
+ }
+
+ g_slist_foreach (old_items, (GFunc) g_object_unref, NULL);
+ g_slist_free (old_items);
+}
+
diff --git a/lib/toolbar/ephy-toolbar-tree-model.h b/lib/toolbar/ephy-toolbar-tree-model.h
new file mode 100644
index 000000000..893e6ba9a
--- /dev/null
+++ b/lib/toolbar/ephy-toolbar-tree-model.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2002 Ricardo Fernándezs Pascual <ric@users.sourceforge.net>
+ *
+ * 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.
+ */
+
+#ifndef EPHY_TOOLBAR_TREE_MODEL_H
+#define EPHY_TOOLBAR_TREE_MODEL_H
+
+#include <gtk/gtktreemodel.h>
+#include "ephy-toolbar.h"
+
+G_BEGIN_DECLS
+
+/* object forward declarations */
+
+typedef struct _EphyTbTreeModel EphyTbTreeModel;
+typedef struct _EphyTbTreeModelClass EphyTbTreeModelClass;
+typedef struct _EphyTbTreeModelPrivate EphyTbTreeModelPrivate;
+
+typedef enum {
+ EPHY_TB_TREE_MODEL_COL_ICON,
+ EPHY_TB_TREE_MODEL_COL_NAME,
+ EPHY_TB_TREE_MODEL_NUM_COLUMS
+} EphyTbTreeModelColumn;
+
+/**
+ * Tb tree model object
+ */
+
+#define EPHY_TYPE_TB_TREE_MODEL (ephy_tb_tree_model_get_type())
+#define EPHY_TB_TREE_MODEL(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EPHY_TYPE_TB_TREE_MODEL,\
+ EphyTbTreeModel))
+#define EPHY_TB_TREE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EPHY_TYPE_TB_TREE_MODEL,\
+ EphyTbTreeModelClass))
+#define EPHY_IS_TB_TREE_MODEL(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EPHY_TYPE_TB_TREE_MODEL))
+#define EPHY_IS_TB_TREE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EPHY_TYPE_TB_TREE_MODEL))
+#define EPHY_TB_TREE_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_TB_TREE_MODEL,\
+ EphyTbTreeModelClass))
+
+struct _EphyTbTreeModel
+{
+ GObject parent;
+
+ EphyTbTreeModelPrivate *priv;
+ gint stamp;
+};
+
+struct _EphyTbTreeModelClass
+{
+ GObjectClass parent_class;
+};
+
+
+GtkType ephy_tb_tree_model_get_type (void);
+EphyTbTreeModel * ephy_tb_tree_model_new (void);
+void ephy_tb_tree_model_set_toolbar (EphyTbTreeModel *tm, EphyToolbar *tb);
+EphyTbItem * ephy_tb_tree_model_item_from_iter (EphyTbTreeModel *tm, GtkTreeIter *iter);
+
+G_END_DECLS
+
+#endif
diff --git a/lib/toolbar/ephy-toolbar.c b/lib/toolbar/ephy-toolbar.c
new file mode 100644
index 000000000..53598cc6c
--- /dev/null
+++ b/lib/toolbar/ephy-toolbar.c
@@ -0,0 +1,420 @@
+/*
+ * 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
+
+#include <libgnome/gnome-i18n.h>
+#include <string.h>
+#include "ephy-gobject-misc.h"
+#include "ephy-marshal.h"
+#include "ephy-toolbar.h"
+#include "ephy-toolbar-item-factory.h"
+#include "eel-gconf-extensions.h"
+
+#define NOT_IMPLEMENTED g_warning ("not implemented: " G_STRLOC);
+//#define DEBUG_MSG(x) g_print x
+#define DEBUG_MSG(x)
+
+/**
+ * Private data
+ */
+struct _EphyToolbarPrivate
+{
+ GSList *items;
+ guint gconf_notification_id;
+
+ gboolean check_unique;
+ gboolean fixed_order;
+ GSList *order; /* list of ids */
+};
+
+/**
+ * Private functions, only availble from this file
+ */
+static void ephy_toolbar_class_init (EphyToolbarClass *klass);
+static void ephy_toolbar_init (EphyToolbar *tb);
+static void ephy_toolbar_finalize_impl (GObject *o);
+static void ephy_toolbar_listen_to_gconf_cb (GConfClient* client,
+ guint cnxn_id,
+ GConfEntry *entry,
+ gpointer user_data);
+static void ephy_toolbar_update_order (EphyToolbar *tb);
+
+
+static gpointer g_object_class;
+
+/* signals enums and ids */
+enum EphyToolbarSignalsEnum {
+ EPHY_TOOLBAR_CHANGED,
+ EPHY_TOOLBAR_LAST_SIGNAL
+};
+static gint EphyToolbarSignals[EPHY_TOOLBAR_LAST_SIGNAL];
+
+/**
+ * Toolbar object
+ */
+
+MAKE_GET_TYPE (ephy_toolbar, "EphyToolbar", EphyToolbar, ephy_toolbar_class_init,
+ ephy_toolbar_init, G_TYPE_OBJECT);
+
+static void
+ephy_toolbar_class_init (EphyToolbarClass *klass)
+{
+ G_OBJECT_CLASS (klass)->finalize = ephy_toolbar_finalize_impl;
+
+ EphyToolbarSignals[EPHY_TOOLBAR_CHANGED] = g_signal_new (
+ "changed", G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST | G_SIGNAL_RUN_CLEANUP,
+ G_STRUCT_OFFSET (EphyToolbarClass, changed),
+ NULL, NULL,
+ ephy_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ g_object_class = g_type_class_peek_parent (klass);
+}
+
+static void
+ephy_toolbar_init (EphyToolbar *tb)
+{
+ EphyToolbarPrivate *p = g_new0 (EphyToolbarPrivate, 1);
+ tb->priv = p;
+
+ p->check_unique = TRUE;
+}
+
+static void
+ephy_toolbar_finalize_impl (GObject *o)
+{
+ EphyToolbar *tb = EPHY_TOOLBAR (o);
+ EphyToolbarPrivate *p = tb->priv;
+
+ g_slist_foreach (p->items, (GFunc) g_object_unref, NULL);
+ g_slist_free (p->items);
+
+ if (p->gconf_notification_id)
+ {
+ eel_gconf_notification_remove (p->gconf_notification_id);
+ }
+
+ g_slist_foreach (p->order, (GFunc) g_free, NULL);
+ g_slist_free (p->order);
+
+ g_free (p);
+
+ DEBUG_MSG (("EphyToolbar finalized\n"));
+
+ G_OBJECT_CLASS (g_object_class)->finalize (o);
+}
+
+
+EphyToolbar *
+ephy_toolbar_new (void)
+{
+ EphyToolbar *ret = g_object_new (EPHY_TYPE_TOOLBAR, NULL);
+ return ret;
+}
+
+gboolean
+ephy_toolbar_parse (EphyToolbar *tb, const gchar *cfg)
+{
+ EphyToolbarPrivate *p = tb->priv;
+ GSList *list = NULL;
+ gchar **items;
+ int i;
+
+ g_return_val_if_fail (EPHY_IS_TOOLBAR (tb), FALSE);
+ g_return_val_if_fail (cfg != NULL, FALSE);
+
+ items = g_strsplit (cfg, ";", 9999);
+ if (!items) return FALSE;
+
+ for (i = 0; items[i]; ++i)
+ {
+ if (items[i][0])
+ {
+ EphyTbItem *it = ephy_toolbar_item_create_from_string (items[i]);
+
+ if (!it)
+ {
+ /* FIXME: this leaks everything... */
+ return FALSE;
+ }
+
+ list = g_slist_prepend (list, it);
+ }
+ }
+
+ g_strfreev (items);
+
+ g_slist_foreach (p->items, (GFunc) g_object_unref, NULL);
+ g_slist_free (p->items);
+ p->items = g_slist_reverse (list);
+
+ if (p->fixed_order)
+ {
+ ephy_toolbar_update_order (tb);
+ }
+
+ g_signal_emit (tb, EphyToolbarSignals[EPHY_TOOLBAR_CHANGED], 0);
+
+ return TRUE;
+}
+
+gchar *
+ephy_toolbar_to_string (EphyToolbar *tb)
+{
+ EphyToolbarPrivate *p = tb->priv;
+ gchar *ret;
+ GString *str = g_string_new ("");
+ GSList *li;
+
+ for (li = p->items; li; li = li->next)
+ {
+ EphyTbItem *it = li->data;
+ gchar *s = ephy_tb_item_to_string (it);
+ g_string_append (str, s);
+ if (li->next)
+ {
+ g_string_append (str, ";");
+ }
+ g_free (s);
+ }
+
+ ret = str->str;
+ g_string_free (str, FALSE);
+ return ret;
+}
+
+static void
+ephy_toolbar_listen_to_gconf_cb (GConfClient* client,
+ guint cnxn_id,
+ GConfEntry *entry,
+ gpointer user_data)
+{
+ EphyToolbar *tb = user_data;
+ GConfValue *value;
+ const char *str;
+
+ g_return_if_fail (EPHY_IS_TOOLBAR (tb));
+
+ value = gconf_entry_get_value (entry);
+ str = gconf_value_get_string (value);
+
+ DEBUG_MSG (("in ephy_toolbar_listen_to_gconf_cb\n"));
+
+ ephy_toolbar_parse (tb, str);
+}
+
+/**
+ * Listen to changes in the toolbar configuration. Returns TRUE if the
+ * current configuration is valid.
+ */
+gboolean
+ephy_toolbar_listen_to_gconf (EphyToolbar *tb, const gchar *gconf_key)
+{
+ EphyToolbarPrivate *p = tb->priv;
+ gchar *s;
+ gboolean ret = FALSE;
+
+ if (p->gconf_notification_id)
+ {
+ eel_gconf_notification_remove (p->gconf_notification_id);
+ }
+
+ s = eel_gconf_get_string (gconf_key);
+ if (s)
+ {
+ ret = ephy_toolbar_parse (tb, s);
+ g_free (s);
+ }
+
+ p->gconf_notification_id = eel_gconf_notification_add (gconf_key,
+ ephy_toolbar_listen_to_gconf_cb,
+ tb);
+
+ DEBUG_MSG (("listening to %s, %d (FIXME: does not seem to work)\n",
+ gconf_key, p->gconf_notification_id));
+
+ return ret;
+}
+
+EphyTbItem *
+ephy_toolbar_get_item_by_id (EphyToolbar *tb, const gchar *id)
+{
+ EphyToolbarPrivate *p = tb->priv;
+ GSList *li;
+
+ for (li = p->items; li; li = li->next)
+ {
+ EphyTbItem *i = li->data;
+ if (i->id && !strcmp (i->id, id))
+ {
+ return i;
+ }
+ }
+ return NULL;
+}
+
+const GSList *
+ephy_toolbar_get_item_list (EphyToolbar *tb)
+{
+ EphyToolbarPrivate *p = tb->priv;
+ return p->items;
+}
+
+void
+ephy_toolbar_add_item (EphyToolbar *tb, EphyTbItem *it, gint index)
+{
+ EphyToolbarPrivate *p = tb->priv;
+ EphyTbItem *old_it;
+
+ g_return_if_fail (g_slist_find (p->items, it) == NULL);
+
+ if (p->check_unique && ephy_tb_item_is_unique (it)
+ && (old_it = ephy_toolbar_get_item_by_id (tb, it->id)) != NULL)
+ {
+ GSList *old_it_link;
+ if (p->fixed_order)
+ {
+ return;
+ }
+ old_it_link = g_slist_find (p->items, old_it);
+ p->items = g_slist_insert (p->items, old_it, index);
+ p->items = g_slist_delete_link (p->items, old_it_link);
+
+ }
+ else
+ {
+ if (p->fixed_order)
+ {
+ GSList *li;
+ if (ephy_toolbar_get_item_by_id (tb, it->id) != NULL)
+ {
+ return;
+ }
+ index = 0;
+ for (li = p->order; li && strcmp (li->data, it->id); li = li->next)
+ {
+ if (ephy_toolbar_get_item_by_id (tb, li->data) != NULL)
+ {
+ ++index;
+ }
+ }
+ }
+
+ p->items = g_slist_insert (p->items, it, index);
+ g_object_ref (it);
+ }
+ g_signal_emit (tb, EphyToolbarSignals[EPHY_TOOLBAR_CHANGED], 0);
+}
+
+void
+ephy_toolbar_remove_item (EphyToolbar *tb, EphyTbItem *it)
+{
+ EphyToolbarPrivate *p = tb->priv;
+
+ g_return_if_fail (g_slist_find (p->items, it) != NULL);
+
+ p->items = g_slist_remove (p->items, it);
+
+ g_signal_emit (tb, EphyToolbarSignals[EPHY_TOOLBAR_CHANGED], 0);
+
+ g_object_unref (it);
+}
+
+void
+ephy_toolbar_set_fixed_order (EphyToolbar *tb, gboolean value)
+{
+ EphyToolbarPrivate *p = tb->priv;
+ p->fixed_order = value;
+
+ if (value)
+ {
+ ephy_toolbar_update_order (tb);
+ }
+}
+
+void
+ephy_toolbar_set_check_unique (EphyToolbar *tb, gboolean value)
+{
+ EphyToolbarPrivate *p = tb->priv;
+ p->check_unique = value;
+
+ /* maybe it should remove duplicated items now, if any */
+}
+
+gboolean
+ephy_toolbar_get_check_unique (EphyToolbar *tb)
+{
+ EphyToolbarPrivate *p = tb->priv;
+ return p->check_unique;
+}
+
+static void
+ephy_toolbar_update_order (EphyToolbar *tb)
+{
+ EphyToolbarPrivate *p = tb->priv;
+ GSList *li;
+ GSList *lj;
+ GSList *new_order = NULL;
+
+ lj = p->order;
+ for (li = p->items; li; li = li->next)
+ {
+ EphyTbItem *i = li->data;
+ const gchar *id = i->id;
+
+ if (g_slist_find_custom (lj, id, (GCompareFunc) strcmp))
+ {
+ for ( ; lj && strcmp (lj->data, id); lj = lj->next)
+ {
+ if (ephy_toolbar_get_item_by_id (tb, lj->data) == NULL)
+ {
+ new_order = g_slist_prepend (new_order, g_strdup (lj->data));
+ }
+ }
+ }
+
+ new_order = g_slist_prepend (new_order, g_strdup (id));
+
+ }
+
+ for ( ; lj; lj = lj->next)
+ {
+ if (ephy_toolbar_get_item_by_id (tb, lj->data) == NULL)
+ {
+ new_order = g_slist_prepend (new_order, g_strdup (lj->data));
+ }
+ }
+
+ g_slist_foreach (p->order, (GFunc) g_free, NULL);
+ g_slist_free (p->order);
+
+ p->order = g_slist_reverse (new_order);
+
+#ifdef DEBUG_ORDER
+ DEBUG_MSG (("New order:\n"));
+ for (lj = p->order; lj; lj = lj->next)
+ {
+ DEBUG_MSG (("%s\n", (char *) lj->data));
+ }
+#endif
+}
+
diff --git a/lib/toolbar/ephy-toolbar.h b/lib/toolbar/ephy-toolbar.h
new file mode 100644
index 000000000..3c70a4783
--- /dev/null
+++ b/lib/toolbar/ephy-toolbar.h
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+#ifndef EPHY_TOOLBAR_H
+#define EPHY_TOOLBAR_H
+
+#include <glib-object.h>
+
+#include "ephy-toolbar-item.h"
+
+G_BEGIN_DECLS
+
+/* object forward declarations */
+
+typedef struct _EphyToolbar EphyToolbar;
+typedef struct _EphyToolbarClass EphyToolbarClass;
+typedef struct _EphyToolbarPrivate EphyToolbarPrivate;
+
+/**
+ * Toolbar object
+ */
+
+#define EPHY_TYPE_TOOLBAR (ephy_toolbar_get_type())
+#define EPHY_TOOLBAR(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EPHY_TYPE_TOOLBAR,\
+ EphyToolbar))
+#define EPHY_TOOLBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EPHY_TYPE_TOOLBAR,\
+ EphyToolbarClass))
+#define EPHY_IS_TOOLBAR(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EPHY_TYPE_TOOLBAR))
+#define EPHY_IS_TOOLBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EPHY_TYPE_TOOLBAR))
+#define EPHY_TOOLBAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_TOOLBAR,\
+ EphyToolbarClass))
+
+struct _EphyToolbarClass
+{
+ GObjectClass parent_class;
+
+ /* signals */
+ void (*changed) (EphyToolbar *tb);
+
+};
+
+/* Remember: fields are public read-only */
+struct _EphyToolbar
+{
+ GObject parent_object;
+
+ EphyToolbarPrivate *priv;
+};
+
+GType ephy_toolbar_get_type (void);
+EphyToolbar * ephy_toolbar_new (void);
+gboolean ephy_toolbar_parse (EphyToolbar *tb, const gchar *cfg);
+gchar * ephy_toolbar_to_string (EphyToolbar *tb);
+gboolean ephy_toolbar_listen_to_gconf (EphyToolbar *tb, const gchar *gconf_key);
+EphyTbItem * ephy_toolbar_get_item_by_id (EphyToolbar *tb, const gchar *id);
+const GSList * ephy_toolbar_get_item_list (EphyToolbar *tb);
+void ephy_toolbar_add_item (EphyToolbar *tb, EphyTbItem *it, gint index);
+void ephy_toolbar_remove_item (EphyToolbar *tb, EphyTbItem *it);
+void ephy_toolbar_set_fixed_order (EphyToolbar *tb, gboolean value);
+void ephy_toolbar_set_check_unique (EphyToolbar *tb, gboolean value);
+gboolean ephy_toolbar_get_check_unique (EphyToolbar *tb);
+
+G_END_DECLS
+
+#endif