--- epiphany/ChangeLog	2003-05-11 10:53:41.000000000 +0200
+++ epiphany-build/ChangeLog	2003-05-11 12:02:26.000000000 +0200
@@ -1,3 +1,89 @@
+2003-05-11  Christian Persch <chpe+epiphany@stud.uni-saarland.de>
+
+	Reorganised zoom features and implemented zoom control on toolbar:
+
+	* embed/mozilla/mozilla-embed.c: (impl_zoom_set, impl_zoom_get):
+	* embed/ephy-embed.[ch]: (zoom_set), (zoom_get), (ephy_embed_zoom_set),
+	(ephy_embed_zoom_get):
+	* lib/ephy-marshal.list:
+	* src/ephy-nautilus-view.c: (gnv_embed_zoom_change_cb),
+	(gnv_zoomable_set_zoom_level_cb):
+	* src/ephy-tab.c: (ephy_tab_zoom_changed_cb):
+	* src/ephy-window.c: (ephy_window_set_zoom):
+
+	Use float zoom factor instead of int percent for zoom.
+
+	* lib/widgets/ephy-zoom-control.h:
+	* lib/widgets/ephy-zoom-control.c:
+
+	New. First cut to implement a simple zoom control. 
+
+	* src/ephy-zoom-action.h:
+	* src/ephy-zoom-action.c:
+
+	New. Egg action to place a zoom control on the toolbar.
+
+	* lib/ephy-zoom.h:
+	* lib/ephy-zoom.c:
+
+	New. Some zoom helper functions and definitions.
+
+	* src/ephy-nautilus-view.c: (ephy_nautilus_view_instance_init),
+	(ephy_nautilus_view_class_init), (gnv_zoomable_set_zoom_level_cb),
+	(gnv_zoomable_zoom_in_cb), (gnv_zoomable_zoom_out_cb),
+	(gnv_zoomable_zoom_to_default_cb), (gnv_embed_zoom_change_cb):
+	* src/window-commands.c: (window_cmd_view_zoom_in),
+	(window_cmd_view_zoom_out), (window_cmd_view_zoom_normal):
+
+	Simplified; use new functions from ephy-zoom.h where appropriate.
+
+	* embed/ephy-history.h:
+	* embed/ephy-history.c: (ephy_history_get_page_zoom),
+	(ephy_history_set_page_zoom):
+
+	New functions to save and retrieve the zoom levels on a per-host basis.
+
+	* src/ephy-window.c: (ephy_window_set_zoom):
+	
+	After setting zoom, save the level.
+
+	* src/ephy-tab.c: (ephy_tab_location_cb):
+	
+	Retrieve saved zoom level for host and apply it.
+
+	* src/toolbar.h:
+	* src/toolbar.c: (toolbar_update_zoom_control):
+	
+	New. Sets the toolbar's zoom control's level.
+	
+	* src/toolbar.c: (zoom_in_cb), (zoom_out_cb), (zoom_to_level_cb),
+	(zoom_to_fit_cb):
+	
+	New. Callbacks for ephy-zoom-action's signals.
+
+	* src/toolbar.c: (toolbar_setup_actions):
+	
+	Hook up zoom actions.
+	
+	* src/ephy-window.c: (toolbar_update_zoom_control):
+	
+	New. Updates toolbar zoom control and menu item sensitivity.
+	
+	* src/ephy-window.h:
+	* src/ephy-window.c: (ephy_window_change_zoom):
+	
+	New. Zooms the window's active embed in/out/to level/to default.
+
+	* data/art/epiphany-zoom-control.png:
+	* lib/ephy-stock-icons.[ch]:
+
+	Added icon for zoom control.
+
+	* data/ui/epiphany-toolbar.xml.in:
+
+	Make the zoom control and zoom in/out/normal actions available to be
+	added to the toolbar.
+
 2003-05-11  Xan Lopez  <xan@masilla.org>
 
 	* src/bookmarks/ephy-topic-action.c: (build_bookmarks_menu):
--- epiphany/data/art/Makefile.am	2003-04-29 11:04:59.000000000 +0200
+++ epiphany-build/data/art/Makefile.am	2003-04-30 09:51:35.000000000 +0200
@@ -9,8 +9,9 @@
 	epiphany-new-tab.png	\
 	epiphany-viewsource.png \
 	epiphany-send-link.png	\
-	epiphany-bookmarks.png \
-	epiphany-tab-loading.gif
+	epiphany-bookmarks.png	\
+	epiphany-tab-loading.gif \
+	epiphany-zoom-control.png
 
 appicon_DATA = epiphany.png epiphany-bookmarks.png
 appicondir = $(datadir)/pixmaps
--- epiphany/data/ui/epiphany-toolbar.xml.in	2003-04-28 21:15:43.000000000 +0200
+++ epiphany-build/data/ui/epiphany-toolbar.xml.in	2003-05-08 20:27:46.000000000 +0200
@@ -20,6 +20,10 @@
 	<toolitem verb="Location"/>
 	<toolitem verb="Spinner"/>
 	<toolitem verb="ToolbarGo"/>
+	<toolitem verb="ViewZoomIn"/>
+	<toolitem verb="ViewZoomOut"/>
+	<toolitem verb="ViewZoomNormal"/>
+	<toolitem verb="Zoom"/>
 </available>
 <toolbar name="DefaultToolbar">
 	<toolitem verb="NavigationBack"/>
--- epiphany/embed/mozilla/mozilla-embed.cpp	2003-05-10 16:13:36.000000000 +0200
+++ epiphany-build/embed/mozilla/mozilla-embed.cpp	2003-05-10 16:36:47.000000000 +0200
@@ -25,6 +25,7 @@
 #include "MozillaPrivate.h"
 #include "EphyWrapper.h"
 #include "EventContext.h"
+#include "ephy-debug.h"
 
 #include <nsIWindowWatcher.h>
 #include <nsIURI.h>
@@ -37,8 +38,6 @@
 #include <nsIPrintOptions.h>
 #include <nsGfxCIID.h>
 
-#include <math.h>
-
 static void
 mozilla_embed_class_init (MozillaEmbedClass *klass);
 static void
@@ -104,11 +103,11 @@
 		EmbedDisplayType display_type);
 static gresult
 impl_zoom_set (EphyEmbed *embed, 
-               int zoom, 
+               float zoom, 
                gboolean reflow);
 static gresult
 impl_zoom_get (EphyEmbed *embed,
-               int *zoom);
+               float *zoom);
 static gresult 
 impl_selection_can_cut (EphyEmbed *embed);
 static gresult 
@@ -772,7 +771,7 @@
 
 static gresult
 impl_zoom_set (EphyEmbed *embed, 
-               int zoom, 
+               float zoom, 
                gboolean reflow)
 {
 	EphyWrapper *wrapper;
@@ -781,7 +780,7 @@
 	wrapper = MOZILLA_EMBED(embed)->priv->wrapper;
 	g_return_val_if_fail (wrapper != NULL, G_FAILED);
 
-	result = wrapper->SetZoom ((float)(zoom) / 100, reflow);
+	result = wrapper->SetZoom (zoom, reflow);
 
 	if (NS_SUCCEEDED (result))
 	{
@@ -793,7 +792,7 @@
 
 static gresult
 impl_zoom_get (EphyEmbed *embed,
-               int *zoom)
+               float *zoom)
 {
 	float f;
 	EphyWrapper *wrapper;
@@ -801,15 +800,17 @@
 	wrapper = MOZILLA_EMBED(embed)->priv->wrapper;
 	if (!wrapper)
 	{
-		*zoom = 100;
-		return G_OK;
+		LOG ("impl_zoom_get: wrapper == NULL")
+		
+//		*zoom = 1.0;
+		return G_FAILED;
 	}
 	
 	nsresult result = wrapper->GetZoom (&f);
 	
 	if (NS_SUCCEEDED (result))
 	{
-		*zoom = (int) rint (f * 100);
+		*zoom = f;
 
 		return G_OK;
 	}
--- epiphany/embed/ephy-embed.h	2003-02-05 21:28:09.000000000 +0100
+++ epiphany-build/embed/ephy-embed.h	2003-04-24 19:38:15.000000000 +0200
@@ -235,10 +235,10 @@
 					    EphyEmbed *source,
 					    EmbedDisplayType display_type);
 	gresult   (* zoom_set)             (EphyEmbed *embed,
-					    int zoom,
+					    float zoom,
 					    gboolean reflow);
 	gresult   (* zoom_get)             (EphyEmbed *embed,
-				            int *zoom);
+				            float *zoom);
 	gresult   (* selection_can_cut)    (EphyEmbed *embed);
 	gresult   (* selection_can_copy)   (EphyEmbed *embed);
 	gresult   (* can_paste)            (EphyEmbed *embed);
@@ -337,11 +337,11 @@
 
 /* Zoom */
 gresult       ephy_embed_zoom_set             (EphyEmbed *embed,
-					       int zoom,
+					       float zoom,
 					       gboolean reflow);
 
 gresult       ephy_embed_zoom_get             (EphyEmbed *embed,
-					       int *zoom);
+					       float *zoom);
 
 /* Clipboard */
 gresult       ephy_embed_selection_can_cut    (EphyEmbed *embed);
--- epiphany/embed/ephy-embed.c	2003-02-05 21:28:09.000000000 +0100
+++ epiphany-build/embed/ephy-embed.c	2003-04-26 13:45:53.000000000 +0200
@@ -245,10 +245,10 @@
                               G_SIGNAL_RUN_LAST,
                               G_STRUCT_OFFSET (EphyEmbedClass, zoom_change),
                               NULL, NULL,
-                              g_cclosure_marshal_VOID__INT,
+                              g_cclosure_marshal_VOID__FLOAT,
                               G_TYPE_NONE,
                               1,
-			      G_TYPE_INT);
+			      G_TYPE_FLOAT);
 	initialized = TRUE;
 	}
 }
@@ -411,7 +411,7 @@
 
 gresult
 ephy_embed_zoom_set (EphyEmbed *embed,
-                     int zoom,
+                     float zoom,
                      gboolean reflow)
 {
 	EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed);
@@ -420,7 +420,7 @@
 
 gresult
 ephy_embed_zoom_get (EphyEmbed *embed,
-                     int *zoom)
+                     float *zoom)
 {
 	EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed);
         return klass->zoom_get (embed, zoom);
--- epiphany/lib/widgets/Makefile.am	2003-04-28 19:38:18.000000000 +0200
+++ epiphany-build/lib/widgets/Makefile.am	2003-04-29 10:33:20.000000000 +0200
@@ -28,5 +28,6 @@
 	ephy-tree-model-node.c			\
 	ephy-tree-model-node.h			\
 	ephy-tree-model-sort.c			\
-	ephy-tree-model-sort.h
-
+	ephy-tree-model-sort.h			\
+	ephy-zoom-control.c			\
+	ephy-zoom-control.h
--- epiphany/lib/widgets/ephy-zoom-control.h	1970-01-01 01:00:00.000000000 +0100
+++ epiphany-build/lib/widgets/ephy-zoom-control.h	2003-05-08 19:42:30.000000000 +0200
@@ -0,0 +1,89 @@
+/*
+ *  Copyright (C) 2002  Ricardo Fernández Pascual
+ *  Copyright (C) 2003  Christian Persch
+ *
+ *  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_ZOOM_CONTROL_H
+#define EPHY_ZOOM_CONTROL_H
+
+#include "ephy-zoom.h"
+
+#include <glib-object.h>
+#include <gtk/gtkvbox.h>
+
+/* object forward declarations */
+
+typedef struct _EphyZoomControl EphyZoomControl;
+typedef struct _EphyZoomControlClass EphyZoomControlClass;
+typedef struct _EphyZoomControlPrivate EphyZoomControlPrivate;
+
+/**
+ * EphyZoomControl object
+ */
+
+#define EPHY_TYPE_ZOOM_CONTROL			(ephy_zoom_control_get_type())
+#define EPHY_ZOOM_CONTROL(object)		(G_TYPE_CHECK_INSTANCE_CAST((object), EPHY_TYPE_ZOOM_CONTROL, EphyZoomControl))
+#define EPHY_ZOOM_CONTROL_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), EPHY_TYPE_ZOOM_CONTROL, EphyZoomControlClass))
+#define EPHY_IS_ZOOM_CONTROL(object)		(G_TYPE_CHECK_INSTANCE_TYPE((object), EPHY_TYPE_ZOOM_CONTROL))
+#define EPHY_IS_ZOOM_CONTROL_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), EPHY_TYPE_ZOOM_CONTROL))
+#define EPHY_ZOOM_CONTROL_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_ZOOM_CONTROL, EphyZoomControlClass))
+
+struct _EphyZoomControlClass
+{
+	GtkVBoxClass parent_class;
+
+	/* signals */
+	void (*zoom_in)		(EphyZoomControl *control);
+	void (*zoom_out) 	(EphyZoomControl *control);
+	void (*zoom_to_level) 	(EphyZoomControl *control,
+				 float zoom_level);
+	void (*zoom_to_fit) 	(EphyZoomControl *control);
+};
+
+/* Remember: fields are public read-only */
+struct _EphyZoomControl
+{
+	GtkVBox parent_object;
+
+	EphyZoomControlPrivate *priv;
+};
+
+GType      ephy_zoom_control_get_type		(void);
+
+GtkWidget *ephy_zoom_control_new		(void);
+
+void       ephy_zoom_control_set_zoom_level     (EphyZoomControl *control,
+						 float zoom_level);
+
+void       ephy_zoom_control_set_parameters	(EphyZoomControl *control,
+						 float min_zoom_level,
+						 float max_zoom_level,
+						 float *preferred_zoom_levels,
+						 gchar **preferred_zoom_level_names,
+						 guint n_preferred_zoom_levels);
+
+float      ephy_zoom_control_get_zoom_level	(EphyZoomControl *control);
+
+float      ephy_zoom_control_get_min_zoom_level	(EphyZoomControl *control);
+
+float      ephy_zoom_control_get_max_zoom_level	(EphyZoomControl *control);
+
+gboolean   ephy_zoom_control_can_zoom_in	(EphyZoomControl *control);
+
+gboolean   ephy_zoom_control_can_zoom_out	(EphyZoomControl *control);
+
+#endif
--- epiphany/lib/widgets/ephy-zoom-control.c	1970-01-01 01:00:00.000000000 +0100
+++ epiphany-build/lib/widgets/ephy-zoom-control.c	2003-05-08 20:21:17.000000000 +0200
@@ -0,0 +1,251 @@
+/*
+ *  Copyright (C) 2002  Ricardo Fernández Pascual
+ *  Copyright (C) 2003  Christian Persch
+ *
+ *  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.
+ */
+
+#include "ephy-zoom-control.h"
+#include "ephy-marshal.h"
+#include "ephy-gobject-misc.h"
+#include "ephy-debug.h"
+
+#include <gtk/gtk.h>
+#include <glib-object.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkoptionmenu.h>
+
+/**
+ * Private data
+ */
+struct _EphyZoomControlPrivate {
+	GtkWidget *option_menu;
+	GtkWidget *menu;
+	float zoom;
+	float *levels;
+	guint n_levels;
+
+	guint handler_id;
+	char *last_action_target;
+};
+
+/**
+ * Private functions, only availble from this file
+ */
+static void	ephy_zoom_control_class_init	(EphyZoomControlClass *klass);
+static void	ephy_zoom_control_init		(EphyZoomControl *control);
+static void	ephy_zoom_control_finalize_impl	(GObject *o);
+static void	ephy_zoom_control_changed_cb	(GtkOptionMenu *option_menu,
+						 EphyZoomControl *control);
+
+static gpointer gtk_vbox_class;
+
+/**
+ * Signals enums and ids
+ */
+enum EphyZoomControlSignalsEnum {
+	ZOOM_IN_SIGNAL,
+	ZOOM_OUT_SIGNAL,
+	ZOOM_TO_LEVEL_SIGNAL,
+	ZOOM_TO_FIT_SIGNAL,
+	LAST_SIGNAL
+};
+static guint signals[LAST_SIGNAL];
+
+/**
+ * EphyZoomControl object
+ */
+
+MAKE_GET_TYPE (ephy_zoom_control, "EphyZoomControl", EphyZoomControl,
+	       ephy_zoom_control_class_init,
+	       ephy_zoom_control_init, GTK_TYPE_VBOX);
+
+static void
+ephy_zoom_control_class_init (EphyZoomControlClass *klass)
+{
+	G_OBJECT_CLASS (klass)->finalize = ephy_zoom_control_finalize_impl;
+	gtk_vbox_class = g_type_class_peek_parent (klass);
+
+	signals[ZOOM_IN_SIGNAL] =
+		g_signal_new ("zoom_in",
+		              G_TYPE_FROM_CLASS (klass),
+		              G_SIGNAL_RUN_LAST,
+		              G_STRUCT_OFFSET (EphyZoomControlClass,
+					       zoom_in),
+		              NULL, NULL,
+		              g_cclosure_marshal_VOID__VOID,
+		              G_TYPE_NONE, 0);
+
+	signals[ZOOM_OUT_SIGNAL] =
+		g_signal_new ("zoom_out",
+		              G_TYPE_FROM_CLASS (klass),
+		              G_SIGNAL_RUN_LAST,
+		              G_STRUCT_OFFSET (EphyZoomControlClass,
+					       zoom_out),
+		              NULL, NULL,
+		              g_cclosure_marshal_VOID__VOID,
+		              G_TYPE_NONE, 0);
+
+	signals[ZOOM_TO_LEVEL_SIGNAL] =
+		g_signal_new ("zoom_to_level",
+		              G_TYPE_FROM_CLASS (klass),
+		              G_SIGNAL_RUN_LAST,
+		              G_STRUCT_OFFSET (EphyZoomControlClass,
+					       zoom_to_level),
+		              NULL, NULL,
+		              g_cclosure_marshal_VOID__FLOAT,
+		              G_TYPE_NONE,
+			      1,
+			      G_TYPE_FLOAT);
+
+	signals[ZOOM_TO_FIT_SIGNAL] =
+		g_signal_new ("zoom_to_fit",
+		              G_TYPE_FROM_CLASS (klass),
+		              G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+		              G_STRUCT_OFFSET (EphyZoomControlClass,
+					       zoom_to_fit),
+		              NULL, NULL,
+		              g_cclosure_marshal_VOID__VOID,
+		              G_TYPE_NONE, 0);
+}
+
+static void
+ephy_zoom_control_init (EphyZoomControl *control)
+{
+	EphyZoomControlPrivate *p;
+	
+	p = g_new0 (EphyZoomControlPrivate, 1);
+	control->priv = p;
+	p->menu = NULL;
+	p->levels = NULL;
+	p->n_levels = 0;
+	p->zoom = 1.0;
+	p->last_action_target = NULL;
+
+	p->option_menu = gtk_option_menu_new ();
+	gtk_widget_show (p->option_menu);
+	gtk_box_pack_start (GTK_BOX (control), p->option_menu, TRUE, FALSE, 2);
+	p->handler_id = g_signal_connect (p->option_menu, "changed",
+					  G_CALLBACK (ephy_zoom_control_changed_cb), control);
+}
+
+void
+ephy_zoom_control_set_parameters	(EphyZoomControl *control,
+					 float min_zoom_level,
+					 float max_zoom_level,
+					 float *preferred_zoom_levels,
+					 gchar **preferred_zoom_level_names,
+					 guint n_preferred_zoom_levels)
+{
+	EphyZoomControlPrivate *p;
+	GtkWidget *item;
+	guint i;
+
+	g_return_if_fail (EPHY_IS_ZOOM_CONTROL (control));
+	p = control->priv;
+	p->levels = preferred_zoom_levels;
+	p->n_levels = n_preferred_zoom_levels;
+
+	p->menu = gtk_menu_new ();
+
+	for (i = 0; i < n_preferred_zoom_levels; i++)
+	{
+		item = gtk_menu_item_new_with_label (preferred_zoom_level_names[i]);
+		gtk_menu_shell_append  (GTK_MENU_SHELL (p->menu),item);
+		gtk_widget_show (item);
+		g_object_set_data (G_OBJECT (item), "desc", preferred_zoom_level_names[i]);
+	}
+	
+	gtk_widget_show (p->menu);
+	gtk_option_menu_set_menu (GTK_OPTION_MENU (p->option_menu), p->menu);
+	gtk_option_menu_set_history (GTK_OPTION_MENU (p->option_menu), ephy_zoom_get_index (1.0));
+}
+
+static void
+ephy_zoom_control_changed_cb (GtkOptionMenu *option_menu, EphyZoomControl *control)
+{
+	EphyZoomControlPrivate *p = control->priv;
+	gint index;
+
+	index = gtk_option_menu_get_history (option_menu);
+
+	if (p->zoom != p->levels[index])
+	{
+		g_signal_emit (control, signals[ZOOM_TO_LEVEL_SIGNAL], 0, p->levels[index]);	
+	}
+}
+
+static void
+ephy_zoom_control_finalize_impl (GObject *o)
+{
+	EphyZoomControl *control = EPHY_ZOOM_CONTROL (o);
+	EphyZoomControlPrivate *p = control->priv;
+	
+	LOG ("EphyZoomControl finalized")
+
+	g_free (p);
+	G_OBJECT_CLASS (gtk_vbox_class)->finalize (o);
+}
+
+GtkWidget *
+ephy_zoom_control_new (void)
+{
+	return GTK_WIDGET (g_object_new (EPHY_TYPE_ZOOM_CONTROL, NULL));
+}
+
+void
+ephy_zoom_control_set_zoom_level (EphyZoomControl *control,
+				  float zoom_level)
+{
+	EphyZoomControlPrivate *p = control->priv;
+	guint index;
+	
+	index = ephy_zoom_get_index (zoom_level);
+	p->zoom = p->levels[index];
+
+	g_signal_handler_block (p->option_menu, p->handler_id);
+	gtk_option_menu_set_history (GTK_OPTION_MENU (p->option_menu), index);
+	g_signal_handler_unblock (p->option_menu, p->handler_id);	
+}
+	
+float
+ephy_zoom_control_get_zoom_level (EphyZoomControl *control)
+{
+	return control->priv->zoom;
+}
+
+float
+ephy_zoom_control_get_min_zoom_level (EphyZoomControl *control)
+{
+	return ZOOM_MINIMAL;
+}
+
+float
+ephy_zoom_control_get_max_zoom_level (EphyZoomControl *control)
+{
+	return ZOOM_MAXIMAL;
+}
+
+gboolean
+ephy_zoom_control_can_zoom_in (EphyZoomControl *control)
+{
+	return control->priv->zoom < ZOOM_MAXIMAL;
+}
+
+gboolean
+ephy_zoom_control_can_zoom_out (EphyZoomControl *control)
+{
+	return control->priv->zoom > ZOOM_MINIMAL;
+}
--- epiphany/lib/Makefile.am	2003-01-21 13:35:45.000000000 +0100
+++ epiphany-build/lib/Makefile.am	2003-04-23 16:24:32.000000000 +0200
@@ -53,7 +53,9 @@
 	ephy-stock-icons.h			\
 	ephy-thread-helpers.c			\
 	ephy-thread-helpers.h			\
-	ephy-types.h
+	ephy-types.h				\
+	ephy-zoom.h				\
+	ephy-zoom.c
 
 libephy_la_LIBADD = \
 	$(top_builddir)/lib/widgets/libephywidgets.la	\
--- epiphany/lib/ephy-marshal.list	2003-03-29 18:07:48.000000000 +0100
+++ epiphany-build/lib/ephy-marshal.list	2003-04-25 00:13:28.000000000 +0200
@@ -15,3 +15,4 @@
 VOID:INT,INT,INT
 INT:OBJECT
 VOID:POINTER,POINTER
+VOID:FLOAT
--- epiphany/lib/ephy-stock-icons.h	2003-03-24 21:08:05.000000000 +0100
+++ epiphany-build/lib/ephy-stock-icons.h	2003-04-26 13:54:37.000000000 +0200
@@ -33,6 +33,7 @@
 #define EPHY_STOCK_VIEWSOURCE      "epiphany-viewsource"
 #define EPHY_STOCK_SEND_LINK       "epiphany-send-link"
 #define EPHY_STOCK_ENTRY		    "epiphany-entry"
+#define EPHY_STOCK_ZOOM_CONTROL		"epiphany-zoom-control"
 
 void ephy_stock_icons_init (void);
 
--- epiphany/lib/ephy-stock-icons.c	2003-03-24 21:08:05.000000000 +0100
+++ epiphany-build/lib/ephy-stock-icons.c	2003-04-24 09:53:01.000000000 +0200
@@ -43,7 +43,8 @@
 		EPHY_STOCK_NEW_TAB,
 		EPHY_STOCK_VIEWSOURCE,
 		EPHY_STOCK_SEND_LINK,
-		EPHY_STOCK_ENTRY
+		EPHY_STOCK_ENTRY,
+		EPHY_STOCK_ZOOM_CONTROL
 	};
 
 	factory = gtk_icon_factory_new ();
--- epiphany/lib/ephy-zoom.h	1970-01-01 01:00:00.000000000 +0100
+++ epiphany-build/lib/ephy-zoom.h	2003-05-08 20:10:14.000000000 +0200
@@ -0,0 +1,53 @@
+/*
+ *  Copyright (C) 2003 Christian Persch
+ *
+ *  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_ZOOM_H
+#define EPHY_ZOOM_H
+
+#include <gtk/gtkwidget.h>
+
+G_BEGIN_DECLS
+
+typedef enum
+{
+	ZOOM_IN,
+	ZOOM_OUT,
+	ZOOM_TO_DEFAULT,
+	ZOOM_TO_FIT
+} ZoomChangeFlags;
+
+
+
+
+#define NUM_ZOOM_FACTORS	11
+
+#define ZOOM_MINIMAL		0.5
+#define ZOOM_MAXIMAL		4.0
+
+void	ephy_zoom_get_factors 		(float *zoom_factors,
+					 gchar **zoom_factor_names);
+
+guint	ephy_zoom_get_index		(float factor);
+
+float	ephy_zoom_get_changed_factor	(float factor, gint steps);
+
+float	ephy_zoom_get_nearest_factor	(float factor);
+
+G_END_DECLS
+
+#endif
--- epiphany/lib/ephy-zoom.c	1970-01-01 01:00:00.000000000 +0100
+++ epiphany-build/lib/ephy-zoom.c	2003-05-08 20:35:52.000000000 +0200
@@ -0,0 +1,114 @@
+/*
+ *  Copyright (C) 2003 Christian Persch
+ *  Copyright (C) 2000-2002 Marco Pesenti Gritti
+ *  Copyright (C) 2000 Eazel, Inc.
+ *
+ *  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-zoom.h"
+#include "ephy-debug.h"
+
+#include <bonobo/bonobo-i18n.h>
+#include <math.h>
+
+/**
+ * Private functions, available only from this file
+ */
+float ephy_zoom_get_factor (guint index);
+
+static const float zoom_factor_exponents[] =
+{
+	-1.0,
+	-0.75,
+	-0.5,
+	-0.25,
+	0.0,
+	0.25,
+	0.5,
+	0.75,
+	1.0,
+	1.5,
+	2.0
+};
+
+#define ZOOM_FACTOR_BASE_LOG	G_LN2
+
+void
+ephy_zoom_get_factors (float *zoom_factors,
+		       gchar **zoom_factor_names)
+{
+	float f;
+	guint i, percent;
+
+	for (i = 0; i < NUM_ZOOM_FACTORS; i++)
+	{		
+		f = ephy_zoom_get_factor (i);
+		zoom_factors[i] = f;
+		percent = floor ((100.0 * f) + .5);
+		zoom_factor_names[i] = g_strdup_printf ("%d%%", percent);
+	}
+}
+
+guint
+ephy_zoom_get_index (float factor)
+{
+	float exponent, last, curr;
+	gint i;
+
+	exponent = logf (factor) / ZOOM_FACTOR_BASE_LOG;
+
+	last = zoom_factor_exponents[0];
+	if (last > exponent) return 0;
+
+	for (i = 0; i < NUM_ZOOM_FACTORS; i++)
+	{
+		curr = zoom_factor_exponents[i];
+		if (curr > exponent)
+		{
+			float center = (last + curr) / 2.0;
+
+			return (exponent < center) ? i-1 : i;
+		}
+
+		last = curr;
+	}
+
+	return NUM_ZOOM_FACTORS - 1;	
+}
+
+float
+ephy_zoom_get_factor (guint index)
+{
+	return expf (zoom_factor_exponents[index] * ZOOM_FACTOR_BASE_LOG);
+}
+
+float
+ephy_zoom_get_changed_factor (float factor, gint steps)
+{
+	guint index;
+
+	index = ephy_zoom_get_index (factor);
+	return ephy_zoom_get_factor (CLAMP(index + steps, 0, NUM_ZOOM_FACTORS - 1));
+}
+
+float	ephy_zoom_get_nearest_factor (float factor)
+{
+	return ephy_zoom_get_changed_factor (factor, 0);
+}
--- epiphany/src/Makefile.am	2003-05-11 10:53:44.000000000 +0200
+++ epiphany-build/src/Makefile.am	2003-05-11 11:01:33.000000000 +0200
@@ -72,6 +72,8 @@
 	ephy-toolbars-model.h				\
 	ephy-window.c					\
 	ephy-window.h					\
+	ephy-zoom-action.c				\
+	ephy-zoom-action.h				\
 	language-editor.c				\
 	language-editor.h				\
 	pdm-dialog.c					\
--- epiphany/src/ephy-nautilus-view.c	2003-05-03 18:51:29.000000000 +0200
+++ epiphany-build/src/ephy-nautilus-view.c	2003-05-05 21:04:02.000000000 +0200
@@ -29,6 +29,7 @@
 #include "find-dialog.h"
 #include "print-dialog.h"
 #include "ephy-prefs.h"
+#include "ephy-zoom.h"
 #include "eel-gconf-extensions.h"
 #include "ephy-debug.h"
 
@@ -47,7 +48,7 @@
 								 EphyEmbedEvent *event,
 								 EphyNautilusView *view);
 static void		gnv_embed_zoom_change_cb 		(EphyNautilusView *embed,
-								 guint new_zoom, 
+								 float new_zoom, 
 								 EphyNautilusView *view);
 
 
@@ -97,33 +98,8 @@
 								 EphyEmbedPopup *popup, 
 								 const char* verbname);
 
-
-static float preferred_zoom_levels[] = {
-	0.2, 0.4, 0.6, 0.8,
-	1.0, 1.2, 1.4, 1.6, 1.8,
-	2.0, 2.2, 2.4, 2.6, 2.8,
-	3.0, 3.2, 3.4, 3.6, 3.8,
-	4.0, 4.2, 4.4, 4.6, 4.8,
-	5.0, 5.2, 5.4, 5.6, 5.8,
-	6.0, 6.2, 6.4, 6.6, 6.8,
-	7.0, 7.2, 7.4, 7.6, 7.8,
-	8.0, 8.2, 8.4, 8.6, 8.8,
-	9.0, 9.2, 9.4, 9.6, 9.8,
-};
-
-static const gchar *preferred_zoom_level_names[] = {
-	"20%", "40%", "60%", "80%",
-	"100%", "120%", "140%", "160%", "180%",
-	"200%", "220%", "240%", "260%", "280%",
-	"300%", "320%", "340%", "360%", "380%",
-	"400%", "420%", "440%", "460%", "480%",
-	"500%", "520%", "540%", "560%", "580%",
-	"600%", "620%", "640%", "660%", "680%",
-	"700%", "720%", "740%", "760%", "780%",
-	"800%", "820%", "840%", "860%", "880%",
-	"900%", "920%", "940%", "960%", "980%",
-};
-#define NUM_ZOOM_LEVELS (sizeof (preferred_zoom_levels) / sizeof (float))
+static float preferred_zoom_levels[NUM_ZOOM_FACTORS];
+static gchar *preferred_zoom_level_names[NUM_ZOOM_FACTORS];
 
 struct EphyNautilusViewPrivate {
 	EphyEmbed *embed;
@@ -253,11 +229,11 @@
 	bonobo_zoomable_set_parameters_full (view->priv->zoomable,
 					     1.0,
 					     preferred_zoom_levels [0],
-					     preferred_zoom_levels [NUM_ZOOM_LEVELS - 1],
+					     preferred_zoom_levels [NUM_ZOOM_FACTORS - 1],
 					     FALSE, FALSE, TRUE,
 					     preferred_zoom_levels,
-					     preferred_zoom_level_names,
-					     NUM_ZOOM_LEVELS);
+					     (const gchar **) preferred_zoom_level_names,
+					     NUM_ZOOM_FACTORS);
 
 	bonobo_object_add_interface (BONOBO_OBJECT (view),
 				     BONOBO_OBJECT (view->priv->zoomable));
@@ -323,6 +299,9 @@
 static void
 ephy_nautilus_view_class_init (EphyNautilusViewClass *class)
 {
+	ephy_zoom_get_factors (preferred_zoom_levels,
+			       preferred_zoom_level_names);
+
 	G_OBJECT_CLASS (class)->finalize = ephy_nautilus_view_finalize;
 }
 
@@ -465,7 +444,7 @@
 					  EMBED_CHROME_OPENASPOPUP);
 	}
 	new_tab = ephy_tab_new ();
-	ephy_window_add_tab (window, new_tab, FALSE, FALSE);
+	ephy_window_add_tab (window, new_tab, EPHY_NOTEBOOK_INSERT_LAST, FALSE);
 	
 	*new_embed = ephy_tab_get_embed (new_tab);
 }
@@ -613,33 +592,41 @@
 				float level,
 				EphyNautilusView *view)
 {
-	gint zoom = level * 100;
 	g_return_if_fail (EPHY_IS_NAUTILUS_VIEW (view));
-	if (zoom < 10) return;
-	if (zoom > 1000) return;
-	ephy_embed_zoom_set (view->priv->embed, zoom, TRUE);
+	ephy_embed_zoom_set (view->priv->embed,
+			     CLAMP (level, ZOOM_MINIMAL, ZOOM_MAXIMAL), TRUE);
 }
 
 static void
 gnv_zoomable_zoom_in_cb (BonoboZoomable *zoomable,
 			 EphyNautilusView *view)
 {
-	gint zoom;
+	float zoom, new_zoom;
+	gresult rv;
+	
 	g_return_if_fail (EPHY_IS_NAUTILUS_VIEW (view));
-	ephy_embed_zoom_get (view->priv->embed, &zoom);
-	if (zoom > 990) return;
-	ephy_embed_zoom_set (view->priv->embed, zoom + 10, TRUE);
+
+	rv = ephy_embed_zoom_get (view->priv->embed, &zoom);
+	if (rv == G_FAILED) return;
+
+	new_zoom = ephy_zoom_get_changed_factor (zoom, 1);
+	ephy_embed_zoom_set (view->priv->embed, new_zoom, TRUE);
 }
 
 static void
 gnv_zoomable_zoom_out_cb (BonoboZoomable *zoomable,
 			  EphyNautilusView *view)
 {
-	gint zoom;
+	float zoom, new_zoom;
+	gresult rv;
+		
 	g_return_if_fail (EPHY_IS_NAUTILUS_VIEW (view));
-	ephy_embed_zoom_get (view->priv->embed, &zoom);
-	if (zoom < 20) return;
-	ephy_embed_zoom_set (view->priv->embed, zoom - 10, TRUE);
+
+	rv = ephy_embed_zoom_get (view->priv->embed, &zoom);
+	if (rv == G_FAILED) return;
+
+	new_zoom = ephy_zoom_get_changed_factor (zoom, -1);
+	ephy_embed_zoom_set (view->priv->embed, new_zoom, TRUE);
 }
 
 static void
@@ -654,22 +641,18 @@
 				 EphyNautilusView *view)
 {
 	g_return_if_fail (EPHY_IS_NAUTILUS_VIEW (view));
-	ephy_embed_zoom_set (view->priv->embed, 100, TRUE);
+	ephy_embed_zoom_set (view->priv->embed, 1.0, TRUE);
 }
 
 static void
 gnv_embed_zoom_change_cb (EphyNautilusView *embed,
-			  guint new_zoom, 
+			  float new_zoom, 
 			  EphyNautilusView *view)
 {
-	float flevel;
 	g_return_if_fail (EPHY_IS_NAUTILUS_VIEW (view));
 	
-	flevel = ((float) new_zoom) / 100.0;
-	
 	bonobo_zoomable_report_zoom_level_changed (view->priv->zoomable,
-						   flevel, NULL);
-	
+						   new_zoom, NULL);
 }
 
 
--- epiphany/src/ephy-tab.c	2003-05-11 10:53:44.000000000 +0200
+++ epiphany-build/src/ephy-tab.c	2003-05-11 10:59:55.000000000 +0200
@@ -391,6 +393,11 @@
 static void
 ephy_tab_location_cb (EphyEmbed *embed, EphyTab *tab)
 {
+
+
+
+
+
 	if (tab->priv->location) g_free (tab->priv->location);
 	ephy_embed_get_location (embed, TRUE,
 				 &tab->priv->location);
@@ -404,10 +411,32 @@
 		ephy_window_update_control (tab->priv->window, NavControl);
 		ephy_window_update_control (tab->priv->window, FaviconControl);
 	}
+
+
+
+	
+	 
+	
+		
+
+		
+		
+		
+				
+
+			
+		
+
+		
+		
+			
+			
+		
+	
 }
 
 static void
-ephy_tab_zoom_changed_cb (EphyEmbed *embed, gint zoom, EphyTab *tab)
+ephy_tab_zoom_changed_cb (EphyEmbed *embed, float zoom, EphyTab *tab)
 {
 	if (tab->priv->is_active)
 	{
--- epiphany/src/ephy-zoom-action.h	1970-01-01 01:00:00.000000000 +0100
+++ epiphany-build/src/ephy-zoom-action.h	2003-04-25 16:05:50.000000000 +0200
@@ -0,0 +1,55 @@
+/*
+ *  Copyright (C) 2003 Marco Pesenti Gritti
+ *  Copyright (C) 2003 Christian Persch
+ *
+ *  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_ZOOM_ACTION_H
+#define EPHY_ZOOM_ACTION_H
+
+#include <gtk/gtk.h>
+#include <egg-action.h>
+
+#define EPHY_TYPE_ZOOM_ACTION            (ephy_zoom_action_get_type ())
+#define EPHY_ZOOM_ACTION(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), EPHY_TYPE_ZOOM_ACTION, EphyZoomAction))
+#define EPHY_ZOOM_ACTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), EPHY_TYPE_ZOOM_ACTION, EphyZoomActionClass))
+#define EPHY_IS_ZOOM_ACTION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EPHY_TYPE_ZOOM_ACTION))
+#define EPHY_IS_ZOOM_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EPHY_TYPE_ZOOM_ACTION))
+#define EPHY_ZOOM_ACTION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_ZOOM_ACTION, EphyZoomActionClass))
+
+typedef struct _EphyZoomAction        EphyZoomAction;
+typedef struct _EphyZoomActionClass   EphyZoomActionClass;
+
+struct _EphyZoomAction
+{
+	EggAction parent;
+};
+
+struct _EphyZoomActionClass
+{
+	EggActionClass parent_class;
+
+	void (* zoom_in)	(EphyZoomAction *action);
+	void (* zoom_out)	(EphyZoomAction *action);
+	void (* zoom_to_level)	(EphyZoomAction *action, float level);
+	void (* zoom_to_fit)	(EphyZoomAction *action);
+};
+
+GType      ephy_zoom_action_get_type   (void);
+
+GtkWidget *ephy_zoom_action_get_widget (EphyZoomAction *action);
+
+#endif
--- epiphany/src/ephy-zoom-action.c	1970-01-01 01:00:00.000000000 +0100
+++ epiphany-build/src/ephy-zoom-action.c	2003-05-08 20:39:40.000000000 +0200
@@ -0,0 +1,242 @@
+/*
+ *  Copyright (C) 2003 Marco Pesenti Gritti
+ *  Copyright (C) 2003 Christian Persch
+ *
+ *  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.
+ */
+
+#include "ephy-zoom-action.h"
+#include "ephy-zoom-control.h"
+#include "ephy-shell.h"
+#include "ephy-debug.h"
+#include "eggtoolitem.h"
+
+static void ephy_zoom_action_init       (EphyZoomAction *action);
+static void ephy_zoom_action_class_init (EphyZoomActionClass *class);
+
+enum
+{
+	ZOOM_IN_SIGNAL,
+	ZOOM_OUT_SIGNAL,
+	ZOOM_TO_LEVEL_SIGNAL,
+	ZOOM_TO_FIT_SIGNAL,
+	LAST_SIGNAL
+};
+
+enum
+{
+        PROP_WINDOW
+};
+
+static GObjectClass *parent_class = NULL;
+
+static guint ephy_zoom_action_signals[LAST_SIGNAL] = { 0 };
+
+static float zoom_factors[NUM_ZOOM_FACTORS];
+static gchar *zoom_factor_names[NUM_ZOOM_FACTORS];
+
+GType
+ephy_zoom_action_get_type (void)
+{
+	static GType type = 0;
+
+	if (!type)
+	{
+		static const GTypeInfo type_info =
+		{
+			sizeof (EphyZoomActionClass),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) ephy_zoom_action_class_init,
+			(GClassFinalizeFunc) NULL,
+			NULL,
+			sizeof (EphyZoomAction),
+			0, /* n_preallocs */
+			(GInstanceInitFunc) ephy_zoom_action_init,
+		};
+
+		type = g_type_register_static (EGG_TYPE_ACTION,
+					       "EphyZoomAction",
+					       &type_info, 0);
+	}
+	return type;
+}
+
+static GtkWidget *
+create_tool_item (EggAction *action)
+{
+	GtkWidget *item;
+	GtkWidget *control;
+	GtkWidget *hbox, *vbox;
+
+	LOG ("Create zoom toolitem")
+
+	item = GTK_WIDGET (egg_tool_item_new ());
+	control = ephy_zoom_control_new ();
+
+	ephy_zoom_control_set_parameters (EPHY_ZOOM_CONTROL (control),
+					  ZOOM_MINIMAL, ZOOM_MAXIMAL,
+					  zoom_factors,
+					  zoom_factor_names,
+					  NUM_ZOOM_FACTORS);
+
+	/* FIXME: what's the proper way to do this padding? */
+	hbox = gtk_hbox_new (TRUE, 2);
+	gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (control), TRUE, TRUE, 2);
+	vbox = gtk_vbox_new (TRUE, 2);
+	gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (hbox), TRUE, TRUE, 2);
+	gtk_container_add (GTK_CONTAINER (item), vbox);
+	
+	egg_tool_item_set_expand (EGG_TOOL_ITEM (item), FALSE);
+	gtk_widget_show (control);
+	gtk_widget_show (hbox);
+	gtk_widget_show (vbox);
+
+	g_object_set_data (G_OBJECT (action), "control", control);
+
+	LOG ("Create zoom toolitem: Done.")
+
+	return item;
+}
+
+static void
+zoom_in_cb (EphyZoomControl *control,
+	    EphyZoomAction *action)
+{
+	LOG ("Zoom in")
+
+	g_signal_emit (action,
+		       ephy_zoom_action_signals[ZOOM_IN_SIGNAL],
+		       0);
+}
+
+static void
+zoom_out_cb (EphyZoomControl *control,
+	     EphyZoomAction *action)
+{
+	LOG ("Zoom out")
+
+	g_signal_emit (action,
+		       ephy_zoom_action_signals[ZOOM_OUT_SIGNAL],
+		       0);
+}
+
+static void
+zoom_to_level_cb (EphyZoomControl *control,
+		  float zoom,
+		  EphyZoomAction *action)
+{
+	LOG ("Zoom to level %f", zoom)
+
+	g_signal_emit (action,
+		       ephy_zoom_action_signals[ZOOM_TO_LEVEL_SIGNAL],
+		       0, zoom);
+}
+
+static void
+zoom_to_fit_cb (EphyZoomControl *control,
+		EphyZoomAction *action)
+{
+	LOG ("Zoom to fit")
+
+	g_signal_emit (action,
+		       ephy_zoom_action_signals[ZOOM_TO_FIT_SIGNAL],
+		       0);
+}
+
+static void
+connect_proxy (EggAction *action, GtkWidget *proxy)
+{
+	EphyZoomControl *control;
+
+	LOG ("Connect zoom proxy")
+
+	control = EPHY_ZOOM_CONTROL (g_object_get_data (G_OBJECT (action), "control"));
+
+	g_signal_connect (control, "zoom_in", GTK_SIGNAL_FUNC(zoom_in_cb), action);
+	g_signal_connect (control, "zoom_out", GTK_SIGNAL_FUNC(zoom_out_cb), action);
+	g_signal_connect (control, "zoom_to_level", GTK_SIGNAL_FUNC(zoom_to_level_cb), action);
+	g_signal_connect (control, "zoom_to_fit", GTK_SIGNAL_FUNC(zoom_to_fit_cb), action);
+
+	(* EGG_ACTION_CLASS (parent_class)->connect_proxy) (action, proxy);
+}
+
+static void
+ephy_zoom_action_class_init (EphyZoomActionClass *class)
+{
+	EggActionClass *action_class;
+	GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+	parent_class = g_type_class_peek_parent (class);
+	action_class = EGG_ACTION_CLASS (class);
+
+	action_class->toolbar_item_type = EPHY_TYPE_ZOOM_CONTROL;
+	action_class->create_tool_item = create_tool_item;
+	action_class->connect_proxy = connect_proxy;
+
+	ephy_zoom_action_signals[ZOOM_IN_SIGNAL] =
+		g_signal_new ("zoom_in",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_FIRST,
+			      G_STRUCT_OFFSET (EphyZoomActionClass, zoom_in),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE,
+			      0);
+	
+	ephy_zoom_action_signals[ZOOM_OUT_SIGNAL] =
+		g_signal_new ("zoom_out",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_FIRST,
+			      G_STRUCT_OFFSET (EphyZoomActionClass, zoom_out),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE,
+			      0);
+	
+	ephy_zoom_action_signals[ZOOM_TO_LEVEL_SIGNAL] =
+		g_signal_new ("zoom_to_level",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_FIRST,
+			      G_STRUCT_OFFSET (EphyZoomActionClass, zoom_to_level),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__FLOAT,
+			      G_TYPE_NONE,
+			      1,
+			      G_TYPE_FLOAT);
+	
+	ephy_zoom_action_signals[ZOOM_TO_FIT_SIGNAL] =
+		g_signal_new ("zoom_to_fit",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_FIRST,
+			      G_STRUCT_OFFSET (EphyZoomActionClass, zoom_to_fit),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE,
+			      0);
+	
+	ephy_zoom_get_factors (zoom_factors, zoom_factor_names);
+}
+
+static void
+ephy_zoom_action_init (EphyZoomAction *action)
+{
+}
+
+GtkWidget *
+ephy_zoom_action_get_widget (EphyZoomAction *action)
+{
+	return GTK_WIDGET (g_object_get_data (G_OBJECT (action), "control"));
+}
--- epiphany/src/toolbar.h	2003-04-25 17:23:07.000000000 +0200
+++ epiphany-build/src/toolbar.h	2003-04-26 11:53:41.000000000 +0200
@@ -21,6 +21,7 @@
 
 #include "egg-editable-toolbar.h"
 #include "ephy-window.h"
+#include "ephy-zoom.h"
 
 #include <glib-object.h>
 #include <glib.h>
@@ -73,6 +74,8 @@
 						 gboolean back,
 						 gboolean forward,
 						 gboolean up);
+void	      toolbar_update_zoom_control	(Toolbar *t,
+						 float zoom);
 
 void	      toolbar_set_visibility		(Toolbar *t,
 						 gboolean normal_toolbars,
--- epiphany/src/toolbar.c	2003-05-08 20:11:32.000000000 +0200
+++ epiphany-build/src/toolbar.c	2003-05-09 12:01:21.000000000 +0200
@@ -22,6 +22,7 @@
 #include "ephy-file-helpers.h"
 #include "ephy-shell.h"
 #include "ephy-location-entry.h"
+#include "ephy-zoom-control.h"
 #include "ephy-dnd.h"
 #include "ephy-spinner.h"
 #include "ephy-spinner-action.h"
@@ -31,6 +32,7 @@
 #include "ephy-go-action.h"
 #include "ephy-navigation-action.h"
 #include "ephy-bookmark-action.h"
+#include "ephy-zoom-action.h"
 #include "window-commands.h"
 #include "ephy-string.h"
 #include "ephy-debug.h"
@@ -79,6 +81,7 @@
 	GtkWidget *spinner;
 	GtkWidget *favicon;
 	GtkWidget *go;
+	GtkWidget *zoom_control;
 };
 
 GType
@@ -121,6 +124,30 @@
 	ephy_embed_load_url (embed, location);
 }
 
+static void
+zoom_in_cb (EggAction *action, EphyWindow *window)
+{
+	ephy_window_change_zoom (window, ZOOM_IN);	
+}
+
+static void
+zoom_out_cb (EggAction *action, EphyWindow *window)
+{
+	ephy_window_change_zoom (window, ZOOM_OUT);
+}
+
+static void
+zoom_to_level_cb (EggAction *action, float zoom, EphyWindow *window)
+{
+	ephy_window_set_zoom (window, zoom);
+}
+
+static void
+zoom_to_fit_cb (EggAction *action, EphyWindow *window)
+{
+	ephy_window_change_zoom (window, ZOOM_TO_FIT);
+}
+
 
 static EggAction *
 ensure_bookmark_action (Toolbar *t, EphyBookmarks *bookmarks, gulong id, const char *action_name)
@@ -297,6 +324,22 @@
 	egg_action_group_add_action (t->priv->action_group, action);
 	g_object_unref (action);
 
+	action = g_object_new (EPHY_TYPE_ZOOM_ACTION,
+			       "name", "Zoom",
+			       "label", _("Zoom"),
+			       "stock_id", EPHY_STOCK_ZOOM_CONTROL,
+			       NULL);
+	g_signal_connect (action, "zoom_in",
+			  G_CALLBACK (zoom_in_cb), t->priv->window);
+	g_signal_connect (action, "zoom_out",
+			  G_CALLBACK (zoom_out_cb), t->priv->window);
+	g_signal_connect (action, "zoom_to_level",
+			  G_CALLBACK (zoom_to_level_cb), t->priv->window);
+	g_signal_connect (action, "zoom_to_fit",
+			  G_CALLBACK (zoom_to_fit_cb), t->priv->window);
+	egg_action_group_add_action (t->priv->action_group, action);
+	g_object_unref (action);
+
 	action = g_object_new (EPHY_TYPE_FAVICON_ACTION,
 			       "name", "Favicon",
 			       "label", _("Favicon"),
@@ -728,3 +771,17 @@
 		}
 	}
 }
+
+void
+toolbar_update_zoom_control (Toolbar *t, float zoom)
+{
+	EggAction *action;
+	EphyZoomControl *control;
+
+	action = egg_action_group_get_action (t->priv->action_group, "Zoom");
+	control = EPHY_ZOOM_CONTROL(ephy_zoom_action_get_widget 
+				    (EPHY_ZOOM_ACTION (action)));
+	if (control == NULL) return; /* zoom control not present on toolbar */
+
+	ephy_zoom_control_set_zoom_level (control, zoom);
+}
--- epiphany/src/ephy-window.h	2003-05-06 13:59:08.000000000 +0200
+++ epiphany-build/src/ephy-window.h	2003-05-02 17:27:14.000000000 +0200
@@ -22,6 +22,7 @@
 #include "ephy-embed.h"
 #include "ephy-dialog.h"
 #include "ephy-notebook.h"
+#include "ephy-zoom.h"
 #include <glib-object.h>
 #include <glib.h>
 #include <gtk/gtkwindow.h>
@@ -109,7 +110,10 @@
 						   const char *url);
 
 void		  ephy_window_set_zoom		  (EphyWindow *window,
-						   gint zoom);
+						   float zoom);
+
+void		  ephy_window_change_zoom	  (EphyWindow *window,
+						   ZoomChangeFlags delta);
 
 void		  ephy_window_activate_location	  (EphyWindow *window);
 
--- epiphany/src/ephy-window.c	2003-05-08 20:11:32.000000000 +0200
+++ epiphany-build/src/ephy-window.c	2003-05-09 12:01:21.000000000 +0200
@@ -30,6 +30,7 @@
 #include "ephy-shell.h"
 #include "eel-gconf-extensions.h"
 #include "ephy-prefs.h"
+#include "ephy-zoom.h"
 #include "ephy-debug.h"
 #include "ephy-file-helpers.h"
 #include "statusbar.h"
@@ -496,8 +497,6 @@
 	g_object_set (action, "short_label", _("Print"), NULL);
 	action = egg_action_group_get_action (action_group, "FileBookmarkPage");
 	g_object_set (action, "short_label", _("Bookmark"), NULL);
-	action = egg_action_group_get_action (action_group, "ViewZoomNormal");
-	g_object_set (action, "sensitive", FALSE, NULL);
 
 	action_group = egg_action_group_new ("PopupsActions");
 	egg_action_group_add_actions (action_group, ephy_popups_entries,
@@ -1123,6 +1122,76 @@
 }
 
 static void
+update_zoom_control (EphyWindow *window)
+{
+	EphyEmbed *embed;
+	EggActionGroup *action_group;
+	EggAction *action;
+	gboolean can_zoom_in = TRUE, can_zoom_out = TRUE, can_zoom_normal = FALSE;
+	float zoom = 1.0;
+	gresult rv;
+
+	g_return_if_fail (window != NULL);
+
+	LOG ("update_zoom_control called")
+	
+	embed = ephy_window_get_active_embed (window);	
+	g_return_if_fail (embed != NULL);
+
+	rv = ephy_embed_zoom_get (embed, &zoom);
+	if (rv == G_OK)
+	{
+		if (zoom >= ZOOM_MAXIMAL) can_zoom_in = FALSE; 
+		if (zoom <= ZOOM_MINIMAL) can_zoom_out = FALSE; 
+		if (zoom != 1.0) can_zoom_normal = TRUE;
+	}
+
+	toolbar_update_zoom_control (window->priv->toolbar, zoom);
+
+	action_group = window->priv->action_group;
+	action = egg_action_group_get_action (action_group, "ViewZoomIn");
+	g_object_set (action, "sensitive", can_zoom_in, NULL);
+	action = egg_action_group_get_action (action_group, "ViewZoomOut");
+	g_object_set (action, "sensitive", can_zoom_out, NULL);
+	action = egg_action_group_get_action (action_group, "ViewZoomNormal");
+	g_object_set (action, "sensitive", can_zoom_normal, NULL);
+}
+
+void
+ephy_window_change_zoom (EphyWindow *window, ZoomChangeFlags delta)
+{
+	EphyEmbed *embed;
+	float new_zoom = 1.0, zoom = 1.0;
+
+	embed = ephy_window_get_active_embed (window);
+	g_assert (embed != NULL);
+
+	ephy_embed_zoom_get (embed, &zoom);
+
+	switch (delta)
+	{
+		case ZOOM_TO_DEFAULT:
+		case ZOOM_TO_FIT:	/* not implemented */
+			new_zoom = 1.0;
+			break;
+		case ZOOM_IN:
+			new_zoom = ephy_zoom_get_changed_factor (zoom, 1);
+			break;
+		case ZOOM_OUT:
+			new_zoom = ephy_zoom_get_changed_factor (zoom, -1);
+			break;
+		default:
+			g_assert_not_reached ();
+			break;
+	}
+
+	if (zoom != new_zoom)
+	{
+		ephy_window_set_zoom (window, new_zoom);
+	}
+}
+
+static void
 update_title_control (EphyWindow *window)
 {
 	EphyTab *tab;
@@ -1310,6 +1379,7 @@
 		 /* the zoom control is updated at the same time than the navigation
 		    controls. This keeps it synched most of the time, but not always,
 		    because we don't get a notification when zoom changes */
+		update_zoom_control (window);
 	case NavControl:
 		update_nav_control (window);
 		break;
@@ -1354,6 +1424,7 @@
 		update_find_control (window);
 		update_spinner_control (window);
 		update_tabs (window);
+		update_zoom_control (window);
 	}
 }
 
@@ -1495,27 +1566,38 @@
 
 void
 ephy_window_set_zoom (EphyWindow *window,
-		      gint zoom)
+		      float zoom)
 {
 	EphyEmbed *embed;
-	gboolean zoom_out, zoom_normal;
-	EggActionGroup *action_group;
-	EggAction *action;
+	
+	gresult rv = G_FAILED;
+	
 
         g_return_if_fail (IS_EPHY_WINDOW (window));
 
 	embed = ephy_window_get_active_embed (window);
-        g_return_if_fail (embed != NULL);
+	g_return_if_fail (embed != NULL);
 
-        ephy_embed_zoom_set (embed, zoom, TRUE);
+	LOG ("ephy_window_set_zoom %f", zoom)
 
-	zoom_normal = (zoom != 100);
-	zoom_out = (zoom > 0);
-	action_group = window->priv->action_group;
-	action = egg_action_group_get_action (action_group, "ViewZoomOut");
-	g_object_set (action, "sensitive", zoom_out, NULL);
-	action = egg_action_group_get_action (action_group, "ViewZoomNormal");
-	g_object_set (action, "sensitive", zoom_normal, NULL);
+	rv = ephy_embed_zoom_set (embed, zoom, TRUE);
+
+
+	
+	
+
+	
+		
+		
+			
+
+		
+
+		
+		
+
+		
+	
 }
 
 Toolbar *
--- epiphany/src/window-commands.c	2003-05-11 10:53:44.000000000 +0200
+++ epiphany-build/src/window-commands.c	2003-05-11 10:59:55.000000000 +0200
@@ -36,6 +36,7 @@
 #include "toolbar.h"
 #include "ephy-state.h"
 #include "ephy-gui.h"
+#include "ephy-zoom.h"
 
 #include <string.h>
 #include <libgnomevfs/gnome-vfs-uri.h>
@@ -564,38 +563,21 @@
 window_cmd_view_zoom_in	(EggAction *action,
 			 EphyWindow *window)
 {
-	EphyEmbed *embed;
-	int zoom;
-
-	embed = ephy_window_get_active_embed (window);
-	g_return_if_fail (embed != NULL);
-
-	ephy_embed_zoom_get (embed, &zoom);
-	ephy_window_set_zoom (window, zoom + 10);
+	ephy_window_change_zoom (window, ZOOM_IN);
 }
 
 void
 window_cmd_view_zoom_out (EggAction *action,
 			  EphyWindow *window)
 {
-	EphyEmbed *embed;
-	int zoom;
-
-	embed = ephy_window_get_active_embed (window);
-	g_return_if_fail (embed != NULL);
-
-	ephy_embed_zoom_get (embed, &zoom);
-	if (zoom >= 10)
-	{
-		ephy_window_set_zoom (window, zoom - 10);
-	}
+	ephy_window_change_zoom (window, ZOOM_OUT);
 }
 
 void
 window_cmd_view_zoom_normal (EggAction *action,
 			     EphyWindow *window)
 {
-	ephy_window_set_zoom (window, 100);
+	ephy_window_change_zoom (window, ZOOM_TO_DEFAULT);
 }
 
 void
@@ -643,7 +625,12 @@
 toolbar_editor_destroy_cb (GtkWidget *tbe,
 			   Toolbar *t)
 {
+	GtkWidget *window;
+
+	window = gtk_widget_get_toplevel (GTK_WIDGET (t));
+
 	egg_editable_toolbar_set_edit_mode (EGG_EDITABLE_TOOLBAR (t), FALSE);
+	ephy_window_update_all_controls (EPHY_WINDOW (window));
 }
 
 static void
