diff --git a/src/dialogs/wbcg.ui b/src/dialogs/wbcg.ui
index d6b17d5..376cb5b 100644
--- a/src/dialogs/wbcg.ui
+++ b/src/dialogs/wbcg.ui
@@ -241,26 +241,106 @@
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <child>
-                  <object class="GtkLabel" id="bnotebook_placeholder">
+                  <object class="GtkBox" id="box1">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
+                    <property name="halign">start</property>
+                    <child>
+                      <object class="GtkButton" id="prev_sheet_button">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <property name="halign">center</property>
+                        <property name="valign">center</property>
+                        <property name="focus_on_click">False</property>
+                        <child>
+                          <object class="GtkArrow" id="prev_sheet_arrow">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="halign">center</property>
+                            <property name="valign">center</property>
+                            <property name="arrow_type">left</property>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkBox" id="bnotebook-placeholder">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="orientation">vertical</property>
+                        <child>
+                          <placeholder/>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="next_sheet_button">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <property name="halign">center</property>
+                        <property name="valign">center</property>
+                        <property name="focus_on_click">False</property>
+                        <child>
+                          <object class="GtkArrow" id="next_sheet_arrow">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="halign">center</property>
+                            <property name="valign">center</property>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="add_sheet_button">
+                        <property name="label" translatable="yes">+</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <property name="halign">center</property>
+                        <property name="valign">center</property>
+                        <property name="focus_on_click">False</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">3</property>
+                      </packing>
+                    </child>
                   </object>
                   <packing>
-                    <property name="resize">False</property>
-                    <property name="shrink">True</property>
+                    <property name="resize">True</property>
+                    <property name="shrink">False</property>
                   </packing>
                 </child>
                 <child>
                   <object class="GtkProgressBar" id="progress_bar">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
+                    <property name="hexpand">True</property>
                     <property name="text" translatable="yes"> </property>
                     <property name="show_text">True</property>
                     <property name="ellipsize">end</property>
                   </object>
                   <packing>
-                    <property name="resize">False</property>
-                    <property name="shrink">True</property>
+                    <property name="resize">True</property>
+                    <property name="shrink">False</property>
                   </packing>
                 </child>
               </object>
diff --git a/src/gnm-marshalers.list b/src/gnm-marshalers.list
index 52c2879..f8b4f78 100644
--- a/src/gnm-marshalers.list
+++ b/src/gnm-marshalers.list
@@ -23,3 +23,4 @@
 BOOLEAN:POINTER
 BOOLEAN:OBJECT,POINTER
 VOID:BOOLEAN,INT
+VOID:OBJECT,UINT
diff --git a/src/gnumeric.css b/src/gnumeric.css
index 6d48df4..e1911dd 100644
--- a/src/gnumeric.css
+++ b/src/gnumeric.css
@@ -195,3 +195,27 @@ GtkArrow.auto-filter:active {
 }
 
 /* ------------------------------------------------------------------------- */
+
+GtkButton.sheet-move {
+  padding: 0;
+  margin: 0;
+}
+
+GtkButton.sheet-add {
+  padding: 0;
+  margin: 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+GnmNotebookButton {
+  padding-left: 10px;
+  padding-right: 10px;
+  border-width: 0;
+  -GnmNotebookButton-outline-width: 2px;
+}
+
+GnmNotebookButton:active {
+  background-image: none;
+  background-color: white;
+}
diff --git a/src/sheet-control-gui.c b/src/sheet-control-gui.c
index 2bc9c01..10e5a20 100644
--- a/src/sheet-control-gui.c
+++ b/src/sheet-control-gui.c
@@ -62,7 +62,6 @@
 #include "item-bar.h"
 #include "item-cursor.h"
 #include "widgets/gnumeric-expr-entry.h"
-#include "widgets/widget-editable-label.h"
 #include "gnm-sheet-slicer.h"
 
 #include <go-data-slicer-field.h>
@@ -1711,14 +1710,18 @@ sheet_control_gui_new (SheetView *sv, WBCGtk *wbcg)
 		}
 	}
 
-	scg->label = editable_label_new
-		(sheet->name_unquoted,
-		 sheet->tab_color
-		 ? go_color_to_gdk_rgba (sheet->tab_color->go_color, &cback)
-		 : NULL,
-		 sheet->tab_text_color
-		 ? go_color_to_gdk_rgba (sheet->tab_text_color->go_color, &cfore)
-		 : NULL);
+	scg->label = g_object_new
+		(GNM_NOTEBOOK_BUTTON_TYPE,
+		 "label", sheet->name_unquoted,
+		 "background-color",
+		 (sheet->tab_color
+		  ? go_color_to_gdk_rgba (sheet->tab_color->go_color, &cback)
+		  : NULL),
+		 "text-color",
+		 (sheet->tab_text_color
+		  ? go_color_to_gdk_rgba (sheet->tab_text_color->go_color, &cfore)
+		  : NULL),
+		 NULL);
 	g_object_ref (scg->label);
 
 	return scg;
diff --git a/src/wbc-gtk-actions.c b/src/wbc-gtk-actions.c
index 20af87c..f9e94d9 100644
--- a/src/wbc-gtk-actions.c
+++ b/src/wbc-gtk-actions.c
@@ -70,7 +70,6 @@
 #include <goffice/goffice.h>
 #include <goffice/component/goffice-component.h>
 
-#include "widgets/widget-editable-label.h"
 #include <gtk/gtk.h>
 #include <glib/gi18n-lib.h>
 #include <gsf/gsf-input.h>
@@ -919,7 +918,9 @@ static GNM_ACTION_DEF (cb_insert_comment)
 static GNM_ACTION_DEF (cb_sheet_name)
 {
 	SheetControlGUI *scg = wbcg_cur_scg(wbcg);
+#if 0
 	editable_label_start_editing (EDITABLE_LABEL(scg->label));
+#endif
 }
 
 static GNM_ACTION_DEF (cb_sheet_order)		{ dialog_sheet_order (wbcg); }
diff --git a/src/wbc-gtk-impl.h b/src/wbc-gtk-impl.h
index 1eb748d..c2fa678 100644
--- a/src/wbc-gtk-impl.h
+++ b/src/wbc-gtk-impl.h
@@ -33,6 +33,9 @@ struct _WBCGtk {
 	/* The GtkPaned that contains the sheet tabs and the status area.  */
 	GtkPaned    *tabs_paned;
 
+	GtkWidget *prev_sheet_button, *next_sheet_button;
+	GtkWidget *add_sheet_button;
+
 	GtkWidget   *progress_bar;
 
 	struct {
diff --git a/src/wbc-gtk.c b/src/wbc-gtk.c
index 185366f..398a9b3 100644
--- a/src/wbc-gtk.c
+++ b/src/wbc-gtk.c
@@ -49,7 +49,6 @@
 #include "style-border.h"
 #include "gnumeric-conf.h"
 #include "dialogs/dialogs.h"
-#include "widgets/widget-editable-label.h"
 #include "widgets/gnm-fontbutton.h"
 #include "gui-clipboard.h"
 #include "libgnumeric.h"
@@ -382,8 +381,9 @@ wbcg_update_action_sensitivity (WorkbookControl *wbc)
 		for (i = 0; i < N; i++) {
 			GtkWidget *label =
 				gnm_notebook_get_nth_label (wbcg->bnotebook, i);
-			editable_label_set_editable (EDITABLE_LABEL (label),
-						     enable_actions);
+			g_object_set_data (G_OBJECT (label),
+					   "editable",
+					   GINT_TO_POINTER (enable_actions));
 		}
 	}
 
@@ -399,7 +399,7 @@ wbcg_update_action_sensitivity (WorkbookControl *wbc)
 			"sensitive", FALSE,
 			NULL);
 		g_object_set (G_OBJECT (wbcg->semi_permanent_actions),
-			"sensitive",TRUE,
+			"sensitive", TRUE,
 			NULL);
 		gtk_widget_set_sensitive (GTK_WIDGET (wbcg->edit_line.entry), FALSE);
 		gtk_widget_set_sensitive (GTK_WIDGET (wbcg->selection_descriptor), FALSE);
@@ -415,6 +415,7 @@ wbcg_update_action_sensitivity (WorkbookControl *wbc)
 	}
 }
 
+#if 0
 static gboolean
 cb_sheet_label_edit_finished (EditableLabel *el, char const *new_name,
 			      WBCGtk *wbcg)
@@ -431,6 +432,7 @@ cb_sheet_label_edit_finished (EditableLabel *el, char const *new_name,
 	wbcg_focus_cur_scg (wbcg);
 	return reject;
 }
+#endif
 
 void
 wbcg_insert_sheet (GtkWidget *unused, WBCGtk *wbcg)
@@ -490,7 +492,11 @@ static void cb_sheets_manage (SheetControlGUI *scg) { dialog_sheet_order (scg->w
 static void cb_sheets_insert (SheetControlGUI *scg) { wbcg_insert_sheet (NULL, scg->wbcg); }
 static void cb_sheets_add    (SheetControlGUI *scg) { wbcg_append_sheet (NULL, scg->wbcg); }
 static void cb_sheets_clone  (SheetControlGUI *scg) { wbcg_clone_sheet  (NULL, scg->wbcg); }
-static void cb_sheets_rename (SheetControlGUI *scg) { editable_label_start_editing (EDITABLE_LABEL(scg->label)); }
+static void cb_sheets_rename (SheetControlGUI *scg) {
+#if 0
+	editable_label_start_editing (EDITABLE_LABEL(scg->label));
+#endif
+}
 static void cb_sheets_resize (SheetControlGUI *scg) { dialog_sheet_resize (scg->wbcg); }
 
 
@@ -586,7 +592,7 @@ sheet_menu_label_run (SheetControlGUI *scg, GdkEventButton *event)
 /**
  * cb_sheet_label_button_press:
  *
- * Invoked when the user has clicked on the EditableLabel widget.
+ * Invoked when the user has clicked on the sheet name widget.
  * This takes care of switching to the notebook that contains the label
  */
 static gboolean
@@ -609,7 +615,7 @@ cb_sheet_label_button_press (GtkWidget *widget, GdkEventButton *event,
 	if (event->button == 3) {
 		if ((scg_wbcg (scg))->edit_line.guru == NULL)
 			scg_object_unselect (scg, NULL);
-		if (editable_label_get_editable (EDITABLE_LABEL (widget))) {
+		if (g_object_get_data (G_OBJECT (widget), "editable")) {
 			sheet_menu_label_run (scg, event);
 			scg_take_focus (scg);
 			return TRUE;
@@ -963,11 +969,9 @@ static void
 wbc_gtk_create_notebook_area (WBCGtk *wbcg)
 {
 	GtkWidget *placeholder;
+	GtkStyleContext *context;
 
-	wbcg->bnotebook = g_object_new (GNM_NOTEBOOK_TYPE,
-					"tab-pos", GTK_POS_BOTTOM,
-					"show-border", FALSE,
-					NULL);
+	wbcg->bnotebook = g_object_new (GNM_NOTEBOOK_TYPE, NULL);
 	g_object_ref (wbcg->bnotebook);
 
 	g_signal_connect_after (G_OBJECT (wbcg->bnotebook),
@@ -976,10 +980,32 @@ wbc_gtk_create_notebook_area (WBCGtk *wbcg)
 	g_signal_connect (G_OBJECT (wbcg->bnotebook),
 			  "button-press-event", G_CALLBACK (cb_bnotebook_button_press),
 			  NULL);
-	placeholder = gtk_paned_get_child1 (wbcg->tabs_paned);
-	if (placeholder)
-		gtk_widget_destroy (placeholder);
-	gtk_paned_pack1 (wbcg->tabs_paned, GTK_WIDGET (wbcg->bnotebook), FALSE, TRUE);
+
+	placeholder = GET_GUI_ITEM ("bnotebook-placeholder");
+	go_gtk_widget_replace (placeholder, GTK_WIDGET (wbcg->bnotebook));
+
+	context = gtk_widget_get_style_context (wbcg->next_sheet_button);
+	gtk_style_context_add_class (context, "sheet-move");
+	gtk_style_context_add_class (context, "next");
+	g_signal_connect_swapped (wbcg->next_sheet_button,
+				  "clicked",
+				  G_CALLBACK (gnm_notebook_next_page),
+				  wbcg->bnotebook);
+
+	context = gtk_widget_get_style_context (wbcg->prev_sheet_button);
+	gtk_style_context_add_class (context, "sheet-move");
+	gtk_style_context_add_class (context, "previous");
+	g_signal_connect_swapped (wbcg->prev_sheet_button,
+				  "clicked",
+				  G_CALLBACK (gnm_notebook_prev_page),
+				  wbcg->bnotebook);
+
+	context = gtk_widget_get_style_context (wbcg->add_sheet_button);
+	gtk_style_context_add_class (context, "sheet-add");
+	g_signal_connect (wbcg->add_sheet_button,
+			  "clicked",
+			  G_CALLBACK (wbcg_append_sheet),
+			  wbcg);
 
 	gtk_widget_show_all (GTK_WIDGET (wbcg->tabs_paned));
 }
@@ -998,22 +1024,27 @@ wbcg_menu_state_sheet_count (WBCGtk *wbcg)
 static void
 cb_sheet_tab_change (Sheet *sheet,
 		     G_GNUC_UNUSED GParamSpec *pspec,
-		     EditableLabel *el)
+		     GtkWidget *label)
 {
 	GdkRGBA cfore, cback;
-	SheetControlGUI *scg = get_scg (GTK_WIDGET (el));
+	SheetControlGUI *scg = get_scg (label);
 
 	g_return_if_fail (IS_SHEET_CONTROL_GUI (scg));
 
 	/* We're lazy and just set all relevant attributes.  */
-	editable_label_set_text (el, sheet->name_unquoted);
-	editable_label_set_color (el,
-				  sheet->tab_color
-				  ? go_color_to_gdk_rgba (sheet->tab_color->go_color, &cback)
-				  : NULL,
-				  sheet->tab_text_color
-				  ? go_color_to_gdk_rgba (sheet->tab_text_color->go_color, &cfore)
-				  : NULL);
+	g_object_set (label,
+		      "label", sheet->name_unquoted,
+		      "background-color",
+		      (sheet->tab_color
+		       ? go_color_to_gdk_rgba (sheet->tab_color->go_color,
+					       &cback)
+		       : NULL),
+		      "text-color",
+		      (sheet->tab_text_color
+		       ? go_color_to_gdk_rgba (sheet->tab_text_color->go_color,
+					       &cfore)
+		       : NULL),
+		      NULL);
 }
 
 static void
@@ -1106,9 +1137,11 @@ wbcg_sheet_add (WorkbookControl *wbc, SheetView *sv)
 	g_object_set_data (G_OBJECT (scg->grid), SHEET_CONTROL_KEY, scg);
 
 	g_object_set_data (G_OBJECT (scg->label), SHEET_CONTROL_KEY, scg);
+#if 0
 	g_signal_connect_after (G_OBJECT (scg->label),
 				"edit_finished",
 				G_CALLBACK (cb_sheet_label_edit_finished), wbcg);
+#endif
 
 	/* do not preempt the editable label handler */
 	g_signal_connect_after (G_OBJECT (scg->label),
@@ -2576,7 +2609,7 @@ cb_wbcg_drag_motion (GtkWidget *widget, GdkDragContext *context,
 {
 	GtkWidget *source_widget = gtk_drag_get_source_widget (context);
 
-	if (IS_EDITABLE_LABEL (source_widget)) {
+	if (IS_GNM_NOTEBOOK_BUTTON (source_widget)) {
 		/* The user wants to reorder sheets. We simulate a
 		 * drag motion over a label.
 		 */
@@ -2598,7 +2631,7 @@ cb_wbcg_drag_leave (GtkWidget *widget, GdkDragContext *context,
 
 	g_return_if_fail (IS_WBC_GTK (wbcg));
 
-	if (IS_EDITABLE_LABEL (source_widget))
+	if (IS_GNM_NOTEBOOK_BUTTON (source_widget))
 		gtk_widget_hide (
 			g_object_get_data (G_OBJECT (source_widget), "arrow"));
 	else if (wbcg_is_local_drag (wbcg, source_widget))
@@ -5543,6 +5576,9 @@ wbc_gtk_init (GObject *obj)
 	wbcg->auto_expr_label = GET_GUI_ITEM ("auto_expr_label");
 	wbcg->status_text = GET_GUI_ITEM ("status_text");
 	wbcg->tabs_paned = GET_GUI_ITEM ("tabs_paned");
+	wbcg->prev_sheet_button = GET_GUI_ITEM ("prev_sheet_button");
+	wbcg->next_sheet_button = GET_GUI_ITEM ("next_sheet_button");
+	wbcg->add_sheet_button = GET_GUI_ITEM ("add_sheet_button");
 	wbcg->status_area = GET_GUI_ITEM ("status_area");
 	wbcg->notebook_area = GET_GUI_ITEM ("notebook_area");
 	wbcg->snotebook = GET_GUI_ITEM ("snotebook");
diff --git a/src/widgets/gnm-notebook.c b/src/widgets/gnm-notebook.c
index 485bac6..aea0b24 100644
--- a/src/widgets/gnm-notebook.c
+++ b/src/widgets/gnm-notebook.c
@@ -1,8 +1,7 @@
-/**
+/*
  * gnm-notebook.c: Implements a button-only notebook.
  *
- * Copyright (c) 2008 Morten Welinder <terra@gnome.org>
- * Copyright notices for included gtknotebook.c, see below.
+ * Copyright (c) 2008,2013 Morten Welinder <terra@gnome.org>
  *
  * 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
@@ -17,159 +16,657 @@
  * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- **/
+ */
 
 #include <gnumeric-config.h>
 #include "gnm-notebook.h"
+#include "gnm-marshalers.h"
+#include <goffice/goffice.h>
+#include <gnm-i18n.h>
 #include <gsf/gsf-impl-utils.h>
 
+/* -------------------------------------------------------------------------- */
+
+typedef struct {
+	GtkLabel base;
+	GdkRGBA *fg, *bg;
+} GnmNotebookButton;
+
+typedef struct {
+	GtkLabelClass parent_class;
+} GnmNotebookButtonClass;
+
+static GObjectClass *gnm_notebook_button_parent_class;
+
+enum {
+	NBB_PROP_0,
+	NBB_PROP_BACKGROUND_COLOR,
+	NBB_PROP_TEXT_COLOR
+};
+
+static void
+gnm_notebook_button_finalize (GObject *obj)
+{
+	GnmNotebookButton *nbb = GNM_NOTEBOOK_BUTTON (obj);
+	gdk_rgba_free (nbb->fg);
+	gdk_rgba_free (nbb->bg);
+	gnm_notebook_button_parent_class->finalize (obj);
+}
+
+static void 
+gnm_notebook_button_set_property (GObject      *obj,
+				  guint         prop_id,
+				  const GValue *value,
+				  GParamSpec   *pspec)
+{
+	GnmNotebookButton *nbb = GNM_NOTEBOOK_BUTTON (obj);
+
+	switch (prop_id) {
+	case NBB_PROP_BACKGROUND_COLOR:
+		gdk_rgba_free (nbb->bg);
+		nbb->bg = g_value_dup_boxed (value);
+		gtk_widget_override_background_color (GTK_WIDGET (obj),
+						      GTK_STATE_FLAG_NORMAL,
+						      nbb->bg);
+		gtk_widget_override_background_color (GTK_WIDGET (obj),
+						      GTK_STATE_FLAG_ACTIVE,
+						      nbb->bg);
+		break;
+	case NBB_PROP_TEXT_COLOR:
+		gdk_rgba_free (nbb->fg);
+		nbb->fg = g_value_dup_boxed (value);
+		gtk_widget_override_color (GTK_WIDGET (obj),
+					   GTK_STATE_FLAG_NORMAL,
+					   nbb->fg);
+		gtk_widget_override_color (GTK_WIDGET (obj),
+					   GTK_STATE_FLAG_ACTIVE,
+					   nbb->fg);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+		break;
+	}
+}
+
+static gboolean
+gnm_notebook_button_draw (GtkWidget *widget, cairo_t *cr)
+{
+	GtkStyleContext *context;
+	gboolean res;
+	GtkAllocation alloc;
+	GtkBorder padding;
+	GtkStateFlags state = GTK_STATE_FLAG_NORMAL;
+	GtkBorder border;
+	GdkRGBA border_color;
+	GnmNotebook *nb = GNM_NOTEBOOK (gtk_widget_get_parent (widget));
+	int line_width;
+
+	if (widget == gnm_notebook_get_current_label (nb))
+		state |= GTK_STATE_FLAG_ACTIVE;
+
+	context = gtk_widget_get_style_context (widget);
+	gtk_style_context_save (context);
+	gtk_style_context_set_state (context, state);
+	gtk_style_context_get_padding (context, state, &padding);
+	gtk_style_context_get_border (context, state, &border);
+	gtk_style_context_get_border_color (context, state, &border_color);
+	gtk_widget_style_get (widget, "outline-width", &line_width, NULL);
+
+	gtk_widget_get_allocation (widget, &alloc);
+	g_printerr ("Drawing notebook button at (%d,%d) size %dx%d  state %x\n",
+		    alloc.x, alloc.y,
+		    alloc.width, alloc.height,
+		    state);
+
+	cairo_move_to (cr, 0, 0);
+	cairo_line_to (cr, alloc.width, 0);
+	cairo_line_to (cr, alloc.width - padding.right, alloc.height);
+	cairo_line_to (cr, padding.left, alloc.height);
+	cairo_close_path (cr);
+	cairo_clip (cr);
+	gtk_render_background (context, cr, alloc.x, alloc.y, alloc.width, alloc.height);
+
+	cairo_save (cr);
+	res = GTK_WIDGET_CLASS(gnm_notebook_button_parent_class)
+		->draw (widget, cr);
+	cairo_restore (cr);
+
+	gdk_cairo_set_source_rgba (cr, &border_color);
+	cairo_set_line_width (cr, line_width);
+
+	cairo_move_to (cr, alloc.width, 0);
+	cairo_line_to (cr, alloc.width - padding.right, alloc.height);
+	cairo_line_to (cr, padding.left, alloc.height);
+	cairo_line_to (cr, 0, 0);
+	cairo_stroke (cr);
+
+	gtk_style_context_restore (context);
+
+	return res;
+}
+
+static void
+gnm_notebook_button_class_init (GObjectClass *klass)
+{
+	GtkWidgetClass *wclass = (GtkWidgetClass *)klass;
+
+	gnm_notebook_button_parent_class = g_type_class_peek_parent (klass);
+	klass->finalize = gnm_notebook_button_finalize;
+	klass->set_property = gnm_notebook_button_set_property;
+
+	g_object_class_install_property
+		(klass,
+		 NBB_PROP_BACKGROUND_COLOR,
+		 g_param_spec_boxed ("background-color",
+				     P_("Background Color"),
+				     P_("Override color to use for background"),
+				     GDK_TYPE_RGBA,
+				     G_PARAM_WRITABLE));
+	g_object_class_install_property
+		(klass,
+		 NBB_PROP_TEXT_COLOR,
+		 g_param_spec_boxed ("text-color",
+				     P_("Text Color"),
+				     P_("Override color to use for label"),
+				     GDK_TYPE_RGBA,
+				     G_PARAM_WRITABLE));
+
+	wclass->draw = gnm_notebook_button_draw;
+	gtk_widget_class_install_style_property
+		(wclass,
+		 g_param_spec_int ("outline-width",
+				   P_("Outline Width"),
+				   P_("Width of outline of sheet name button"),
+				   0,
+				   G_MAXINT,
+				   1,
+				   G_PARAM_READABLE));
+}
+
+static void
+gnm_notebook_button_init (GnmNotebookButton *nbb)
+{
+	GtkStyleContext *context = gtk_widget_get_style_context (GTK_WIDGET (nbb));
+	gtk_style_context_add_class (context, GTK_STYLE_CLASS_BUTTON);
+}
+
+GSF_CLASS (GnmNotebookButton, gnm_notebook_button,
+	   gnm_notebook_button_class_init,
+	   gnm_notebook_button_init, GTK_TYPE_LABEL)
+#if 0
+	;
+#endif
+
+/* -------------------------------------------------------------------------- */
+
 struct _GnmNotebook {
-	GtkNotebook parent;
+	GtkContainer parent;
+	GPtrArray *children;
 
-	/*
-	 * This is the number of pixels from a regular notebook that
-	 * we are not drawing.  It is caused by the empty widgets
-	 * that we have to use.
-	 */
-	int dummy_height;
+	/* Currently active page or -1 if none.  */
+	int current;
+
+	/* Stuff set by inspect.  */
+	int first_visible, last_visible;
+	int prev_visible, next_visible;
+	int n_visible;
+
+	int first_shown, last_shown;
 };
 
 typedef struct {
-	GtkNotebookClass parent_class;
+	GtkContainerClass parent_class;
+
+	void (* switch_page)       (GnmNotebook     *notebook,
+				    GtkWidget       *page,
+				    guint            page_num);
 } GnmNotebookClass;
 
-static GtkNotebookClass *gnm_notebook_parent_class;
+static GObjectClass *gnm_notebook_parent_class;
+
+enum {
+  SWITCH_PAGE,
+  LAST_SIGNAL
+};
+static guint notebook_signals[LAST_SIGNAL] = { 0 };
+
+static void
+gnm_notebook_finalize (GObject *obj)
+{
+	GnmNotebook *nb = GNM_NOTEBOOK (obj);
+	g_ptr_array_free (nb->children, TRUE);
+	gnm_notebook_parent_class->finalize (obj);
+}
+
+static void
+gnm_notebook_inspect (GnmNotebook *nb)
+{
+	unsigned ui;
+
+	nb->first_visible = nb->last_visible = -1;
+	nb->prev_visible = nb->next_visible = -1;
+	nb->n_visible = 0;
+
+	for (ui = 0; ui < nb->children->len; ui++) {
+		GtkWidget *child = g_ptr_array_index (nb->children, ui);
+		if (gtk_widget_get_visible (child)) {
+			nb->n_visible++;
+			if (nb->first_visible == -1)
+				nb->first_visible = ui;
+			nb->last_visible = ui;
+			if ((int)ui < nb->current)
+				nb->prev_visible = ui;
+			if ((int)ui > nb->current && nb->next_visible == -1)
+				nb->next_visible = ui;
+		}
+	}
+}
+
 
-#define DUMMY_KEY "GNM-NOTEBOOK-DUMMY-WIDGET"
+static void
+gnm_notebook_add (GtkContainer *container, GtkWidget *widget)
+{
+	GnmNotebook *nb = GNM_NOTEBOOK (container);
+	gnm_notebook_insert_tab (nb, widget, -1);
+}
+
+static void
+gnm_notebook_remove (GtkContainer *container, GtkWidget *widget)
+{
+	GnmNotebook *nb = GNM_NOTEBOOK (container);
+	gboolean was_visible = gtk_widget_get_visible (widget);
+	unsigned ui;
+
+	for (ui = 0; ui < nb->children->len; ui++) {
+		GtkWidget *child = g_ptr_array_index (nb->children, ui);
+		if (child == widget) {
+			gboolean is_current = (nb->current == (int)ui);
+			g_ptr_array_remove_index (nb->children, ui);
+			if (nb->current >= (int)ui)
+				nb->current--;
+			gtk_widget_unparent (widget);
+			if (was_visible)
+				gtk_widget_queue_resize (GTK_WIDGET (nb));
+			if (is_current) {
+				gnm_notebook_inspect (nb);
+				if (nb->n_visible == 0) {
+					nb->current = -1;
+					g_signal_emit (nb, notebook_signals[SWITCH_PAGE],
+						       0, NULL, -1);
+				} else
+					gnm_notebook_next_page (nb);
+			}
+			return;
+		}
+	}
+}
+
+static void
+gnm_notebook_forall (GtkContainer *container,
+		     G_GNUC_UNUSED gboolean include_internals,
+		     GtkCallback   callback,
+		     gpointer      callback_data)
+{
+	GnmNotebook *nb = GNM_NOTEBOOK (container);
+	unsigned ui;
+
+	for (ui = 0; ui < nb->children->len; ui++) {
+		GtkWidget *child = g_ptr_array_index (nb->children, ui);
+		callback (child, callback_data);
+	}
+}
+
+static void
+gnm_notebook_get_preferred_height (GtkWidget *widget,
+				   gint      *minimum,
+				   gint      *natural)
+{
+	GnmNotebook *nb = GNM_NOTEBOOK (widget);
+	unsigned ui;
+
+	*minimum = 0;
+	for (ui = 0; ui < nb->children->len; ui++) {
+		GtkWidget *child = g_ptr_array_index (nb->children, ui);
+		gint child_minimum, child_natural;
+
+		if (!gtk_widget_get_visible (child))
+			continue;
+		gtk_widget_get_preferred_height (child,
+						 &child_minimum,
+						 &child_natural);
+		*minimum = MAX (*minimum, child_natural);
+	}
+	*natural = *minimum;
+}
+
+static void
+gnm_notebook_get_preferred_width (GtkWidget *widget,
+				  gint      *minimum,
+				  gint      *natural)
+{
+	GnmNotebook *nb = GNM_NOTEBOOK (widget);
+	unsigned ui;
+	gboolean first_visible = TRUE;
+
+	*natural = 0;
+	*minimum = *natural;
+	for (ui = 0; ui < nb->children->len; ui++) {
+		GtkWidget *child = g_ptr_array_index (nb->children, ui);
+		gint child_minimum, child_natural;
+		GtkBorder child_padding;
+		GtkStateFlags state = GTK_STATE_FLAG_NORMAL;
+
+		if (!gtk_widget_get_visible (child))
+			continue;
+		gtk_widget_get_preferred_width (child,
+						&child_minimum,
+						&child_natural);
+
+		if (!first_visible) {
+			int overlap;
+			gtk_style_context_get_padding (gtk_widget_get_style_context (child),
+						       state,
+						       &child_padding);
+			overlap = child_padding.left + child_padding.right / 2;
+			child_natural -= overlap;
+			child_minimum -= overlap;
+		}
+		first_visible = FALSE;
+
+		*natural += child_natural;
+		*minimum += child_minimum;
+	}
+
+	g_printerr ("width: %d - %d\n", *minimum, *natural);
+}
+
+static void
+gnm_notebook_realize (GtkWidget *widget)
+{
+	GtkAllocation allocation;
+	GdkWindow *window;
+	GdkWindowAttr attributes;
+	gint attributes_mask;
+
+	gtk_widget_set_realized (widget, TRUE);
+
+	gtk_widget_get_allocation (widget, &allocation);
+
+	attributes.window_type = GDK_WINDOW_CHILD;
+	attributes.x = allocation.x;
+	attributes.y = allocation.y;
+	attributes.width = allocation.width;
+	attributes.height = allocation.height;
+	attributes.wclass = GDK_INPUT_OUTPUT;
+	attributes.visual = gtk_widget_get_visual (widget);
+	attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
+	attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
+  
+	window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
+	gtk_widget_set_window (widget, window);
+#if 1
+	gdk_window_set_user_data (window, widget);
+#else
+	gtk_widget_register_window (widget, window);
+
+#endif
+	gdk_window_set_background_pattern (window, NULL);
+}
 
 static void
 gnm_notebook_size_allocate (GtkWidget     *widget,
 			    GtkAllocation *allocation)
 {
-	int i, h = 0;
-	GnmNotebook *gnb = (GnmNotebook *)widget;
-	GtkAllocation alc = *allocation;
+	GnmNotebook *nb = GNM_NOTEBOOK (widget);
+	unsigned ui;
+	GtkRequestedSize *sizes;
+	int x, width;
+	gboolean first_visible = TRUE;
+
+	gtk_widget_set_allocation (widget, allocation);
+	g_printerr ("Allocated notebook at (%d,%d) size %dx%d\n",
+		    allocation->x, allocation->y,
+		    allocation->width, allocation->height);
+	if (gtk_widget_get_realized (widget)) {
+		gdk_window_move_resize (gtk_widget_get_window (widget),
+					allocation->x, allocation->y,
+					allocation->width, allocation->height);
+	}
+
+	sizes = g_new (GtkRequestedSize, nb->children->len);
+	for (ui = 0; ui < nb->children->len; ui++) {
+		GtkWidget *child = g_ptr_array_index (nb->children, ui);
+
+		if (gtk_widget_get_visible (child))
+			gtk_widget_get_preferred_width
+				(child,
+				 &sizes[ui].minimum_size,
+				 &sizes[ui].natural_size);
+		else
+			sizes[ui].natural_size = sizes[ui].minimum_size = 0;
+	}
 
-	for (i = 0; TRUE; i++) {
-		GtkWidget *page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (widget), i);
-		GtkAllocation a;
-		if (!page)
-			break;
-		if (!gtk_widget_get_visible (page))
+	x = 0;
+	width = allocation->width;
+	for (ui = 0; ui < nb->children->len; ui++) {
+		GtkWidget *child = g_ptr_array_index (nb->children, ui);
+		GtkAllocation child_allocation = *allocation;
+		int width1;
+		GtkStateFlags state = GTK_STATE_FLAG_NORMAL;
+
+		if (sizes[ui].natural_size <= 0)
 			continue;
-		gtk_widget_get_allocation (page, &a);
-		h = MAX (h, a.height);
+
+		if (!first_visible) {
+			GtkBorder child_padding;
+			gtk_style_context_get_padding (gtk_widget_get_style_context (child),
+						       state,
+						       &child_padding);
+			x -= child_padding.left + child_padding.right / 2;
+		}
+		first_visible = FALSE;
+
+		width1 = sizes[ui].natural_size;
+
+		child_allocation.x = x;
+		child_allocation.width = width1;
+		g_printerr ("Allocated child %d at (%d,%d) size %dx%d\n",
+			    ui, child_allocation.x, child_allocation.y,
+			    child_allocation.width, child_allocation.height);
+
+		gtk_widget_size_allocate (child, &child_allocation);
+
+		x += width1;
+		width -= width1;
 	}
 
-	gnb->dummy_height = h;
+	g_free (sizes);
+}
 
-	alc.y -= h;
-	((GtkWidgetClass *)gnm_notebook_parent_class)->size_allocate
-		(widget, &alc);
+static gboolean
+gnm_notebook_draw (GtkWidget *widget, cairo_t *cr)
+{
+	GnmNotebook *nb = GNM_NOTEBOOK (widget);
+	GtkStyleContext *context = gtk_widget_get_style_context (widget);
+	GtkAllocation allocation;
+	unsigned ui;
+
+	gtk_widget_get_allocation (widget, &allocation);
+	g_printerr ("Drawing notebook at (%d,%d) size %dx%d\n",
+		    allocation.x, allocation.y,
+		    allocation.width, allocation.height);
+	gtk_render_background (context, cr,
+			       allocation.x, allocation.y,
+			       allocation.width, allocation.height);
+
+	for (ui = 0; ui < nb->children->len; ui++) {
+		GtkWidget *child = g_ptr_array_index (nb->children, ui);
+		if (!gtk_widget_get_child_visible (child))
+			continue;
+		if ((int)ui == nb->current)
+			continue;
+                gtk_container_propagate_draw (GTK_CONTAINER (nb), child, cr);
+	}
+	if (nb->current != -1) {
+		GtkWidget *child =
+			g_ptr_array_index (nb->children, nb->current);
+                gtk_container_propagate_draw (GTK_CONTAINER (nb), child, cr);
+	}
+
+	return FALSE;
 }
 
 static void
-gnm_notebook_class_init (GtkWidgetClass *klass)
+gnm_notebook_class_init (GObjectClass *klass)
 {
-	gnm_notebook_parent_class = g_type_class_peek (GTK_TYPE_NOTEBOOK);
-	klass->size_allocate = gnm_notebook_size_allocate;
+	GtkContainerClass *cclass = (GtkContainerClass *)klass;
+	GtkWidgetClass *wclass = (GtkWidgetClass *)klass;
+
+	gnm_notebook_parent_class = g_type_class_peek_parent (klass);
+	klass->finalize = gnm_notebook_finalize;
+
+	/**
+	 * GtkNotebook::switch-page:
+	 * @notebook: the object which received the signal.
+	 * @page: the new current page
+	 * @page_num: the index of the page
+	 *
+	 * Emitted when the user or a function changes the current page.
+	 */
+	notebook_signals[SWITCH_PAGE] =
+		g_signal_new ("switch-page",
+			      G_TYPE_FROM_CLASS (klass),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (GnmNotebookClass, switch_page),
+			      NULL, NULL,
+			      gnm__VOID__OBJECT_UINT,
+			      G_TYPE_NONE, 2,
+			      GTK_TYPE_WIDGET,
+			      G_TYPE_UINT);
+
+	cclass->add = gnm_notebook_add;
+	cclass->remove = gnm_notebook_remove;
+	cclass->forall = gnm_notebook_forall;
+	gtk_container_class_handle_border_width (cclass);
+	
+	wclass->realize = gnm_notebook_realize;
+	wclass->draw = gnm_notebook_draw;
+	wclass->get_preferred_width = gnm_notebook_get_preferred_width;
+	wclass->get_preferred_height = gnm_notebook_get_preferred_height;
+	wclass->size_allocate = gnm_notebook_size_allocate;
 }
 
 static void
-gnm_notebook_init (GnmNotebook *notebook)
+gnm_notebook_init (GnmNotebook *nb)
 {
-	gtk_notebook_set_scrollable (GTK_NOTEBOOK (notebook), TRUE);
+	GtkStyleContext *context;
+
+	nb->children = g_ptr_array_new ();
+	nb->current = -1;
+
+	context = gtk_widget_get_style_context (GTK_WIDGET (nb));
+	gtk_style_context_add_class (context, GTK_STYLE_CLASS_NOTEBOOK);
 }
 
 GSF_CLASS (GnmNotebook, gnm_notebook,
-	   gnm_notebook_class_init, gnm_notebook_init, GTK_TYPE_NOTEBOOK)
+	   gnm_notebook_class_init, gnm_notebook_init, GTK_TYPE_CONTAINER)
+#if 0
+	;
+#endif
+
+/* -------------------------------------------------------------------------- */
 
 int
 gnm_notebook_get_n_visible (GnmNotebook *nb)
 {
-	int count = 0;
-	GList *l, *children = gtk_container_get_children (GTK_CONTAINER (nb));
+	g_return_val_if_fail (IS_GNM_NOTEBOOK (nb), 0);
 
-	for (l = children; l; l = l->next) {
-		GtkWidget *child = l->data;
-		if (gtk_widget_get_visible (child))
-			count++;
-	}
-
-	g_list_free (children);
-
-	return count;
+	gnm_notebook_inspect (nb);
+	return nb->n_visible;
 }
 
 GtkWidget *
 gnm_notebook_get_nth_label (GnmNotebook *nb, int n)
 {
-	GtkWidget *page;
-
 	g_return_val_if_fail (IS_GNM_NOTEBOOK (nb), NULL);
 
-	page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (nb), n);
-	if (!page)
+	if (n < 0 || n >= (int)nb->children->len)
 		return NULL;
 
-	return gtk_notebook_get_tab_label (GTK_NOTEBOOK (nb), page);
+	return g_ptr_array_index (nb->children, n);
 }
 
-static void
-cb_label_destroyed (G_GNUC_UNUSED GtkWidget *label, GtkWidget *dummy)
-{
-	gtk_widget_destroy (dummy);
-}
-
-static void
-cb_label_visibility (GtkWidget *label,
-		     G_GNUC_UNUSED GParamSpec *pspec,
-		     GtkWidget *dummy)
+GtkWidget *
+gnm_notebook_get_current_label (GnmNotebook *nb)
 {
-	gtk_widget_set_visible (dummy, gtk_widget_get_visible (label));
+	return gnm_notebook_get_nth_label (nb, nb->current);
 }
 
 void
 gnm_notebook_insert_tab (GnmNotebook *nb, GtkWidget *label, int pos)
 {
-	GtkWidget *dummy_page = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-	gtk_widget_set_size_request (dummy_page, 1, 1);
+	g_return_if_fail (IS_GNM_NOTEBOOK (nb));
+
+	if (pos == -1)
+		pos = nb->children->len;
 
-	g_object_set_data (G_OBJECT (label), DUMMY_KEY, dummy_page);
+	go_ptr_array_insert (nb->children, label, pos);
+	if (nb->current >= pos)
+		nb->current++;
 
-	g_signal_connect_object (G_OBJECT (label), "destroy",
-				 G_CALLBACK (cb_label_destroyed), dummy_page,
-				 0);
+	gtk_widget_set_parent (label, GTK_WIDGET (nb));
 
-	cb_label_visibility (label, NULL, dummy_page);
-	g_signal_connect_object (G_OBJECT (label), "notify::visible",
-				 G_CALLBACK (cb_label_visibility), dummy_page,
-				 0);
+	if (nb->current == -1)
+		gnm_notebook_next_page (nb);
 
-	gtk_notebook_insert_page (GTK_NOTEBOOK (nb), dummy_page, label, pos);
+	gtk_widget_queue_resize (GTK_WIDGET (nb));
 }
 
 void
 gnm_notebook_move_tab (GnmNotebook *nb, GtkWidget *label, int newpos)
 {
-	GtkWidget *child = g_object_get_data (G_OBJECT (label), DUMMY_KEY);
-	gtk_notebook_reorder_child (GTK_NOTEBOOK (nb), child, newpos);
+	g_return_if_fail (IS_GNM_NOTEBOOK (nb));
+	g_printerr ("gnm_notebook_move_tab\n");
 }
 
 void
 gnm_notebook_set_current_page (GnmNotebook *nb, int page)
 {
-	gtk_notebook_set_current_page (GTK_NOTEBOOK (nb), page);
+	GtkWidget *child;
+
+	g_return_if_fail (IS_GNM_NOTEBOOK (nb));
+	g_return_if_fail (page >= 0 && page < (int)nb->children->len);
+
+	if (page == nb->current)
+		return;
+
+	child = g_ptr_array_index (nb->children, page);
+	if (!gtk_widget_get_visible (child))
+		return;
+
+	nb->current = page;
+	gtk_widget_queue_draw (GTK_WIDGET (nb));
+
+	g_signal_emit (nb, notebook_signals[SWITCH_PAGE],
+		       0, child, page);
 }
 
 void
 gnm_notebook_prev_page (GnmNotebook *nb)
 {
-	gtk_notebook_prev_page (GTK_NOTEBOOK (nb));
+	g_return_if_fail (IS_GNM_NOTEBOOK (nb));
+
+	gnm_notebook_inspect (nb);
+	if (nb->prev_visible != -1)
+		gnm_notebook_set_current_page (nb, nb->prev_visible);
 }
 
 void
 gnm_notebook_next_page (GnmNotebook *nb)
 {
-	gtk_notebook_next_page (GTK_NOTEBOOK (nb));
+	g_return_if_fail (IS_GNM_NOTEBOOK (nb));
+
+	gnm_notebook_inspect (nb);
+	if (nb->next_visible != -1)
+		gnm_notebook_set_current_page (nb, nb->next_visible);
 }
diff --git a/src/widgets/gnm-notebook.h b/src/widgets/gnm-notebook.h
index 9dae466..96e5fb0 100644
--- a/src/widgets/gnm-notebook.h
+++ b/src/widgets/gnm-notebook.h
@@ -23,6 +23,11 @@
 
 #include <gtk/gtk.h>
 
+GType		gnm_notebook_button_get_type	(void);
+#define GNM_NOTEBOOK_BUTTON_TYPE        (gnm_notebook_button_get_type ())
+#define GNM_NOTEBOOK_BUTTON(obj)        (G_TYPE_CHECK_INSTANCE_CAST((obj), GNM_NOTEBOOK_BUTTON_TYPE, GnmNotebookButton))
+#define IS_GNM_NOTEBOOK_BUTTON(obj)     (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNM_NOTEBOOK_BUTTON_TYPE))
+
 #define GNM_NOTEBOOK_TYPE        (gnm_notebook_get_type ())
 #define GNM_NOTEBOOK(obj)        (G_TYPE_CHECK_INSTANCE_CAST((obj), GNM_NOTEBOOK_TYPE, GnmNotebook))
 #define IS_GNM_NOTEBOOK(obj)     (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNM_NOTEBOOK_TYPE))
@@ -33,6 +38,7 @@ GType		gnm_notebook_get_type	(void);
 
 int             gnm_notebook_get_n_visible (GnmNotebook *nb);
 GtkWidget *     gnm_notebook_get_nth_label (GnmNotebook *nb, int n);
+GtkWidget *     gnm_notebook_get_current_label (GnmNotebook *nb);
 void            gnm_notebook_insert_tab (GnmNotebook *nb, GtkWidget *label,
 					 int pos);
 void            gnm_notebook_move_tab (GnmNotebook *nb, GtkWidget *label, int newpos);
