[glabels] Refactored glLabel and glView



commit ff3a495ea186e7ff5d68a589312b3e2ef5c7d35e
Author: Jim Evins <evins snaught com>
Date:   Wed Dec 2 17:06:31 2009 -0500

    Refactored glLabel and glView
    
    Refactored glLabel and glView code:
    
    - Moved selection tracking and storage of current label defaults from
      glView to glLabel.
    
    - Removed complexity of synchronizing lists of labels between glView and
      glLabel.
    
    - Current defaults for new objects are now kept in glLabel, not glView.
    
    - Now follows a more faithful MVC pattern.  As a consequence, the
      Object editor and property bar are now fully independent views of
      glLabel and do not need to be aware of glView at all.
    
    - Refactoring reduced total SLOC count by about 1100 lines of code.
    
    - This should potentially simplify the addition of an Undo/Redo
      capability, because selections and object lists do not need
      to be kept synchronized.

 .gitignore                         |    1 +
 data/builder/object-editor.builder |    6 +-
 po/POTFILES.in                     |    2 -
 src/Makefile.am                    |    2 -
 src/cairo-label-path.c             |   14 +-
 src/cairo-label-path.h             |    2 +-
 src/cairo-markup-path.c            |   16 +-
 src/color-swatch.c                 |    7 +-
 src/file.c                         |   18 +-
 src/glabels-batch.c                |    4 +-
 src/label-barcode.c                |   53 +-
 src/label-box.c                    |   59 +-
 src/label-ellipse.c                |   59 +-
 src/label-image.c                  |   66 +-
 src/label-line.c                   |   52 +-
 src/label-object.c                 |  845 ++++++++-----
 src/label-object.h                 |  234 +++--
 src/label-text.c                   |  101 ++-
 src/label-text.h                   |   12 +-
 src/label.c                        | 2476 ++++++++++++++++++++++++++++++++----
 src/label.h                        |  280 ++++-
 src/object-editor-bc-page.c        |   10 +-
 src/object-editor-data-page.c      |    3 +-
 src/object-editor-fill-page.c      |    8 +-
 src/object-editor-image-page.c     |   27 +-
 src/object-editor-line-page.c      |    8 +-
 src/object-editor-lsize-page.c     |    4 +-
 src/object-editor-private.h        |  209 +++-
 src/object-editor-shadow-page.c    |   11 +-
 src/object-editor-size-page.c      |   33 +-
 src/object-editor-text-page.c      |   16 +-
 src/object-editor.c                | 1129 ++++++++++++-----
 src/object-editor.h                |  230 +----
 src/print-op-dialog.c              |    6 +-
 src/print-op.c                     |   24 +-
 src/print.c                        |   33 +-
 src/ui-commands.c                  |   48 +-
 src/ui-property-bar.c              |  235 ++--
 src/ui-property-bar.h              |    6 +-
 src/ui-sidebar.c                   |   71 +-
 src/ui-sidebar.h                   |    4 +-
 src/ui.c                           |   16 +-
 src/view-barcode.c                 |  307 +-----
 src/view-barcode.h                 |   34 +-
 src/view-box.c                     |  354 +-----
 src/view-box.h                     |   35 +-
 src/view-ellipse.c                 |  356 +-----
 src/view-ellipse.h                 |   34 +-
 src/view-image.c                   |  290 +-----
 src/view-image.h                   |   34 +-
 src/view-line.c                    |  328 +-----
 src/view-line.h                    |   34 +-
 src/view-object.c                  |  786 ------------
 src/view-object.h                  |  144 ---
 src/view-text.c                    |  412 +------
 src/view-text.h                    |   37 +-
 src/view.c                         | 2282 ++++-----------------------------
 src/view.h                         |  193 +---
 src/window.c                       |   20 +-
 src/window.h                       |    5 +-
 src/xml-label.c                    |   21 +-
 61 files changed, 5173 insertions(+), 6973 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 397a7f6..b89e7e4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -83,3 +83,4 @@ glabels-*.tar.gz
 .*.swp
 *.orig
 *.rej
+gmon.out
diff --git a/data/builder/object-editor.builder b/data/builder/object-editor.builder
index 365f426..117e360 100644
--- a/data/builder/object-editor.builder
+++ b/data/builder/object-editor.builder
@@ -52,6 +52,7 @@
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="scrollable">True</property>
+                <property name="homogeneous">True</property>
                 <child>
                   <object class="GtkVBox" id="edit_page_vbox">
                     <property name="visible">True</property>
@@ -233,7 +234,6 @@
                                   <object class="GtkImage" id="image1">
                                     <property name="visible">True</property>
                                     <property name="stock">gtk-bold</property>
-                                    <property name="icon-size">4</property>
                                   </object>
                                 </child>
                               </object>
@@ -252,7 +252,6 @@
                                   <object class="GtkImage" id="image2">
                                     <property name="visible">True</property>
                                     <property name="stock">gtk-italic</property>
-                                    <property name="icon-size">4</property>
                                   </object>
                                 </child>
                               </object>
@@ -415,7 +414,6 @@
                                   <object class="GtkImage" id="image3">
                                     <property name="visible">True</property>
                                     <property name="stock">gtk-justify-left</property>
-                                    <property name="icon-size">4</property>
                                   </object>
                                 </child>
                               </object>
@@ -434,7 +432,6 @@
                                   <object class="GtkImage" id="image4">
                                     <property name="visible">True</property>
                                     <property name="stock">gtk-justify-center</property>
-                                    <property name="icon-size">4</property>
                                   </object>
                                 </child>
                               </object>
@@ -453,7 +450,6 @@
                                   <object class="GtkImage" id="image5">
                                     <property name="visible">True</property>
                                     <property name="stock">gtk-justify-right</property>
-                                    <property name="icon-size">4</property>
                                   </object>
                                 </child>
                               </object>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 8afc6d4..4f6bb28 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -171,8 +171,6 @@ src/view-image.c
 src/view-image.h
 src/view-line.c
 src/view-line.h
-src/view-object.c
-src/view-object.h
 src/view-text.c
 src/view-text.h
 src/warning-handler.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 0e241da..fe1c337 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -79,8 +79,6 @@ glabels_SOURCES = 			\
 	hig.h				\
 	view.c				\
 	view.h				\
-	view-object.c			\
-	view-object.h			\
 	view-box.c			\
 	view-box.h			\
 	view-ellipse.c			\
diff --git a/src/cairo-label-path.c b/src/cairo-label-path.c
index 0d7e4b7..3596476 100644
--- a/src/cairo-label-path.c
+++ b/src/cairo-label-path.c
@@ -42,15 +42,15 @@
 /*===========================================*/
 
 static void gl_cairo_rect_label_path             (cairo_t                *cr,
-                                                  lglTemplate            *template,
+                                                  const lglTemplate      *template,
                                                   gboolean                rotate_flag,
                                                   gboolean                waste_flag);
 static void gl_cairo_round_label_path            (cairo_t                *cr,
-                                                  lglTemplate            *template,
+                                                  const lglTemplate      *template,
                                                   gboolean                rotate_flag,
                                                   gboolean                waste_flag);
 static void gl_cairo_cd_label_path               (cairo_t                *cr,
-                                                  lglTemplate            *template,
+                                                  const lglTemplate      *template,
                                                   gboolean                rotate_flag,
                                                   gboolean                waste_flag);
 
@@ -60,7 +60,7 @@ static void gl_cairo_cd_label_path               (cairo_t                *cr,
 /*--------------------------------------------------------------------------*/
 void
 gl_cairo_label_path (cairo_t           *cr,
-                     lglTemplate       *template,
+                     const lglTemplate *template,
                      gboolean           rotate_flag,
                      gboolean           waste_flag)
 {
@@ -98,7 +98,7 @@ gl_cairo_label_path (cairo_t           *cr,
 /*--------------------------------------------------------------------------*/
 static void
 gl_cairo_rect_label_path (cairo_t           *cr,
-                          lglTemplate       *template,
+                          const lglTemplate *template,
                           gboolean           rotate_flag,
                           gboolean           waste_flag)
 {
@@ -157,7 +157,7 @@ gl_cairo_rect_label_path (cairo_t           *cr,
 /*--------------------------------------------------------------------------*/
 static void
 gl_cairo_round_label_path (cairo_t           *cr,
-                           lglTemplate       *template,
+                           const lglTemplate *template,
                            gboolean           rotate_flag,
                            gboolean           waste_flag)
 {
@@ -200,7 +200,7 @@ gl_cairo_round_label_path (cairo_t           *cr,
 /*--------------------------------------------------------------------------*/
 static void
 gl_cairo_cd_label_path (cairo_t           *cr,
-                        lglTemplate       *template,
+                        const lglTemplate *template,
                         gboolean           rotate_flag,
                         gboolean           waste_flag)
 {
diff --git a/src/cairo-label-path.h b/src/cairo-label-path.h
index 9bb3c23..b42dcad 100644
--- a/src/cairo-label-path.h
+++ b/src/cairo-label-path.h
@@ -27,7 +27,7 @@
 G_BEGIN_DECLS
 
 void gl_cairo_label_path (cairo_t                *cr,
-                          lglTemplate            *template,
+                          const lglTemplate      *template,
                           gboolean                rotate_flag,
                           gboolean                waste_flag);
 
diff --git a/src/cairo-markup-path.c b/src/cairo-markup-path.c
index 7a8bab3..2785c01 100644
--- a/src/cairo-markup-path.c
+++ b/src/cairo-markup-path.c
@@ -107,11 +107,13 @@ gl_cairo_markup_margin_path (cairo_t                *cr,
                              const lglTemplateMarkup *markup,
                              glLabel                *label)
 {
+	const lglTemplate      *template;
 	const lglTemplateFrame *frame;
 
         gl_debug (DEBUG_PATH, "START");
 
-        frame = (lglTemplateFrame *)label->template->frames->data;
+        template = gl_label_get_template (label);
+        frame = (lglTemplateFrame *)template->frames->data;
 
         switch (frame->shape) {
 
@@ -144,12 +146,14 @@ gl_cairo_markup_margin_rect_path (cairo_t                 *cr,
                                   const lglTemplateMarkup *markup,
                                   glLabel                 *label)
 {
+        const lglTemplate      *template;
         const lglTemplateFrame *frame;
         gdouble                 w, h, r, m;
 
         gl_debug (DEBUG_PATH, "START");
 
-        frame = (lglTemplateFrame *)label->template->frames->data;
+        template = gl_label_get_template (label);
+        frame = (lglTemplateFrame *)template->frames->data;
 
         m = markup->margin.size;
 
@@ -184,12 +188,14 @@ gl_cairo_markup_margin_round_path (cairo_t                 *cr,
                                    const lglTemplateMarkup *markup,
                                    glLabel                 *label)
 {
+	const lglTemplate      *template;
 	const lglTemplateFrame *frame;
 	gdouble                 r, m;
 
 	gl_debug (DEBUG_PATH, "START");
 
-        frame = (lglTemplateFrame *)label->template->frames->data;
+        template = gl_label_get_template (label);
+        frame = (lglTemplateFrame *)template->frames->data;
 
 	r = frame->round.r;
 	m = markup->margin.size;
@@ -209,6 +215,7 @@ gl_cairo_markup_margin_cd_path (cairo_t                 *cr,
                                 const lglTemplateMarkup *markup,
                                 glLabel                 *label)
 {
+	const lglTemplate      *template;
 	const lglTemplateFrame *frame;
 	gdouble                 m, r1, r2;
 	gdouble                 theta1, theta2;
@@ -217,7 +224,8 @@ gl_cairo_markup_margin_cd_path (cairo_t                 *cr,
 
 	gl_debug (DEBUG_PATH, "START");
 
-        frame = (lglTemplateFrame *)label->template->frames->data;
+        template = gl_label_get_template (label);
+        frame = (lglTemplateFrame *)template->frames->data;
 
         lgl_template_frame_get_size (frame, &w, &h);
         xc = w/2.0;
diff --git a/src/color-swatch.c b/src/color-swatch.c
index f43108f..b068e6c 100644
--- a/src/color-swatch.c
+++ b/src/color-swatch.c
@@ -146,9 +146,12 @@ void
 gl_color_swatch_set_color (glColorSwatch *this,
                            guint          color)
 {
-        this->priv->color = color;
+        if ( color != this->priv->color )
+        {
+                this->priv->color = color;
 
-        redraw (this);
+                redraw (this);
+        }
 }
 
 
diff --git a/src/file.c b/src/file.c
index 3f0c633..5264efb 100644
--- a/src/file.c
+++ b/src/file.c
@@ -176,8 +176,10 @@ void
 gl_file_properties (glLabel   *label,
 		    glWindow  *window)
 {
-	GtkWidget    *dialog;
-        gchar        *name;
+        const lglTemplate *template;
+        gboolean           rotate_flag;
+	GtkWidget         *dialog;
+        gchar             *name;
 
 	gl_debug (DEBUG_FILE, "START");
 
@@ -192,19 +194,21 @@ gl_file_properties (glLabel   *label,
 	g_signal_connect (G_OBJECT(dialog), "response",
 			  G_CALLBACK (properties_response), dialog);
 
-        if (label->template->paper_id != NULL) {
+        template    = gl_label_get_template (label);
+        rotate_flag = gl_label_get_rotate_flag (label);
+
+        if (template->paper_id != NULL) {
                 gl_new_label_dialog_set_filter_parameters (GL_NEW_LABEL_DIALOG (dialog),
-                                                           label->template->paper_id,
+                                                           template->paper_id,
                                                            NULL);
         }
-        name = lgl_template_get_name (label->template);
+        name = lgl_template_get_name (template);
         if (name != NULL) {
                 gl_new_label_dialog_set_template_name (GL_NEW_LABEL_DIALOG (dialog), name);
         }
         g_free (name);
 
-        gl_new_label_dialog_set_rotate_state (GL_NEW_LABEL_DIALOG (dialog),
-					      label->rotate_flag);
+        gl_new_label_dialog_set_rotate_state (GL_NEW_LABEL_DIALOG (dialog), rotate_flag);
 
         gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
 	gtk_widget_show_all (GTK_WIDGET (dialog));
diff --git a/src/glabels-batch.c b/src/glabels-batch.c
index ac57432..78f7f07 100644
--- a/src/glabels-batch.c
+++ b/src/glabels-batch.c
@@ -81,6 +81,7 @@ main (int argc, char **argv)
         gchar             *abs_fn;
         glLabel           *label = NULL;
         glMerge           *merge = NULL;
+        const lglTemplate *template;
         lglTemplateFrame  *frame;
         glXMLLabelStatus   status;
         glPrintOp         *print_op;
@@ -148,7 +149,8 @@ main (int argc, char **argv)
                                 }
                         }
                         abs_fn = gl_file_util_make_absolute ( output );
-                        frame = (lglTemplateFrame *)label->template->frames->data;
+                        template = gl_label_get_template (label);
+                        frame = (lglTemplateFrame *)template->frames->data;
 
                         print_op = gl_print_op_new (label);
                         gl_print_op_set_filename        (print_op, abs_fn);
diff --git a/src/label-barcode.c b/src/label-barcode.c
index c45c20c..992f982 100644
--- a/src/label-barcode.c
+++ b/src/label-barcode.c
@@ -73,10 +73,15 @@ static void  set_line_color                 (glLabelObject       *object,
 
 static glColorNode *get_line_color          (glLabelObject       *object);
 
-static void    draw_object                (glLabelObject     *object,
-                                           cairo_t           *cr,
-                                           gboolean           screen_flag,
-                                           glMergeRecord     *record);
+static void     draw_object                 (glLabelObject       *object,
+                                             cairo_t             *cr,
+                                             gboolean             screen_flag,
+                                             glMergeRecord       *record);
+
+static gboolean object_at                   (glLabelObject       *object,
+                                             cairo_t             *cr,
+                                             gdouble              x_pixels,
+                                             gdouble              y_pixels);
 
 
 /*****************************************************************************/
@@ -99,6 +104,7 @@ gl_label_barcode_class_init (glLabelBarcodeClass *class)
 	label_object_class->get_line_color = get_line_color;
         label_object_class->draw_object    = draw_object;
         label_object_class->draw_shadow    = NULL;
+        label_object_class->object_at      = object_at;
 
 	object_class->finalize = gl_label_barcode_finalize;
 }
@@ -108,7 +114,6 @@ static void
 gl_label_barcode_init (glLabelBarcode *lbc)
 {
 	lbc->priv = g_new0 (glLabelBarcodePrivate, 1);
-	lbc->priv->color_node = gl_color_node_new_default ();
 	lbc->priv->text_node  = gl_text_node_new_from_text ("");
 }
 
@@ -135,11 +140,21 @@ gl_label_barcode_finalize (GObject *object)
 GObject *
 gl_label_barcode_new (glLabel *label)
 {
-	glLabelBarcode *lbc;
+	glLabelBarcode      *lbc;
+	glColorNode         *line_color_node;
 
 	lbc = g_object_new (gl_label_barcode_get_type(), NULL);
 
-	gl_label_object_set_parent (GL_LABEL_OBJECT(lbc), label);
+        if (label != NULL)
+        {
+                gl_label_object_set_parent (GL_LABEL_OBJECT(lbc), label);
+
+                line_color_node = gl_color_node_new_default ();
+
+                line_color_node->color = gl_label_get_default_line_color(label);
+
+                lbc->priv->color_node = line_color_node;
+        }
 
 	return G_OBJECT (lbc);
 }
@@ -491,6 +506,30 @@ draw_object (glLabelObject *object,
 }
 
 
+/*****************************************************************************/
+/* Is object at coordinates?                                                 */
+/*****************************************************************************/
+static gboolean
+object_at (glLabelObject *object,
+           cairo_t       *cr,
+           gdouble        x,
+           gdouble        y)
+{
+        gdouble           w, h;
+
+        gl_label_object_get_size (object, &w, &h);
+
+        cairo_rectangle (cr, 0.0, 0.0, w, h);
+
+        if (cairo_in_fill (cr, x, y))
+        {
+                return TRUE;
+        }
+
+        return FALSE;
+}
+
+
 
 
 /*
diff --git a/src/label-box.c b/src/label-box.c
index 2679736..6104e72 100644
--- a/src/label-box.c
+++ b/src/label-box.c
@@ -75,6 +75,11 @@ static void    draw_shadow                (glLabelObject     *object,
                                            gboolean           screen_flag,
                                            glMergeRecord     *record);
 
+static gboolean object_at                 (glLabelObject     *object,
+                                           cairo_t           *cr,
+                                           gdouble            x_pixels,
+                                           gdouble            y_pixels);
+
 
 /*****************************************************************************/
 /* Boilerplate object stuff.                                                 */
@@ -99,6 +104,7 @@ gl_label_box_class_init (glLabelBoxClass *class)
 	label_object_class->get_line_width = get_line_width;
         label_object_class->draw_object    = draw_object;
         label_object_class->draw_shadow    = draw_shadow;
+        label_object_class->object_at      = object_at;
 
 	object_class->finalize = gl_label_box_finalize;
 }
@@ -108,8 +114,6 @@ static void
 gl_label_box_init (glLabelBox *lbox)
 {
 	lbox->priv = g_new0 (glLabelBoxPrivate, 1);
-	lbox->priv->line_color_node = gl_color_node_new_default ();
-	lbox->priv->fill_color_node = gl_color_node_new_default ();
 }
 
 
@@ -134,11 +138,26 @@ gl_label_box_finalize (GObject *object)
 GObject *
 gl_label_box_new (glLabel *label)
 {
-	glLabelBox *lbox;
+	glLabelBox          *lbox;
+	glColorNode         *fill_color_node;
+	glColorNode         *line_color_node;
 
 	lbox = g_object_new (gl_label_box_get_type(), NULL);
 
-	gl_label_object_set_parent (GL_LABEL_OBJECT(lbox), label);
+        if (label != NULL)
+        {
+                gl_label_object_set_parent (GL_LABEL_OBJECT(lbox), label);
+
+                fill_color_node = gl_color_node_new_default ();
+                line_color_node = gl_color_node_new_default ();
+
+                line_color_node->color = gl_label_get_default_line_color(label);
+                fill_color_node->color = gl_label_get_default_fill_color(label);
+
+                lbox->priv->line_width      = gl_label_get_default_line_width(label);
+                lbox->priv->line_color_node = line_color_node;
+                lbox->priv->fill_color_node = fill_color_node;
+        }
 
 	return G_OBJECT (lbox);
 }
@@ -406,6 +425,38 @@ draw_shadow (glLabelObject *object,
 }
 
 
+/*****************************************************************************/
+/* Is object at coordinates?                                                 */
+/*****************************************************************************/
+static gboolean
+object_at (glLabelObject *object,
+           cairo_t       *cr,
+           gdouble        x,
+           gdouble        y)
+{
+        gdouble           w, h;
+        gdouble           line_width;
+
+        gl_label_object_get_size (object, &w, &h);
+
+        cairo_rectangle (cr, 0.0, 0.0, w, h);
+
+        if (cairo_in_fill (cr, x, y))
+        {
+                return TRUE;
+        }
+
+        line_width = gl_label_object_get_line_width (object);
+        cairo_set_line_width (cr, line_width);
+        if (cairo_in_stroke (cr, x, y))
+        {
+                return TRUE;
+        }
+
+        return FALSE;
+}
+
+
 
 
 /*
diff --git a/src/label-ellipse.c b/src/label-ellipse.c
index d327068..42439ff 100644
--- a/src/label-ellipse.c
+++ b/src/label-ellipse.c
@@ -79,6 +79,11 @@ static void    draw_shadow                (glLabelObject     *object,
                                            gboolean           screen_flag,
                                            glMergeRecord     *record);
 
+static gboolean object_at                 (glLabelObject     *object,
+                                           cairo_t           *cr,
+                                           gdouble            x_pixels,
+                                           gdouble            y_pixels);
+
 
 /*****************************************************************************/
 /* Boilerplate object stuff.                                                 */
@@ -103,6 +108,7 @@ gl_label_ellipse_class_init (glLabelEllipseClass *class)
 	label_object_class->get_line_width = get_line_width;
         label_object_class->draw_object    = draw_object;
         label_object_class->draw_shadow    = draw_shadow;
+        label_object_class->object_at      = object_at;
 
 	object_class->finalize = gl_label_ellipse_finalize;
 }
@@ -112,8 +118,6 @@ static void
 gl_label_ellipse_init (glLabelEllipse *lellipse)
 {
 	lellipse->priv = g_new0 (glLabelEllipsePrivate, 1);
-	lellipse->priv->line_color_node = gl_color_node_new_default ();
-	lellipse->priv->fill_color_node = gl_color_node_new_default ();
 }
 
 
@@ -138,11 +142,26 @@ gl_label_ellipse_finalize (GObject *object)
 GObject *
 gl_label_ellipse_new (glLabel *label)
 {
-	glLabelEllipse *lellipse;
+	glLabelEllipse      *lellipse;
+	glColorNode         *fill_color_node;
+	glColorNode         *line_color_node;
 
 	lellipse = g_object_new (gl_label_ellipse_get_type(), NULL);
 
-	gl_label_object_set_parent (GL_LABEL_OBJECT(lellipse), label);
+        if (label != NULL)
+        {
+                gl_label_object_set_parent (GL_LABEL_OBJECT(lellipse), label);
+
+                fill_color_node = gl_color_node_new_default ();
+                line_color_node = gl_color_node_new_default ();
+
+                line_color_node->color = gl_label_get_default_line_color(label);
+                fill_color_node->color = gl_label_get_default_fill_color(label);
+
+                lellipse->priv->line_width      = gl_label_get_default_line_width(label);
+                lellipse->priv->line_color_node = line_color_node;
+                lellipse->priv->fill_color_node = fill_color_node;
+        }
 
 	return G_OBJECT (lellipse);
 }
@@ -409,6 +428,38 @@ draw_shadow (glLabelObject *object,
 }
 
 
+/*****************************************************************************/
+/* Is object at coordinates?                                                 */
+/*****************************************************************************/
+static gboolean
+object_at (glLabelObject *object,
+           cairo_t       *cr,
+           gdouble        x,
+           gdouble        y)
+{
+        gdouble           w, h;
+        gdouble           line_width;
+
+        gl_label_object_get_size (object, &w, &h);
+
+        gl_cairo_ellipse_path (cr, w/2, h/2);
+
+        if (cairo_in_fill (cr, x, y))
+        {
+                return TRUE;
+        }
+
+        line_width = gl_label_object_get_line_width (object);
+        cairo_set_line_width (cr, line_width);
+        if (cairo_in_stroke (cr, x, y))
+        {
+                return TRUE;
+        }
+
+        return FALSE;
+}
+
+
 
 
 /*
diff --git a/src/label-image.c b/src/label-image.c
index d325dc6..001ed36 100644
--- a/src/label-image.c
+++ b/src/label-image.c
@@ -59,6 +59,9 @@ static void gl_label_image_finalize      (GObject           *object);
 static void copy                         (glLabelObject     *dst_object,
 					  glLabelObject     *src_object);
 
+static void copy_to_clipboard            (glLabelObject     *object,
+                                          GtkClipboard      *clipboard);
+
 static void set_size                     (glLabelObject     *object,
                                           gdouble            w,
                                           gdouble            h);
@@ -68,6 +71,11 @@ static void draw_object                  (glLabelObject     *object,
                                           gboolean           screen_flag,
                                           glMergeRecord     *record);
 
+static gboolean object_at                (glLabelObject     *object,
+                                          cairo_t           *cr,
+                                          gdouble            x_pixels,
+                                          gdouble            y_pixels);
+
 
 /*****************************************************************************/
 /* Boilerplate object stuff.                                                 */
@@ -83,10 +91,12 @@ gl_label_image_class_init (glLabelImageClass *class)
 
 	gl_label_image_parent_class = g_type_class_peek_parent (class);
 
-	label_object_class->copy           = copy;
-	label_object_class->set_size       = set_size;
-        label_object_class->draw_object    = draw_object;
-        label_object_class->draw_shadow    = NULL;
+	label_object_class->copy              = copy;
+	label_object_class->copy_to_clipboard = copy_to_clipboard;
+	label_object_class->set_size          = set_size;
+        label_object_class->draw_object       = draw_object;
+        label_object_class->draw_shadow       = NULL;
+        label_object_class->object_at         = object_at;
 
 	object_class->finalize = gl_label_image_finalize;
 }
@@ -186,6 +196,30 @@ copy (glLabelObject *dst_object,
 
 
 /*---------------------------------------------------------------------------*/
+/* Private.  Copy pixbuf to clipboard.                                       */
+/*---------------------------------------------------------------------------*/
+static void
+copy_to_clipboard (glLabelObject     *object,
+                   GtkClipboard      *clipboard)
+{
+        glLabelImage *limage;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (object && GL_IS_LABEL_IMAGE (object));
+
+        limage = GL_LABEL_IMAGE (object);
+
+        if ( limage->priv->pixbuf != NULL )
+        {
+                gtk_clipboard_set_image (clipboard, limage->priv->pixbuf);
+        }
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*---------------------------------------------------------------------------*/
 /* PRIVATE.  Set size method.                                                */
 /*---------------------------------------------------------------------------*/
 static void
@@ -360,6 +394,30 @@ draw_object (glLabelObject *object,
 }
 
 
+/*****************************************************************************/
+/* Is object at coordinates?                                                 */
+/*****************************************************************************/
+static gboolean
+object_at (glLabelObject *object,
+           cairo_t       *cr,
+           gdouble        x,
+           gdouble        y)
+{
+        gdouble           w, h;
+
+        gl_label_object_get_size (object, &w, &h);
+
+        cairo_rectangle (cr, 0.0, 0.0, w, h);
+
+        if (cairo_in_fill (cr, x, y))
+        {
+                return TRUE;
+        }
+
+        return FALSE;
+}
+
+
 
 
 /*
diff --git a/src/label-line.c b/src/label-line.c
index 70b26cc..676b9af 100644
--- a/src/label-line.c
+++ b/src/label-line.c
@@ -69,6 +69,11 @@ static void    draw_shadow                (glLabelObject     *object,
                                            gboolean           screen_flag,
                                            glMergeRecord     *record);
 
+static gboolean object_at                 (glLabelObject     *object,
+                                           cairo_t           *cr,
+                                           gdouble            x_pixels,
+                                           gdouble            y_pixels);
+
 
 /*****************************************************************************/
 /* Boilerplate object stuff.                                                 */
@@ -91,6 +96,9 @@ gl_label_line_class_init (glLabelLineClass *class)
 	label_object_class->get_line_width = get_line_width;
         label_object_class->draw_object    = draw_object;
         label_object_class->draw_shadow    = draw_shadow;
+	label_object_class->draw_handles   = gl_label_object_draw_handles_line;
+        label_object_class->object_at      = object_at;
+	label_object_class->handle_at      = gl_label_object_line_handle_at;
 
 	object_class->finalize = gl_label_line_finalize;
 }
@@ -100,7 +108,6 @@ static void
 gl_label_line_init (glLabelLine *lline)
 {
 	lline->priv = g_new0 (glLabelLinePrivate, 1);
-	lline->priv->line_color_node = gl_color_node_new_default ();
 }
 
 
@@ -124,11 +131,22 @@ gl_label_line_finalize (GObject *object)
 GObject *
 gl_label_line_new (glLabel *label)
 {
-	glLabelLine *lline;
+	glLabelLine         *lline;
+	glColorNode         *line_color_node;
 
 	lline = g_object_new (gl_label_line_get_type(), NULL);
 
-	gl_label_object_set_parent (GL_LABEL_OBJECT(lline), label);
+        if (label != NULL)
+        {
+                gl_label_object_set_parent (GL_LABEL_OBJECT(lline), label);
+
+                line_color_node = gl_color_node_new_default ();
+
+                line_color_node->color = gl_label_get_default_line_color(label);
+
+                lline->priv->line_width      = gl_label_get_default_line_width(label);
+                lline->priv->line_color_node = line_color_node;
+        }
 
 	return G_OBJECT (lline);
 }
@@ -327,6 +345,34 @@ draw_shadow (glLabelObject *object,
 }
 
 
+/*****************************************************************************/
+/* Is object at coordinates?                                                 */
+/*****************************************************************************/
+static gboolean
+object_at (glLabelObject *object,
+           cairo_t       *cr,
+           gdouble        x,
+           gdouble        y)
+{
+        gdouble           w, h;
+        gdouble           line_width;
+
+        gl_label_object_get_size (object, &w, &h);
+
+        cairo_move_to (cr, 0, 0);
+        cairo_line_to (cr, w, h);
+
+        line_width = gl_label_object_get_line_width (object);
+        cairo_set_line_width (cr, line_width);
+        if (cairo_in_stroke (cr, x, y))
+        {
+                return TRUE;
+        }
+
+        return FALSE;
+}
+
+
 
 
 /*
diff --git a/src/label-object.c b/src/label-object.c
index 89cefc9..55540bf 100644
--- a/src/label-object.c
+++ b/src/label-object.c
@@ -38,13 +38,23 @@
 #define DEFAULT_SHADOW_Y_OFFSET (3.6)
 #define DEFAULT_SHADOW_OPACITY  (0.5)
 
+#define HANDLE_FILL_RGBA_ARGS      0.0,   0.75,  0.0,   0.4
+#define HANDLE_OUTLINE_RGBA_ARGS   0.0,   0.0,   0.0,   0.8
+
+#define HANDLE_OUTLINE_WIDTH_PIXELS   1.0
+#define HANDLE_PIXELS 7
+
 
 /*========================================================*/
 /* Private types.                                         */
 /*========================================================*/
 
 struct _glLabelObjectPrivate {
+
 	gchar             *name;
+
+        gboolean           selected_flag;
+
 	gdouble            x, y;
 	gdouble            w, h;
         cairo_matrix_t     matrix;
@@ -59,13 +69,8 @@ struct _glLabelObjectPrivate {
 };
 
 enum {
-	CHANGED,
-	MOVED,
-	FLIP_ROTATE,
-	TOP,
-	BOTTOM,
-        REMOVED,
-	LAST_SIGNAL
+        CHANGED,
+        LAST_SIGNAL
 };
 
 
@@ -73,21 +78,18 @@ enum {
 /* Private globals.                                       */
 /*========================================================*/
 
-static guint signals[LAST_SIGNAL] = {0};
-
 static guint instance = 0;
 
+static guint signals[LAST_SIGNAL] = {0};
+
 
 /*========================================================*/
 /* Private function prototypes.                           */
 /*========================================================*/
 
-static void gl_label_object_finalize      (GObject            *object);
-
-static void merge_changed_cb              (glLabel            *label,
-					   glLabelObject      *object);
+static void     gl_label_object_finalize  (GObject            *object);
 
-static void set_size                      (glLabelObject      *object,
+static void     set_size                  (glLabelObject      *object,
 					   gdouble             w,
 					   gdouble             h);
 
@@ -109,7 +111,9 @@ gl_label_object_class_init (glLabelObjectClass *class)
 
 	object_class->finalize = gl_label_object_finalize;
 
-	class->set_size = set_size;
+	class->set_size     = set_size;
+	class->draw_handles = gl_label_object_draw_handles_box; /* Default style */
+	class->handle_at    = gl_label_object_box_handle_at;    /* Default style */
 
 	signals[CHANGED] =
 		g_signal_new ("changed",
@@ -121,53 +125,6 @@ gl_label_object_class_init (glLabelObjectClass *class)
 			      G_TYPE_NONE,
 			      0);
 
-	signals[MOVED] =
-		g_signal_new ("moved",
-			      G_OBJECT_CLASS_TYPE (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (glLabelObjectClass, moved),
-			      NULL, NULL,
-			      gl_marshal_VOID__DOUBLE_DOUBLE,
-			      G_TYPE_NONE,
-			      2, G_TYPE_DOUBLE, G_TYPE_DOUBLE);
-	signals[FLIP_ROTATE] =
-		g_signal_new ("flip_rotate",
-			      G_OBJECT_CLASS_TYPE (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (glLabelObjectClass, flip_rotate),
-			      NULL, NULL,
-			      gl_marshal_VOID__VOID,
-			      G_TYPE_NONE,
-			      0);
-	signals[TOP] =
-		g_signal_new ("top",
-			      G_OBJECT_CLASS_TYPE (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (glLabelObjectClass, top),
-			      NULL, NULL,
-			      gl_marshal_VOID__VOID,
-			      G_TYPE_NONE,
-			      0);
-
-	signals[BOTTOM] =
-		g_signal_new ("bottom",
-			      G_OBJECT_CLASS_TYPE (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (glLabelObjectClass, bottom),
-			      NULL, NULL,
-			      gl_marshal_VOID__VOID,
-			      G_TYPE_NONE,
-			      0);
-	signals[REMOVED] =
-		g_signal_new ("removed",
-			      G_OBJECT_CLASS_TYPE (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (glLabelObjectClass, removed),
-			      NULL, NULL,
-			      gl_marshal_VOID__VOID,
-			      G_TYPE_NONE,
-			      0);
-
 	gl_debug (DEBUG_LABEL, "END");
 }
 
@@ -272,11 +229,10 @@ gl_label_object_dup (glLabelObject *src_object,
 
 	gl_color_node_free (&shadow_color_node);
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(src_object)->copy != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(src_object)->copy != NULL )
+        {
 		/* We have an object specific method, use it */
 		GL_LABEL_OBJECT_GET_CLASS(src_object)->copy (dst_object, src_object);
-
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -286,18 +242,39 @@ gl_label_object_dup (glLabelObject *src_object,
 
 
 /*****************************************************************************/
+/* Copy object interesting object data to clipboard.                         */
+/*****************************************************************************/
+void
+gl_label_object_copy_to_clipboard (glLabelObject     *object,
+                                   GtkClipboard      *clipboard)
+{
+        gl_debug (DEBUG_LABEL, "START");
+
+        g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
+
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->copy_to_clipboard != NULL )
+        {
+		/* We have an object specific method, use it */
+		GL_LABEL_OBJECT_GET_CLASS(object)->copy_to_clipboard (object, clipboard);
+	}
+
+        gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
 /* Emit "changed" signal (for derived objects).                              */
 /*****************************************************************************/
 void
 gl_label_object_emit_changed (glLabelObject *object)
 {
-	gl_debug (DEBUG_LABEL, "START");
+        gl_debug (DEBUG_LABEL, "START");
 
-	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
+        g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
 
-	g_signal_emit (G_OBJECT(object), signals[CHANGED], 0);
+        g_signal_emit (G_OBJECT(object), signals[CHANGED], 0);
 
-	gl_debug (DEBUG_LABEL, "END");
+        gl_debug (DEBUG_LABEL, "END");
 }
 
 
@@ -316,20 +293,15 @@ gl_label_object_set_parent (glLabelObject *object,
 	g_return_if_fail (label && GL_IS_LABEL (label));
 
 	old_parent = object->parent;
-	if ( old_parent != NULL ) {
-		g_signal_handlers_disconnect_by_func (old_parent,
-						      G_CALLBACK(merge_changed_cb),
-						      object);
-		gl_label_remove_object( old_parent, object );
+	if ( old_parent != NULL )
+        {
+                g_object_ref (object);
+		gl_label_delete_object( old_parent, object );
 	}
-	gl_label_add_object( label, object );
-
-	g_signal_connect (G_OBJECT(label), "merge_changed",
-			  G_CALLBACK(merge_changed_cb), object);
-
-	g_signal_emit (G_OBJECT(object), signals[CHANGED], 0);
+        object->parent = label;
+	gl_label_add_object (label, object);
 
-	gl_debug (DEBUG_LABEL, "END");
+        gl_label_object_emit_changed (object);
 }
 
 
@@ -350,38 +322,39 @@ gl_label_object_get_parent (glLabelObject *object)
 
 
 /*****************************************************************************/
-/* Set remove object from parent.                                            */
+/* Select object.                                                            */
 /*****************************************************************************/
 void
-gl_label_object_remove (glLabelObject *object)
+gl_label_object_select (glLabelObject     *object)
 {
-	glLabel *parent;
-
-	gl_debug (DEBUG_LABEL, "START");
-
-	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
-
-	parent = object->parent;
-	if ( parent != NULL ) {
-		g_signal_handlers_disconnect_by_func (parent,
-						      G_CALLBACK(merge_changed_cb),
-						      object);
-		gl_label_remove_object (parent, object);
+        object->priv->selected_flag = TRUE;
+}
 
-                g_signal_emit (G_OBJECT(object), signals[REMOVED], 0);
 
-                g_object_unref (G_OBJECT(object));
-	}
+/*****************************************************************************/
+/* Unselect object.                                                          */
+/*****************************************************************************/
+void
+gl_label_object_unselect (glLabelObject     *object)
+{
+        object->priv->selected_flag = FALSE;
+}
 
 
-	gl_debug (DEBUG_LABEL, "END");
+/*****************************************************************************/
+/* Is object selected?                                                       */
+/*****************************************************************************/
+gboolean
+gl_label_object_is_selected (glLabelObject     *object)
+{
+        return object->priv->selected_flag;
 }
 
 
 /*****************************************************************************/
 /* Set name of object.                                                       */
 /*****************************************************************************/
-void
+void    
 gl_label_object_set_name (glLabelObject *object,
 			  gchar         *name)
 {
@@ -392,7 +365,7 @@ gl_label_object_set_name (glLabelObject *object,
 	g_free(object->priv->name);
 	object->priv->name = name;
 
-	g_signal_emit (G_OBJECT(object), signals[CHANGED], 0);
+        gl_label_object_emit_changed (object);
 
 	gl_debug (DEBUG_LABEL, "END");
 }
@@ -417,29 +390,28 @@ gl_label_object_get_name (glLabelObject *object)
 /*****************************************************************************/
 /* Set position of object.                                                   */
 /*****************************************************************************/
-void
+void    
 gl_label_object_set_position (glLabelObject *object,
 			      gdouble        x,
 			      gdouble        y)
 {
-	gdouble dx, dy;
+	gdouble  dx, dy;
 
 	gl_debug (DEBUG_LABEL, "START");
 
 	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
 
-	if ( (x != object->priv->x) || (y != object->priv->y) ) {
-
+	if ( (x != object->priv->x) || (y != object->priv->y) )
+        {
 		dx = x - object->priv->x;
 		dy = y - object->priv->y;
 
 		object->priv->x = x;
 		object->priv->y = y;
-
-		g_signal_emit (G_OBJECT(object), signals[MOVED], 0, dx, dy);
-
 	}
 
+        gl_label_object_emit_changed (object);
+
 	gl_debug (DEBUG_LABEL, "END");
 }
 
@@ -447,7 +419,7 @@ gl_label_object_set_position (glLabelObject *object,
 /*****************************************************************************/
 /* Set position of object relative to old position.                          */
 /*****************************************************************************/
-void
+void    
 gl_label_object_set_position_relative (glLabelObject *object,
 				       gdouble        dx,
 				       gdouble        dy)
@@ -456,19 +428,18 @@ gl_label_object_set_position_relative (glLabelObject *object,
 
 	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
 
-	if ( (dx != 0.0) || (dy != 0.0) ) {
-
+	if ( (dx != 0.0) || (dy != 0.0) )
+        {
 		object->priv->x += dx;
 		object->priv->y += dy;
 
 		gl_debug (DEBUG_LABEL, "       x = %f, y= %f",
 			  object->priv->x,
 			  object->priv->y);
-
-		g_signal_emit (G_OBJECT(object), signals[MOVED], 0, dx, dy);
-
 	}
 
+        gl_label_object_emit_changed (object);
+
 	gl_debug (DEBUG_LABEL, "END");
 }
 
@@ -502,12 +473,12 @@ set_size (glLabelObject *object,
 {
 	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
 
-	if ( (object->priv->w != w) || (object->priv->h != h) ) {
-
+	if ( (object->priv->w != w) || (object->priv->h != h) )
+        {
 		object->priv->w = w;
 		object->priv->h = h;
 
-		g_signal_emit (G_OBJECT(object), signals[CHANGED], 0);
+                gl_label_object_emit_changed (object);
 	}
 }
 
@@ -515,7 +486,7 @@ set_size (glLabelObject *object,
 /*****************************************************************************/
 /* Set size of object.                                                       */
 /*****************************************************************************/
-void
+void    
 gl_label_object_set_size (glLabelObject *object,
 			  gdouble        w,
 			  gdouble        h)
@@ -524,16 +495,14 @@ gl_label_object_set_size (glLabelObject *object,
 
 	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_size != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_size != NULL )
+        {
 		/* We have an object specific method, use it */
 		GL_LABEL_OBJECT_GET_CLASS(object)->set_size (object, w, h);
 
 		object->priv->aspect_ratio = h / w;
-
 	}
 
-
 	gl_debug (DEBUG_LABEL, "END");
 }
 
@@ -541,7 +510,7 @@ gl_label_object_set_size (glLabelObject *object,
 /*****************************************************************************/
 /* Set size of object honoring current aspect ratio.                         */
 /*****************************************************************************/
-void
+void    
 gl_label_object_set_size_honor_aspect (glLabelObject *object,
 				       gdouble        w,
 				       gdouble        h)
@@ -550,21 +519,19 @@ gl_label_object_set_size_honor_aspect (glLabelObject *object,
 
 	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
 
-	if ( h > w*object->priv->aspect_ratio ) {
-
+	if ( h > w*object->priv->aspect_ratio )
+        {
 		h = w * object->priv->aspect_ratio;
-
-	} else {
-
+	}
+        else
+        {
 		w = h / object->priv->aspect_ratio;
-
 	}
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_size != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_size != NULL )
+        {
 		/* We have an object specific method, use it */
 		GL_LABEL_OBJECT_GET_CLASS(object)->set_size (object, w, h);
-
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -598,15 +565,14 @@ gl_label_object_get_size (glLabelObject *object,
 
 	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_size != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_size != NULL )
+        {
 		/* We have an object specific method, use it */
 		GL_LABEL_OBJECT_GET_CLASS(object)->get_size (object, w, h);
-
-	} else {
-
+	}
+        else
+        {
 		gl_label_object_get_raw_size (object, w, h);
-
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -669,23 +635,21 @@ gl_label_object_can_text (glLabelObject     *object)
 
 	g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family != NULL )
+        {
 		return TRUE;
-
-	} else {
-
+	}
+        else
+        {
 		return FALSE;
-
 	}
-
 }
 
 
 /*****************************************************************************/
 /* Set font family for all text contained in object.                         */
 /*****************************************************************************/
-void
+void    
 gl_label_object_set_font_family (glLabelObject     *object,
 				 const gchar       *font_family)
 {
@@ -693,11 +657,11 @@ gl_label_object_set_font_family (glLabelObject     *object,
 
 	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family != NULL ) {
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family != NULL )
+        {
 
 		/* We have an object specific method, use it */
 		GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family (object, font_family);
-
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -707,7 +671,7 @@ gl_label_object_set_font_family (glLabelObject     *object,
 /****************************************************************************/
 /* Set font size for all text contained in object.                          */
 /****************************************************************************/
-void
+void    
 gl_label_object_set_font_size (glLabelObject     *object,
 			       gdouble            font_size)
 {
@@ -715,11 +679,10 @@ gl_label_object_set_font_size (glLabelObject     *object,
 
 	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_size != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_size != NULL )
+        {
 		/* We have an object specific method, use it */
 		GL_LABEL_OBJECT_GET_CLASS(object)->set_font_size (object, font_size);
-
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -729,7 +692,7 @@ gl_label_object_set_font_size (glLabelObject     *object,
 /****************************************************************************/
 /* Set font weight for all text contained in object.                        */
 /****************************************************************************/
-void
+void    
 gl_label_object_set_font_weight (glLabelObject     *object,
 				 PangoWeight        font_weight)
 {
@@ -737,11 +700,10 @@ gl_label_object_set_font_weight (glLabelObject     *object,
 
 	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_weight != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_weight != NULL )
+        {
 		/* We have an object specific method, use it */
 		GL_LABEL_OBJECT_GET_CLASS(object)->set_font_weight (object, font_weight);
-
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -751,7 +713,7 @@ gl_label_object_set_font_weight (glLabelObject     *object,
 /****************************************************************************/
 /* Set font italic flag for all text contained in object.                   */
 /****************************************************************************/
-void
+void    
 gl_label_object_set_font_italic_flag (glLabelObject     *object,
 				      gboolean           font_italic_flag)
 {
@@ -759,12 +721,10 @@ gl_label_object_set_font_italic_flag (glLabelObject     *object,
 
 	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_italic_flag != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_italic_flag != NULL )
+        {
 		/* We have an object specific method, use it */
-		GL_LABEL_OBJECT_GET_CLASS(object)->set_font_italic_flag (object,
-									 font_italic_flag);
-
+		GL_LABEL_OBJECT_GET_CLASS(object)->set_font_italic_flag (object, font_italic_flag);
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -774,7 +734,7 @@ gl_label_object_set_font_italic_flag (glLabelObject     *object,
 /****************************************************************************/
 /* Set text alignment for all text contained in object.                     */
 /****************************************************************************/
-void
+void    
 gl_label_object_set_text_alignment (glLabelObject     *object,
 				    PangoAlignment     text_alignment)
 {
@@ -782,12 +742,10 @@ gl_label_object_set_text_alignment (glLabelObject     *object,
 
 	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_alignment != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_alignment != NULL )
+        {
 		/* We have an object specific method, use it */
-		GL_LABEL_OBJECT_GET_CLASS(object)->set_text_alignment (object,
-								       text_alignment);
-
+		GL_LABEL_OBJECT_GET_CLASS(object)->set_text_alignment (object, text_alignment);
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -797,7 +755,7 @@ gl_label_object_set_text_alignment (glLabelObject     *object,
 /****************************************************************************/
 /* Set text line spacing for all text contained in object.                  */
 /****************************************************************************/
-void
+void    
 gl_label_object_set_text_line_spacing (glLabelObject     *object,
 			               gdouble            text_line_spacing)
 {
@@ -805,11 +763,10 @@ gl_label_object_set_text_line_spacing (glLabelObject     *object,
 
 	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_line_spacing != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_line_spacing != NULL )
+        {
 		/* We have an object specific method, use it */
 		GL_LABEL_OBJECT_GET_CLASS(object)->set_text_line_spacing (object, text_line_spacing);
-
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -819,7 +776,7 @@ gl_label_object_set_text_line_spacing (glLabelObject     *object,
 /****************************************************************************/
 /* Set text color for all text contained in object.                         */
 /****************************************************************************/
-void
+void    
 gl_label_object_set_text_color (glLabelObject     *object,
 				glColorNode       *text_color_node)
 {
@@ -827,11 +784,10 @@ gl_label_object_set_text_color (glLabelObject     *object,
 
 	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_color != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_color != NULL )
+        {
 		/* We have an object specific method, use it */
 		GL_LABEL_OBJECT_GET_CLASS(object)->set_text_color (object, text_color_node);
-
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -850,11 +806,10 @@ gl_label_object_get_font_family (glLabelObject     *object)
 
 	g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_family != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_family != NULL )
+        {
 		/* We have an object specific method, use it */
 		ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_family (object);
-
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -875,11 +830,10 @@ gl_label_object_get_font_size (glLabelObject     *object)
 
 	g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0.0);
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_size != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_size != NULL )
+        {
 		/* We have an object specific method, use it */
 		ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_size (object);
-
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -900,11 +854,10 @@ gl_label_object_get_font_weight (glLabelObject     *object)
 
 	g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), PANGO_WEIGHT_NORMAL);
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_weight != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_weight != NULL )
+        {
 		/* We have an object specific method, use it */
 		ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_weight (object);
-
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -925,11 +878,10 @@ gl_label_object_get_font_italic_flag (glLabelObject     *object)
 
 	g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_italic_flag != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_italic_flag != NULL )
+        {
 		/* We have an object specific method, use it */
 		ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_italic_flag (object);
-
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -950,11 +902,10 @@ gl_label_object_get_text_alignment (glLabelObject     *object)
 
 	g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), PANGO_ALIGN_LEFT);
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_alignment != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_alignment != NULL )
+        {
 		/* We have an object specific method, use it */
 		ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_alignment (object);
-
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -975,11 +926,10 @@ gl_label_object_get_text_line_spacing (glLabelObject     *object)
 
 	g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0.0);
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_line_spacing != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_line_spacing != NULL )
+        {
 		/* We have an object specific method, use it */
 		ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_line_spacing (object);
-
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -1000,11 +950,10 @@ gl_label_object_get_text_color (glLabelObject     *object)
 
 	g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0);
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_color != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_color != NULL )
+        {
 		/* We have an object specific method, use it */
 		ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_color (object);
-
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -1023,14 +972,13 @@ gl_label_object_can_fill (glLabelObject     *object)
 
 	g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color != NULL )
+        {
 		return TRUE;
-
-	} else {
-
+	}
+        else
+        {
 		return FALSE;
-
 	}
 
 }
@@ -1039,7 +987,7 @@ gl_label_object_can_fill (glLabelObject     *object)
 /****************************************************************************/
 /* Set fill color for object.                                               */
 /****************************************************************************/
-void
+void    
 gl_label_object_set_fill_color (glLabelObject     *object,
 				glColorNode       *fill_color_node)
 {
@@ -1047,11 +995,10 @@ gl_label_object_set_fill_color (glLabelObject     *object,
 
 	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color != NULL )
+        {
 		/* We have an object specific method, use it */
 		GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color (object, fill_color_node);
-
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -1070,11 +1017,10 @@ gl_label_object_get_fill_color (glLabelObject     *object)
 
 	g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0);
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_fill_color != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_fill_color != NULL )
+        {
 		/* We have an object specific method, use it */
 		ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_fill_color (object);
-
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -1093,14 +1039,13 @@ gl_label_object_can_line_color (glLabelObject     *object)
 
 	g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color != NULL )
+        {
 		return TRUE;
-
-	} else {
-
+	}
+        else
+        {
 		return FALSE;
-
 	}
 
 }
@@ -1109,7 +1054,7 @@ gl_label_object_can_line_color (glLabelObject     *object)
 /****************************************************************************/
 /* Set line color for object.                                               */
 /****************************************************************************/
-void
+void    
 gl_label_object_set_line_color (glLabelObject     *object,
 				glColorNode       *line_color_node)
 {
@@ -1117,11 +1062,10 @@ gl_label_object_set_line_color (glLabelObject     *object,
 
 	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color != NULL )
+        {
 		/* We have an object specific method, use it */
 		GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color (object, line_color_node);
-
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -1140,11 +1084,10 @@ gl_label_object_get_line_color (glLabelObject     *object)
 
 	g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0);
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_line_color != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_line_color != NULL )
+        {
 		/* We have an object specific method, use it */
 		ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_line_color (object);
-
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -1163,14 +1106,13 @@ gl_label_object_can_line_width (glLabelObject     *object)
 
 	g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width != NULL )
+        {
 		return TRUE;
-
-	} else {
-
+	}
+        else
+        {
 		return FALSE;
-
 	}
 
 }
@@ -1179,7 +1121,7 @@ gl_label_object_can_line_width (glLabelObject     *object)
 /****************************************************************************/
 /* Set line width for object.                                               */
 /****************************************************************************/
-void
+void    
 gl_label_object_set_line_width (glLabelObject     *object,
 				gdouble            line_width)
 {
@@ -1187,11 +1129,10 @@ gl_label_object_set_line_width (glLabelObject     *object,
 
 	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width != NULL )
+        {
 		/* We have an object specific method, use it */
 		GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width (object, line_width);
-
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -1210,11 +1151,10 @@ gl_label_object_get_line_width (glLabelObject     *object)
 
 	g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0.0);
 
-	if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_line_width != NULL ) {
-
+	if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_line_width != NULL )
+        {
 		/* We have an object specific method, use it */
 		ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_line_width (object);
-
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -1226,7 +1166,7 @@ gl_label_object_get_line_width (glLabelObject     *object)
 /****************************************************************************/
 /* Set shadow state of object.                                              */
 /****************************************************************************/
-void
+void    
 gl_label_object_set_shadow_state (glLabelObject     *object,
 				  gboolean           state)
 {
@@ -1237,7 +1177,6 @@ gl_label_object_set_shadow_state (glLabelObject     *object,
 	if (object->priv->shadow_state != state)
 	{
 		object->priv->shadow_state = state;
-		gl_label_object_emit_changed (object);
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -1261,7 +1200,7 @@ gl_label_object_get_shadow_state (glLabelObject     *object)
 /****************************************************************************/
 /* Set offset of object's shadow.                                           */
 /****************************************************************************/
-void
+void    
 gl_label_object_set_shadow_offset (glLabelObject     *object,
 				   gdouble            x,
 				   gdouble            y)
@@ -1274,8 +1213,6 @@ gl_label_object_set_shadow_offset (glLabelObject     *object,
 	{
 		object->priv->shadow_x = x;
 		object->priv->shadow_y = y;
-
-		gl_label_object_emit_changed (object);
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -1304,7 +1241,7 @@ gl_label_object_get_shadow_offset (glLabelObject     *object,
 /****************************************************************************/
 /* Set color of object's shadow.                                            */
 /****************************************************************************/
-void
+void    
 gl_label_object_set_shadow_color (glLabelObject     *object,
 				  glColorNode       *color_node)
 {
@@ -1316,7 +1253,6 @@ gl_label_object_set_shadow_color (glLabelObject     *object,
 	{
 		gl_color_node_free (&(object->priv->shadow_color_node));
 		object->priv->shadow_color_node = gl_color_node_dup (color_node);
-		gl_label_object_emit_changed (GL_LABEL_OBJECT(object));
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -1340,7 +1276,7 @@ gl_label_object_get_shadow_color (glLabelObject     *object)
 /****************************************************************************/
 /* Set opacity of object's shadow.                                          */
 /****************************************************************************/
-void
+void    
 gl_label_object_set_shadow_opacity (glLabelObject     *object,
 				    gdouble            alpha)
 {
@@ -1351,7 +1287,6 @@ gl_label_object_set_shadow_opacity (glLabelObject     *object,
 	if (object->priv->shadow_opacity != alpha)
 	{
 		object->priv->shadow_opacity = alpha;
-		gl_label_object_emit_changed (object);
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -1387,8 +1322,6 @@ gl_label_object_flip_horiz (glLabelObject *object)
         cairo_matrix_init_scale (&flip_matrix, -1.0, 1.0);
         cairo_matrix_multiply (&object->priv->matrix, &object->priv->matrix, &flip_matrix);
 
-	g_signal_emit (G_OBJECT(object), signals[FLIP_ROTATE], 0);
-
 	gl_debug (DEBUG_LABEL, "END");
 }
 
@@ -1408,8 +1341,6 @@ gl_label_object_flip_vert (glLabelObject *object)
         cairo_matrix_init_scale (&flip_matrix, 1.0, -1.0);
         cairo_matrix_multiply (&object->priv->matrix, &object->priv->matrix, &flip_matrix);
 
-	g_signal_emit (G_OBJECT(object), signals[FLIP_ROTATE], 0);
-
 	gl_debug (DEBUG_LABEL, "END");
 }
 
@@ -1430,8 +1361,6 @@ gl_label_object_rotate (glLabelObject *object,
         cairo_matrix_init_rotate (&rotate_matrix, theta_degs*(G_PI/180.));
         cairo_matrix_multiply (&object->priv->matrix, &object->priv->matrix, &rotate_matrix);
 
-	g_signal_emit (G_OBJECT(object), signals[FLIP_ROTATE], 0);
-
 	gl_debug (DEBUG_LABEL, "END");
 }
 
@@ -1466,57 +1395,6 @@ gl_label_object_get_matrix (glLabelObject  *object,
 }
 
 
-/****************************************************************************/
-/* Bring label object to front/top.                                         */
-/****************************************************************************/
-void
-gl_label_object_raise_to_top (glLabelObject *object)
-{
-	glLabel *label;
-
-	gl_debug (DEBUG_LABEL, "START");
-
-	label = object->parent;
-
-	gl_label_raise_object_to_top (label, object);
-
-	g_signal_emit (G_OBJECT(object), signals[TOP], 0);
-
-	gl_debug (DEBUG_LABEL, "END");
-}
-
-
-/****************************************************************************/
-/* Send label object to rear/bottom.                                        */
-/****************************************************************************/
-void
-gl_label_object_lower_to_bottom (glLabelObject *object)
-{
-	glLabel *label;
-
-	gl_debug (DEBUG_LABEL, "START");
-
-	label = object->parent;
-
-	gl_label_lower_object_to_bottom (label, object);
-
-	g_signal_emit (G_OBJECT(object), signals[BOTTOM], 0);
-
-	gl_debug (DEBUG_LABEL, "END");
-}
-
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Label's merge data changed callback.                           */
-/*--------------------------------------------------------------------------*/
-static void
-merge_changed_cb (glLabel       *label,
-		  glLabelObject *object)
-{
-	gl_label_object_emit_changed (object);
-}
-
-
 /*****************************************************************************/
 /* Draw object                                                               */
 /*****************************************************************************/
@@ -1542,8 +1420,8 @@ gl_label_object_draw (glLabelObject *object,
         cairo_save (cr);
         cairo_translate (cr, x0, y0);
 
-        if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_shadow != NULL ) {
-
+        if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_shadow != NULL )
+        {
                 shadow_state = gl_label_object_get_shadow_state (object);
 
                 if ( shadow_state )
@@ -1563,8 +1441,8 @@ gl_label_object_draw (glLabelObject *object,
                 }
         }
 
-        if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL ) {
-
+        if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL )
+        {
                 cairo_save (cr);
                 cairo_transform (cr, &matrix);
 
@@ -1582,6 +1460,361 @@ gl_label_object_draw (glLabelObject *object,
 }
 
 
+/*****************************************************************************/
+/* Is object located at coordinates.                                         */
+/*****************************************************************************/
+gboolean
+gl_label_object_is_located_at (glLabelObject     *object,
+                               cairo_t           *cr,
+                               gdouble            x_pixels,
+                               gdouble            y_pixels)
+{
+        gboolean            ret_val = FALSE;
+        gdouble             x0, y0;
+        cairo_matrix_t      matrix;
+        gdouble             x, y;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
+
+        if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL )
+        {
+
+                gl_label_object_get_position (object, &x0, &y0);
+                gl_label_object_get_matrix (object, &matrix);
+
+                cairo_save (cr);
+
+                cairo_translate (cr, x0, y0);
+                cairo_transform (cr, &matrix);
+
+                x = x_pixels;
+                y = y_pixels;
+                cairo_device_to_user (cr, &x, &y);
+
+                ret_val = GL_LABEL_OBJECT_GET_CLASS(object)->object_at (object, cr, x, y);
+
+                cairo_restore (cr);
+        }
+
+	gl_debug (DEBUG_LABEL, "END");
+
+        return ret_val;
+}
+
+
+/*****************************************************************************/
+/* Draw object handles                                                       */
+/*****************************************************************************/
+void
+gl_label_object_draw_handles (glLabelObject     *object,
+                              cairo_t           *cr)
+{
+        gdouble        x0, y0;
+        cairo_matrix_t matrix;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
+
+        if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL )
+        {
+
+                gl_label_object_get_position (object, &x0, &y0);
+                gl_label_object_get_matrix (object, &matrix);
+
+                cairo_save (cr);
+
+                cairo_translate (cr, x0, y0);
+                cairo_transform (cr, &matrix);
+
+                GL_LABEL_OBJECT_GET_CLASS(object)->draw_handles (object, cr);
+
+                cairo_restore (cr);
+        }
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*--------------------------------------------------------------------------*/
+/* Draw individual handle                                                   */
+/*--------------------------------------------------------------------------*/
+static void
+draw_handle (cairo_t                *cr,
+             glLabelObject          *object,
+             gdouble                 x_handle,
+             gdouble                 y_handle)
+{
+        gdouble scale_x, scale_y;
+
+
+        gl_debug (DEBUG_VIEW, "START");
+
+        cairo_save (cr);
+
+        cairo_translate (cr, x_handle, y_handle);
+
+        scale_x = 1.0;
+        scale_y = 1.0;
+        cairo_device_to_user_distance (cr, &scale_x, &scale_y);
+        cairo_scale (cr, scale_x, scale_y);
+
+        cairo_rectangle (cr,
+                         -HANDLE_PIXELS/2.0, -HANDLE_PIXELS/2.0,
+                         HANDLE_PIXELS, HANDLE_PIXELS);
+
+        cairo_set_source_rgba (cr, HANDLE_FILL_RGBA_ARGS);
+        cairo_fill_preserve (cr);
+                               
+        cairo_set_line_width (cr, HANDLE_OUTLINE_WIDTH_PIXELS);
+        cairo_set_source_rgba (cr, HANDLE_OUTLINE_RGBA_ARGS);
+        cairo_stroke (cr);
+
+        cairo_restore (cr);
+
+        gl_debug (DEBUG_VIEW, "END");
+}
+
+
+/*--------------------------------------------------------------------------*/
+/* Create handle path                                                       */
+/*--------------------------------------------------------------------------*/
+static void
+create_handle_path (cairo_t                *cr,
+                    glLabelObject          *object,
+                    gdouble                 x_handle,
+                    gdouble                 y_handle)
+{
+        gdouble scale_x, scale_y;
+
+
+        gl_debug (DEBUG_VIEW, "START");
+
+        cairo_save (cr);
+
+        cairo_translate (cr, x_handle, y_handle);
+
+        scale_x = 1.0;
+        scale_y = 1.0;
+        cairo_device_to_user_distance (cr, &scale_x, &scale_y);
+        cairo_scale (cr, scale_x, scale_y);
+
+        cairo_rectangle (cr,
+                         -HANDLE_PIXELS/2.0, -HANDLE_PIXELS/2.0,
+                         HANDLE_PIXELS, HANDLE_PIXELS);
+
+        cairo_restore (cr);
+
+        gl_debug (DEBUG_VIEW, "END");
+}
+
+
+/*****************************************************************************/
+/* Draw box style handles.                                                   */
+/*****************************************************************************/
+void
+gl_label_object_draw_handles_box (glLabelObject     *object,
+                                  cairo_t           *cr)
+{
+        gdouble w, h;
+
+        gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
+
+        /* North */
+        draw_handle (cr, object, w/2, 0);
+
+        /* North East */
+        draw_handle (cr, object, w, 0);
+
+        /* East */
+        draw_handle (cr, object, w, h/2);
+
+        /* South East */
+        draw_handle (cr, object, w, h);
+
+        /* South */
+        draw_handle (cr, object, w/2, h);
+
+        /* South West */
+        draw_handle (cr, object, 0, h);
+
+        /* West */
+        draw_handle (cr, object, 0, h/2);
+
+        /* North West */
+        draw_handle (cr, object, 0, 0);
+}
+
+
+/*****************************************************************************/
+/* Draw line style handles.                                                  */
+/*****************************************************************************/
+void
+gl_label_object_draw_handles_line (glLabelObject     *object,
+                                   cairo_t           *cr)
+{
+        gdouble w, h;
+
+        gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
+
+        /* P2 */
+        draw_handle (cr, object, w, h);
+
+        /* P1 */
+        draw_handle (cr, object, 0, 0);
+}
+
+
+/*****************************************************************************/
+/* Get handle at given coordinates, if any.                                  */
+/*****************************************************************************/
+glLabelObjectHandle
+gl_label_object_handle_at (glLabelObject     *object,
+                           cairo_t           *cr,
+                           gdouble            x_pixels,
+                           gdouble            y_pixels)
+{
+        glLabelObjectHandle handle = GL_LABEL_OBJECT_HANDLE_NONE;
+        gdouble             x0, y0;
+        cairo_matrix_t      matrix;
+        gdouble             x, y;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), handle);
+
+        if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL )
+        {
+
+                gl_label_object_get_position (object, &x0, &y0);
+                gl_label_object_get_matrix (object, &matrix);
+
+                cairo_save (cr);
+
+                cairo_translate (cr, x0, y0);
+                cairo_transform (cr, &matrix);
+
+                x = x_pixels;
+                y = y_pixels;
+                cairo_device_to_user (cr, &x, &y);
+
+                handle = GL_LABEL_OBJECT_GET_CLASS(object)->handle_at (object, cr, x, y);
+
+                cairo_restore (cr);
+        }
+
+	gl_debug (DEBUG_LABEL, "END");
+
+        return handle;
+}
+
+
+/*****************************************************************************/
+/* Get handle at given coordinates for box style handles, if any.            */
+/*****************************************************************************/
+glLabelObjectHandle
+gl_label_object_box_handle_at (glLabelObject     *object,
+                               cairo_t           *cr,
+                               gdouble            x,
+                               gdouble            y)
+{
+        gdouble w, h;
+
+        gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
+
+        /* South East */
+        create_handle_path (cr, object, w, h);
+        if (cairo_in_fill (cr, x, y))
+        {
+                return GL_LABEL_OBJECT_HANDLE_SE;
+        }
+        
+        /* South West */
+        create_handle_path (cr, object, 0, h);
+        if (cairo_in_fill (cr, x, y))
+        {
+                return GL_LABEL_OBJECT_HANDLE_SW;
+        }
+
+        /* North East */
+        create_handle_path (cr, object, w, 0);
+        if (cairo_in_fill (cr, x, y))
+        {
+                return GL_LABEL_OBJECT_HANDLE_NE;
+        }
+
+        /* North West */
+        create_handle_path (cr, object, 0, 0);
+        if (cairo_in_fill (cr, x, y))
+        {
+                return GL_LABEL_OBJECT_HANDLE_NW;
+        }
+
+        /* East */
+        create_handle_path (cr, object, w, h/2);
+        if (cairo_in_fill (cr, x, y))
+        {
+                return GL_LABEL_OBJECT_HANDLE_E;
+        }
+
+        /* South */
+        create_handle_path (cr, object, w/2, h);
+        if (cairo_in_fill (cr, x, y))
+        {
+                return GL_LABEL_OBJECT_HANDLE_S;
+        }
+
+        /* West */
+        create_handle_path (cr, object, 0, h/2);
+        if (cairo_in_fill (cr, x, y))
+        {
+                return GL_LABEL_OBJECT_HANDLE_W;
+        }
+
+        /* North */
+        create_handle_path (cr, object, w/2, 0);
+        if (cairo_in_fill (cr, x, y))
+        {
+                return GL_LABEL_OBJECT_HANDLE_N;
+        }
+
+        return GL_LABEL_OBJECT_HANDLE_NONE;
+}
+
+
+/*****************************************************************************/
+/* Get handle at given coordinates for line style handles, if any.           */
+/*****************************************************************************/
+glLabelObjectHandle
+gl_label_object_line_handle_at (glLabelObject     *object,
+                                cairo_t           *cr,
+                                gdouble            x,
+                                gdouble            y)
+{
+        gdouble w, h;
+
+        gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
+
+        /* P2 */
+        create_handle_path (cr, object, w, h);
+        if (cairo_in_fill (cr, x, y))
+        {
+                return GL_LABEL_OBJECT_HANDLE_P2;
+        }
+        
+        /* P1 */
+        create_handle_path (cr, object, 0, h);
+        if (cairo_in_fill (cr, x, y))
+        {
+                return GL_LABEL_OBJECT_HANDLE_P1;
+        }
+
+        return GL_LABEL_OBJECT_HANDLE_NONE;
+}
+
+
 
 
 /*
diff --git a/src/label-object.h b/src/label-object.h
index 15cc5e9..eeb586d 100644
--- a/src/label-object.h
+++ b/src/label-object.h
@@ -22,11 +22,13 @@
 #define __LABEL_OBJECT_H__
 
 #include <glib-object.h>
+#include <gtk/gtk.h>
 #include <pango/pango.h>
 #include <cairo.h>
 
 G_BEGIN_DECLS
 
+
 typedef enum {
         GL_LABEL_OBJECT_TEXT,
         GL_LABEL_OBJECT_BOX,
@@ -38,6 +40,21 @@ typedef enum {
 } glLabelObjectType;
 
 
+typedef enum {
+        GL_LABEL_OBJECT_HANDLE_NONE = 0,
+        GL_LABEL_OBJECT_HANDLE_N,
+        GL_LABEL_OBJECT_HANDLE_E,
+        GL_LABEL_OBJECT_HANDLE_W,
+        GL_LABEL_OBJECT_HANDLE_S,
+        GL_LABEL_OBJECT_HANDLE_NW,
+        GL_LABEL_OBJECT_HANDLE_NE,
+        GL_LABEL_OBJECT_HANDLE_SE,
+        GL_LABEL_OBJECT_HANDLE_SW,
+        GL_LABEL_OBJECT_HANDLE_P1,
+        GL_LABEL_OBJECT_HANDLE_P2,
+} glLabelObjectHandle;
+
+
 #define GL_TYPE_LABEL_OBJECT              (gl_label_object_get_type ())
 #define GL_LABEL_OBJECT(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), GL_TYPE_LABEL_OBJECT, glLabelObject))
 #define GL_LABEL_OBJECT_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GL_TYPE_LABEL_OBJECT, glLabelObjectClass))
@@ -66,17 +83,13 @@ struct _glLabelObjectClass {
         GObjectClass          parent_class;
 
         /*
-         * Methods
+         * Set/Get Methods
          */
 
         void              (*set_size)             (glLabelObject     *object,
                                                    gdouble            w,
                                                    gdouble            h);
 
-        void              (*get_size)             (glLabelObject     *object,
-                                                   gdouble           *w,
-                                                   gdouble           *h);
-
         void              (*set_font_family)      (glLabelObject     *object,
                                                    const gchar       *font_family);
 
@@ -92,8 +105,8 @@ struct _glLabelObjectClass {
         void              (*set_text_alignment)   (glLabelObject     *object,
                                                    PangoAlignment     text_alignment);
 
-        void              (*set_text_line_spacing) (glLabelObject    *object,
-                                                    gdouble           text_line_spacing);
+        void              (*set_text_line_spacing)(glLabelObject     *object,
+                                                   gdouble            text_line_spacing);
 
         void              (*set_text_color)       (glLabelObject     *object,
                                                    glColorNode       *text_color_node);
@@ -107,7 +120,11 @@ struct _glLabelObjectClass {
         void              (*set_line_width)       (glLabelObject     *object,
                                                    gdouble            line_width);
 
-        gchar            *(*get_font_family)      (glLabelObject     *object);
+        void              (*get_size)             (glLabelObject     *object,
+                                                   gdouble           *w,
+                                                   gdouble           *h);
+
+        gchar *           (*get_font_family)      (glLabelObject     *object);
 
         gdouble           (*get_font_size)        (glLabelObject     *object);
 
@@ -119,17 +136,21 @@ struct _glLabelObjectClass {
 
         gdouble           (*get_text_line_spacing) (glLabelObject    *object);
 
-        glColorNode*      (*get_text_color)       (glLabelObject     *object);
+        glColorNode *     (*get_text_color)       (glLabelObject     *object);
 
-        glColorNode*      (*get_fill_color)       (glLabelObject     *object);
+        glColorNode *     (*get_fill_color)       (glLabelObject     *object);
 
-        glColorNode*      (*get_line_color)       (glLabelObject     *object);
+        glColorNode *     (*get_line_color)       (glLabelObject     *object);
 
         gdouble           (*get_line_width)       (glLabelObject     *object);
 
-        void              (*copy)                 (glLabelObject     *dst_object,
+        void              (*copy)                 (glLabelObject     *dst_object
+,
                                                    glLabelObject     *src_object);
 
+        void              (*copy_to_clipboard)    (glLabelObject     *object,
+                                                   GtkClipboard      *clipboard);
+
         /*
          * Draw methods
          */
@@ -143,32 +164,34 @@ struct _glLabelObjectClass {
                                          gboolean       screen_flag,
                                          glMergeRecord *record);
 
+        void        (*draw_handles)     (glLabelObject *object,
+                                         cairo_t       *cr);
 
         /*
-         * Signals
+         * Cairo context query methods
          */
-        void (*changed)     (glLabelObject     *object,
-                             gpointer            user_data);
+        gboolean            (*object_at) (glLabelObject     *object,
+                                          cairo_t           *cr,
+                                          gdouble            x_pixels,
+                                          gdouble            y_pixels);
 
-        void (*moved)       (glLabelObject     *object,
-                             gdouble            dx,
-                             gdouble            dy,
-                             gpointer           user_data);
+        glLabelObjectHandle (*handle_at) (glLabelObject     *object,
+                                          cairo_t           *cr,
+                                          gdouble            x_pixels,
+                                          gdouble            y_pixels);
 
-        void (*flip_rotate) (glLabelObject     *object,
-                             gpointer           user_data);
 
-        void (*top)         (glLabelObject     *object,
-                             gpointer           user_data);
-
-        void (*bottom)      (glLabelObject     *object,
-                             gpointer           user_data);
+        /*
+         * Signals
+         */
 
-        void (*removed)     (glLabelObject     *object,
-                             gpointer            user_data);
+        void        (*changed) (glLabelObject *object,
+                                gpointer       user_data);
 
 };
 
+
+
 GType          gl_label_object_get_type              (void) G_GNUC_CONST;
 
 GObject       *gl_label_object_new                   (glLabel           *label);
@@ -177,8 +200,12 @@ GObject       *gl_label_object_new                   (glLabel           *label);
 glLabelObject *gl_label_object_dup                   (glLabelObject     *src_object,
                                                       glLabel           *label);
 
-void           gl_label_object_emit_changed          (glLabelObject     *object);
 
+void           gl_label_object_copy_to_clipboard     (glLabelObject     *object,
+                                                      GtkClipboard      *clipboard);
+
+
+void           gl_label_object_emit_changed          (glLabelObject     *object);
 
 void           gl_label_object_set_parent            (glLabelObject     *object,
                                                       glLabel           *label);
@@ -186,7 +213,9 @@ void           gl_label_object_set_parent            (glLabelObject     *object,
 glLabel       *gl_label_object_get_parent            (glLabelObject     *object);
 
 
-void           gl_label_object_remove                (glLabelObject     *object);
+void           gl_label_object_select                (glLabelObject     *object);
+void           gl_label_object_unselect              (glLabelObject     *object);
+gboolean       gl_label_object_is_selected           (glLabelObject     *object);
 
 void           gl_label_object_set_name              (glLabelObject     *object,
                                                       gchar             *name);
@@ -202,10 +231,6 @@ void           gl_label_object_set_position_relative (glLabelObject     *object,
                                                       gdouble            dx,
                                                       gdouble            dy);
 
-void           gl_label_object_get_position          (glLabelObject     *object,
-                                                      gdouble           *x,
-                                                      gdouble           *y);
-
 void           gl_label_object_set_size              (glLabelObject     *object,
                                                       gdouble            w,
                                                       gdouble            h);
@@ -214,19 +239,6 @@ void           gl_label_object_set_size_honor_aspect (glLabelObject     *object,
                                                       gdouble            w,
                                                       gdouble            h);
 
-void           gl_label_object_get_size              (glLabelObject     *object,
-                                                      gdouble           *w,
-                                                      gdouble           *h);
-
-void           gl_label_object_get_raw_size          (glLabelObject     *object,
-                                                      gdouble           *w,
-                                                      gdouble           *h);
-
-void           gl_label_object_get_extent            (glLabelObject     *object,
-                                                      glLabelRegion     *region);
-
-gboolean       gl_label_object_can_text              (glLabelObject     *object);
-
 void           gl_label_object_set_font_family       (glLabelObject     *object,
                                                       const gchar       *font_family);
 
@@ -248,75 +260,90 @@ void           gl_label_object_set_text_color        (glLabelObject     *object,
 void           gl_label_object_set_text_line_spacing (glLabelObject     *object,
                                                       gdouble            text_line_spacing);
 
+void           gl_label_object_set_fill_color        (glLabelObject     *object,
+                                                      glColorNode       *fill_color_node);
 
-gchar           *gl_label_object_get_font_family       (glLabelObject     *object);
+void           gl_label_object_set_line_color        (glLabelObject     *object,
+                                                      glColorNode       *line_color_node);
 
-gdouble          gl_label_object_get_font_size         (glLabelObject     *object);
+void           gl_label_object_set_line_width        (glLabelObject     *object,
+                                                      gdouble            line_width);
 
-PangoWeight      gl_label_object_get_font_weight       (glLabelObject     *object);
 
-gboolean         gl_label_object_get_font_italic_flag  (glLabelObject     *object);
+void           gl_label_object_set_shadow_state      (glLabelObject     *object,
+                                                      gboolean           state);
 
-PangoAlignment   gl_label_object_get_text_alignment    (glLabelObject     *object);
+void           gl_label_object_set_shadow_offset     (glLabelObject     *object,
+                                                      gdouble            x,
+                                                      gdouble            y);
 
-gdouble          gl_label_object_get_text_line_spacing (glLabelObject     *object);
+void           gl_label_object_set_shadow_color      (glLabelObject     *object,
+                                                      glColorNode       *color_node);
 
-glColorNode     *gl_label_object_get_text_color        (glLabelObject     *object);
+void           gl_label_object_set_shadow_opacity    (glLabelObject     *object,
+                                                      gdouble            alpha);
 
 
-gboolean       gl_label_object_can_fill              (glLabelObject     *object);
+void           gl_label_object_flip_horiz            (glLabelObject     *object);
 
-void           gl_label_object_set_fill_color        (glLabelObject     *object,
-                                                      glColorNode       *fill_color_node);
+void           gl_label_object_flip_vert             (glLabelObject     *object);
 
-glColorNode*   gl_label_object_get_fill_color        (glLabelObject     *object);
+void           gl_label_object_rotate                (glLabelObject     *object,
+                                                      gdouble            theta_degs);
 
+void           gl_label_object_set_matrix            (glLabelObject     *object,
+                                                      cairo_matrix_t    *matrix);
 
-gboolean       gl_label_object_can_line_color        (glLabelObject     *object);
 
-void           gl_label_object_set_line_color        (glLabelObject     *object,
-                                                      glColorNode       *line_color_node);
+void           gl_label_object_get_position          (glLabelObject     *object,
+                                                      gdouble           *x,
+                                                      gdouble           *y);
 
-glColorNode   *gl_label_object_get_line_color        (glLabelObject     *object);
+void           gl_label_object_get_size              (glLabelObject     *object,
+                                                      gdouble           *w,
+                                                      gdouble           *h);
 
-gboolean       gl_label_object_can_line_width        (glLabelObject     *object);
+void           gl_label_object_get_raw_size          (glLabelObject     *object,
+                                                      gdouble           *w,
+                                                      gdouble           *h);
 
-void           gl_label_object_set_line_width        (glLabelObject     *object,
-                                                      gdouble            line_width);
+void           gl_label_object_get_extent            (glLabelObject     *object,
+                                                      glLabelRegion     *region);
 
-gdouble        gl_label_object_get_line_width        (glLabelObject     *object);
+gboolean       gl_label_object_can_text              (glLabelObject     *object);
 
 
-void           gl_label_object_raise_to_top          (glLabelObject     *object);
+gchar         *gl_label_object_get_font_family       (glLabelObject     *object);
 
-void           gl_label_object_lower_to_bottom       (glLabelObject     *object);
+gdouble        gl_label_object_get_font_size         (glLabelObject     *object);
 
+PangoWeight    gl_label_object_get_font_weight       (glLabelObject     *object);
 
-void           gl_label_object_flip_horiz            (glLabelObject     *object);
+gboolean       gl_label_object_get_font_italic_flag  (glLabelObject     *object);
 
-void           gl_label_object_flip_vert             (glLabelObject     *object);
+PangoAlignment gl_label_object_get_text_alignment    (glLabelObject     *object);
 
-void           gl_label_object_rotate                (glLabelObject     *object,
-                                                      gdouble            theta_degs);
+gdouble        gl_label_object_get_text_line_spacing (glLabelObject     *object);
 
-void           gl_label_object_set_matrix            (glLabelObject     *object,
-                                                      cairo_matrix_t    *matrix);
+glColorNode   *gl_label_object_get_text_color        (glLabelObject     *object);
 
-void           gl_label_object_get_matrix            (glLabelObject     *object,
-                                                      cairo_matrix_t    *matrix);
 
-void           gl_label_object_set_shadow_state      (glLabelObject     *object,
-                                                      gboolean           state);
+gboolean       gl_label_object_can_fill              (glLabelObject     *object);
 
-void           gl_label_object_set_shadow_offset     (glLabelObject     *object,
-                                                      gdouble            x,
-                                                      gdouble            y);
+glColorNode*   gl_label_object_get_fill_color        (glLabelObject     *object);
 
-void           gl_label_object_set_shadow_color      (glLabelObject     *object,
-                                                      glColorNode       *color_node);
 
-void           gl_label_object_set_shadow_opacity    (glLabelObject     *object,
-                                                      gdouble            alpha);
+gboolean       gl_label_object_can_line_color        (glLabelObject     *object);
+
+glColorNode   *gl_label_object_get_line_color        (glLabelObject     *object);
+
+gboolean       gl_label_object_can_line_width        (glLabelObject     *object);
+
+gdouble        gl_label_object_get_line_width        (glLabelObject     *object);
+
+
+void           gl_label_object_get_matrix            (glLabelObject     *object,
+                                                      cairo_matrix_t    *matrix);
 
 gboolean       gl_label_object_get_shadow_state      (glLabelObject     *object);
 
@@ -328,11 +355,48 @@ glColorNode*   gl_label_object_get_shadow_color      (glLabelObject     *object)
 
 gdouble        gl_label_object_get_shadow_opacity    (glLabelObject     *object);
 
+
 void           gl_label_object_draw                  (glLabelObject     *object,
                                                       cairo_t           *cr,
                                                       gboolean           screen_flag,
                                                       glMergeRecord     *record);
 
+gboolean       gl_label_object_is_located_at         (glLabelObject     *object,
+                                                      cairo_t           *cr,
+                                                      gdouble            x_pixels,
+                                                      gdouble            y_pixels);
+
+void           gl_label_object_draw_handles          (glLabelObject     *object,
+                                                      cairo_t           *cr);
+
+glLabelObjectHandle gl_label_object_handle_at        (glLabelObject     *object,
+                                                      cairo_t           *cr,
+                                                      gdouble            x_pixels,
+                                                      gdouble            y_pixels);
+
+
+/*
+ * Specific handle drawing methods.
+ */
+void           gl_label_object_draw_handles_box      (glLabelObject     *object,
+                                                      cairo_t           *cr);
+
+void           gl_label_object_draw_handles_line     (glLabelObject     *object,
+                                                      cairo_t           *cr);
+
+
+/*
+ * Specific handle query methods.
+ */
+glLabelObjectHandle gl_label_object_box_handle_at    (glLabelObject     *object,
+                                                      cairo_t           *cr,
+                                                      gdouble            x,
+                                                      gdouble            y);
+
+glLabelObjectHandle gl_label_object_line_handle_at   (glLabelObject     *object,
+                                                      cairo_t           *cr,
+                                                      gdouble            x,
+                                                      gdouble            y);
 
 
 
diff --git a/src/label-text.c b/src/label-text.c
index 9a28dcb..dd9f565 100644
--- a/src/label-text.c
+++ b/src/label-text.c
@@ -37,15 +37,6 @@
 /* Private macros and constants.                          */
 /*========================================================*/
 
-#define DEFAULT_FONT_FAMILY       "Sans"
-#define DEFAULT_FONT_SIZE         14.0
-#define DEFAULT_FONT_WEIGHT       PANGO_WEIGHT_NORMAL
-#define DEFAULT_FONT_ITALIC_FLAG  FALSE
-#define DEFAULT_ALIGN             PANGO_ALIGN_LEFT
-#define DEFAULT_COLOR             GL_COLOR (0,0,0)
-#define DEFAULT_TEXT_LINE_SPACING 1.0
-#define DEFAULT_AUTO_SHRINK       FALSE
-
 #define FONT_SCALE (72.0/96.0)
 
 
@@ -86,6 +77,9 @@ static void gl_label_text_finalize      (GObject          *object);
 static void copy                        (glLabelObject    *dst_object,
 					 glLabelObject    *src_object);
 
+static void copy_to_clipboard           (glLabelObject    *object,
+                                         GtkClipboard     *clipboard);
+
 static void buffer_changed_cb           (GtkTextBuffer    *textbuffer,
 					 glLabelText      *ltext);
 
@@ -152,6 +146,11 @@ static gdouble         auto_shrink_font_size       (cairo_t          *cr,
                                                     gchar            *text,
                                                     gdouble           width);
 
+static gboolean        object_at                   (glLabelObject    *object,
+                                                    cairo_t          *cr,
+                                                    gdouble           x_pixels,
+                                                    gdouble           y_pixels);
+
 
 /*****************************************************************************/
 /* Object infrastructure.                                                    */
@@ -172,6 +171,8 @@ gl_label_text_class_init (glLabelTextClass *class)
 
 	label_object_class->copy                  = copy;
 
+	label_object_class->copy_to_clipboard     = copy_to_clipboard;
+
 	label_object_class->get_size              = get_size;
 
 	label_object_class->set_font_family       = set_font_family;
@@ -190,6 +191,7 @@ gl_label_text_class_init (glLabelTextClass *class)
 	label_object_class->get_text_color        = get_text_color;
         label_object_class->draw_object           = draw_object;
         label_object_class->draw_shadow           = draw_shadow;
+        label_object_class->object_at             = object_at;
 
 	object_class->finalize = gl_label_text_finalize;
 }
@@ -206,16 +208,6 @@ gl_label_text_init (glLabelText *ltext)
 	ltext->priv->tag_table         = gtk_text_tag_table_new ();
 	ltext->priv->buffer            = gtk_text_buffer_new (ltext->priv->tag_table);
 
-	ltext->priv->font_family       = g_strdup(DEFAULT_FONT_FAMILY);
-	ltext->priv->font_size         = DEFAULT_FONT_SIZE;
-	ltext->priv->font_weight       = DEFAULT_FONT_WEIGHT;
-	ltext->priv->font_italic_flag  = DEFAULT_FONT_ITALIC_FLAG;
-	ltext->priv->align             = DEFAULT_ALIGN;
-	ltext->priv->color_node        = gl_color_node_new_default ();
-	ltext->priv->color_node->color = DEFAULT_COLOR;
-	ltext->priv->line_spacing      = DEFAULT_TEXT_LINE_SPACING;
-	ltext->priv->auto_shrink       = DEFAULT_AUTO_SHRINK;
-
         ltext->priv->size_changed      = TRUE;
 
 	g_signal_connect (G_OBJECT(ltext->priv->buffer), "changed",
@@ -249,11 +241,27 @@ gl_label_text_finalize (GObject *object)
 GObject *
 gl_label_text_new (glLabel *label)
 {
-	glLabelText *ltext;
+	glLabelText   *ltext;
+        glColorNode   *color_node;
 
 	ltext = g_object_new (gl_label_text_get_type(), NULL);
 
-	gl_label_object_set_parent (GL_LABEL_OBJECT(ltext), label);
+        if (label != NULL)
+        {
+                gl_label_object_set_parent (GL_LABEL_OBJECT(ltext), label);
+
+                color_node = gl_color_node_new_default ();
+
+                color_node->color = gl_label_get_default_text_color (label);
+
+                ltext->priv->font_family      = gl_label_get_default_font_family (label);
+                ltext->priv->font_size        = gl_label_get_default_font_size (label);
+                ltext->priv->font_weight      = gl_label_get_default_font_weight (label);
+                ltext->priv->font_italic_flag = gl_label_get_default_font_italic_flag (label);
+                ltext->priv->align            = gl_label_get_default_text_alignment (label);
+		ltext->priv->color_node       = color_node;	  
+                ltext->priv->line_spacing     = gl_label_get_default_text_line_spacing (label);
+        }
 
 	return G_OBJECT (ltext);
 }
@@ -300,6 +308,33 @@ copy (glLabelObject *dst_object,
 }
 
 
+/*---------------------------------------------------------------------------*/
+/* Private.  Copy text to clipboard.                                         */
+/*---------------------------------------------------------------------------*/
+static void
+copy_to_clipboard (glLabelObject     *object,
+                   GtkClipboard      *clipboard)
+{
+        glLabelText *ltext;
+	GtkTextIter  start, end;
+	gchar       *text;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (object && GL_IS_LABEL_TEXT (object));
+
+        ltext = GL_LABEL_TEXT (object);
+
+	gtk_text_buffer_get_bounds (ltext->priv->buffer, &start, &end);
+	text = gtk_text_buffer_get_text (ltext->priv->buffer,
+					 &start, &end, FALSE);
+
+        gtk_clipboard_set_text (clipboard, text, -1);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
 /*****************************************************************************/
 /* Set object params.                                                        */
 /*****************************************************************************/
@@ -1042,6 +1077,30 @@ auto_shrink_font_size (cairo_t     *cr,
 }
 
 
+/*****************************************************************************/
+/* Is object at coordinates?                                                 */
+/*****************************************************************************/
+static gboolean
+object_at (glLabelObject *object,
+           cairo_t       *cr,
+           gdouble        x,
+           gdouble        y)
+{
+        gdouble           w, h;
+
+        gl_label_object_get_size (object, &w, &h);
+
+        cairo_rectangle (cr, 0.0, 0.0, w, h);
+
+        if (cairo_in_fill (cr, x, y))
+        {
+                return TRUE;
+        }
+
+        return FALSE;
+}
+
+
 
 /*
  * Local Variables:       -- emacs
diff --git a/src/label-text.h b/src/label-text.h
index 9c7ce43..07086e1 100644
--- a/src/label-text.h
+++ b/src/label-text.h
@@ -30,12 +30,12 @@ G_BEGIN_DECLS
 #define GL_LABEL_TEXT_MARGIN 3.0
 
 
-#define GL_TYPE_LABEL_TEXT               (gl_label_text_get_type ())
-#define GL_LABEL_TEXT(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GL_TYPE_LABEL_TEXT, glLabelText))
-#define GL_LABEL_TEXT_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GL_TYPE_LABEL_TEXT, glLabelTextClass))
-#define GL_IS_LABEL_TEXT(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GL_TYPE_LABEL_TEXT))
-#define GL_IS_LABEL_TEXT_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GL_TYPE_LABEL_TEXT))
-#define GL_COLOR_COMBO_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS ((object), GL_TYPE_LABEL_TEXT, glLabelTextClass))
+#define GL_TYPE_LABEL_TEXT              (gl_label_text_get_type ())
+#define GL_LABEL_TEXT(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), GL_TYPE_LABEL_TEXT, glLabelText))
+#define GL_LABEL_TEXT_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GL_TYPE_LABEL_TEXT, glLabelTextClass))
+#define GL_IS_LABEL_TEXT(obj)           (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GL_TYPE_LABEL_TEXT))
+#define GL_IS_LABEL_TEXT_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GL_TYPE_LABEL_TEXT))
+#define GL_LABEL_TEXT_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS ((object), GL_TYPE_LABEL_TEXT, glLabelTextClass))
 
 
 typedef struct _glLabelText          glLabelText;
diff --git a/src/label.c b/src/label.c
index 9de9a73..b361685 100644
--- a/src/label.c
+++ b/src/label.c
@@ -23,9 +23,12 @@
 #include "label.h"
 
 #include <glib/gi18n.h>
+#include <math.h>
 
 #include "template-history.h"
 #include "file-util.h"
+#include "xml-label.h"
+#include "prefs.h"
 #include "marshal.h"
 
 #include "debug.h"
@@ -35,6 +38,8 @@
 /* Private macros and constants.                          */
 /*========================================================*/
 
+#define GLABELS_CLIPBOARD gdk_atom_intern ("GLABELS", FALSE)
+
 
 /*========================================================*/
 /* Private types.                                         */
@@ -47,18 +52,44 @@ struct _glLabelPrivate {
 	gboolean     modified_flag;
 	gint         untitled_instance;
 
+        lglTemplate *template;
+        gboolean     rotate_flag;
+
+        GList       *object_list;
+
 	glMerge     *merge;
 
 	GHashTable  *pixbuf_cache;
+
+        /* Delay changed signals while operating on selections of multiple objects. */
+        gboolean     selection_op_flag;
+        gboolean     delayed_change_flag;
+
+	/* Default object text properties */
+	gchar             *default_font_family;
+	gdouble            default_font_size;
+	PangoWeight        default_font_weight;
+	gboolean           default_font_italic_flag;
+	guint              default_text_color;
+	PangoAlignment     default_text_alignment;
+	gdouble            default_text_line_spacing;
+
+	/* Default object line properties */
+	gdouble            default_line_width;
+	guint              default_line_color;
+	
+	/* Default object fill properties */
+	guint              default_fill_color;
+
 };
 
 enum {
+	SELECTION_CHANGED,
 	CHANGED,
 	NAME_CHANGED,
 	MODIFIED_CHANGED,
 	MERGE_CHANGED,
 	SIZE_CHANGED,
-        OBJECT_ADDED,
 	LAST_SIGNAL
 };
 
@@ -79,12 +110,16 @@ static guint untitled = 0;
 static void gl_label_finalize      (GObject *object);
 
 static void object_changed_cb      (glLabelObject *object,
-				    glLabel       *label);
+                                    glLabel       *label);
+
+static void do_modify              (glLabel       *label);
 
-static void object_moved_cb        (glLabelObject *object,
-			            gdouble        x,
-				    gdouble        y,
-				    glLabel       *label);
+static void begin_selection_op     (glLabel       *label);
+static void end_selection_op       (glLabel       *label);
+
+static void paste_received_cb      (GtkClipboard  *clipboard,
+                                    const gchar   *buffer,
+                                    glLabel       *label);
 
 
 /*****************************************************************************/
@@ -104,6 +139,15 @@ gl_label_class_init (glLabelClass *class)
 
 	object_class->finalize = gl_label_finalize;
 
+	signals[SELECTION_CHANGED] =
+		g_signal_new ("selection_changed",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (glLabelClass, selection_changed),
+			      NULL, NULL,
+			      gl_marshal_VOID__VOID,
+			      G_TYPE_NONE,
+			      0);
 	signals[CHANGED] =
 		g_signal_new ("changed",
 			      G_OBJECT_CLASS_TYPE (object_class),
@@ -149,15 +193,6 @@ gl_label_class_init (glLabelClass *class)
 			      gl_marshal_VOID__VOID,
 			      G_TYPE_NONE,
 			      0);
-	signals[OBJECT_ADDED] =
-		g_signal_new ("object_added",
-			      G_OBJECT_CLASS_TYPE (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (glLabelClass, object_added),
-			      NULL, NULL,
-			      gl_marshal_VOID__OBJECT,
-			      G_TYPE_NONE,
-			      1, G_TYPE_OBJECT);
 
 	gl_debug (DEBUG_LABEL, "END");
 }
@@ -168,16 +203,33 @@ gl_label_init (glLabel *label)
 {
 	gl_debug (DEBUG_LABEL, "START");
 
-	label->template     = NULL;
-	label->rotate_flag  = FALSE;
-        label->objects      = NULL;
-
 	label->priv = g_new0 (glLabelPrivate, 1);
 
-	label->priv->filename     = NULL;
+	label->priv->template     = NULL;
+	label->priv->rotate_flag  = FALSE;
+        label->priv->object_list  = NULL;
+
+	label->priv->filename      = NULL;
+	label->priv->modified_flag = FALSE;
+	label->priv->compression   = 9;
+
 	label->priv->merge        = NULL;
 	label->priv->pixbuf_cache = gl_pixbuf_cache_new ();
 
+        /*
+         * Defaults from preferences
+         */
+	label->priv->default_font_family       = gl_prefs_model_get_default_font_family (gl_prefs);
+	label->priv->default_font_size         = gl_prefs_model_get_default_font_size (gl_prefs);
+	label->priv->default_font_weight       = gl_prefs_model_get_default_font_weight (gl_prefs);
+	label->priv->default_font_italic_flag  = gl_prefs_model_get_default_font_italic_flag (gl_prefs);
+	label->priv->default_text_color        = gl_prefs_model_get_default_text_color (gl_prefs);
+	label->priv->default_text_alignment    = gl_prefs_model_get_default_text_alignment (gl_prefs);
+	label->priv->default_text_line_spacing = gl_prefs_model_get_default_text_line_spacing (gl_prefs);
+	label->priv->default_line_width        = gl_prefs_model_get_default_line_width (gl_prefs);
+	label->priv->default_line_color        = gl_prefs_model_get_default_line_color (gl_prefs);
+	label->priv->default_fill_color        = gl_prefs_model_get_default_fill_color (gl_prefs);
+
 	gl_debug (DEBUG_LABEL, "END");
 }
 
@@ -186,23 +238,26 @@ static void
 gl_label_finalize (GObject *object)
 {
 	glLabel *label = GL_LABEL (object);
-	GList   *p, *p_next;
+	GList   *p;
 
 	gl_debug (DEBUG_LABEL, "START");
 
 	g_return_if_fail (object && GL_IS_LABEL (object));
 
-	for (p = label->objects; p != NULL; p = p_next) {
-		p_next = p->next;	/* NOTE: p will be left dangling */
+	for (p = label->priv->object_list; p != NULL; p = p->next)
+        {
 		g_object_unref (G_OBJECT(p->data));
 	}
+        g_list_free (label->priv->object_list);
 
-	lgl_template_free (label->template);
+	lgl_template_free (label->priv->template);
 	g_free (label->priv->filename);
-	if (label->priv->merge != NULL) {
+	if (label->priv->merge != NULL)
+        {
 		g_object_unref (G_OBJECT(label->priv->merge));
 	}
 	gl_pixbuf_cache_free (label->priv->pixbuf_cache);
+        g_free (label->priv->default_font_family);
 
 	g_free (label->priv);
 
@@ -212,6 +267,9 @@ gl_label_finalize (GObject *object)
 }
 
 
+/*****************************************************************************/
+/* New label.                                                                */
+/*****************************************************************************/
 GObject *
 gl_label_new (void)
 {
@@ -221,172 +279,221 @@ gl_label_new (void)
 
 	label = g_object_new (gl_label_get_type(), NULL);
 
-	label->priv->compression = 9;
-
-	label->priv->modified_flag = FALSE;
-
 	gl_debug (DEBUG_LABEL, "END");
 
 	return G_OBJECT (label);
 }
 
 
-/*****************************************************************************/
-/* Add object to label.                                                      */
-/*****************************************************************************/
+/****************************************************************************/
+/* Set filename.                                                            */
+/****************************************************************************/
 void
-gl_label_add_object (glLabel       *label,
-		     glLabelObject *object)
+gl_label_set_filename (glLabel     *label,
+		       const gchar *filename)
 {
-	gl_debug (DEBUG_LABEL, "START");
-
-	g_return_if_fail (label && GL_IS_LABEL (label));
-	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
-
-	object->parent = label;
-	label->objects = g_list_append (label->objects, g_object_ref (object));
-
-	label->priv->modified_flag = TRUE;
+	label->priv->filename = g_strdup (filename);
 
-	g_signal_emit (G_OBJECT(label), signals[OBJECT_ADDED], 0, object);
-	g_signal_emit (G_OBJECT(label), signals[CHANGED], 0);
-	g_signal_emit (G_OBJECT(label), signals[MODIFIED_CHANGED], 0);
+	g_signal_emit (G_OBJECT(label), signals[NAME_CHANGED], 0);
+}
 
-	g_signal_connect (G_OBJECT(object), "changed",
-			  G_CALLBACK(object_changed_cb), label);
 
-	g_signal_connect (G_OBJECT(object), "moved",
-			  G_CALLBACK(object_moved_cb), label);
+/****************************************************************************/
+/* return filename.                                                         */
+/****************************************************************************/
+gchar *
+gl_label_get_filename (glLabel *label)
+{
+	gl_debug (DEBUG_LABEL, "");
 
-	gl_debug (DEBUG_LABEL, "END");
+	return g_strdup ( label->priv->filename );
 }
 
 
-/*****************************************************************************/
-/* Remove object from label.                                                 */
-/*****************************************************************************/
-void
-gl_label_remove_object (glLabel       *label,
-			glLabelObject *object)
+/****************************************************************************/
+/* return short filename.                                                   */
+/****************************************************************************/
+gchar *
+gl_label_get_short_name (glLabel *label)
 {
-	gl_debug (DEBUG_LABEL, "START");
-
-	g_return_if_fail (label && GL_IS_LABEL (label));
-	g_return_if_fail (GL_IS_LABEL_OBJECT (object));
+	gl_debug (DEBUG_LABEL, "");
 
-	object->parent = NULL;
-	label->objects = g_list_remove (label->objects, object);
+	if ( label->priv->filename == NULL )
+        {
 
-	if ( G_OBJECT(label)->ref_count /* not finalized */ ) {
+		if ( label->priv->untitled_instance == 0 )
+                {
+			label->priv->untitled_instance = ++untitled;
+		}
 
-		g_signal_handlers_disconnect_by_func (object,
-						      G_CALLBACK(object_changed_cb),
-						      label);
-		g_signal_handlers_disconnect_by_func (object,
-						      G_CALLBACK(object_moved_cb),
-						      label);
+		return g_strdup_printf ( "%s %d", _("Untitled"),
+					 label->priv->untitled_instance );
 
-		label->priv->modified_flag = TRUE;
+	}
+        else
+        {
+		gchar *temp_name, *short_name;
 
-		g_signal_emit (G_OBJECT(label), signals[CHANGED], 0);
-		g_signal_emit (G_OBJECT(label), signals[MODIFIED_CHANGED], 0);
+		temp_name = g_path_get_basename ( label->priv->filename );
+		short_name = gl_file_util_remove_extension (temp_name);
+		g_free (temp_name);
 
+		return short_name;
 	}
-
-	gl_debug (DEBUG_LABEL, "END");
 }
 
 
-/*---------------------------------------------------------------------------*/
-/* PRIVATE.  Object changed callback.                                        */
-/*---------------------------------------------------------------------------*/
-static void
-object_changed_cb (glLabelObject *object,
-		   glLabel       *label)
+/****************************************************************************/
+/* Is label untitled?                                                       */
+/****************************************************************************/
+gboolean
+gl_label_is_untitled (glLabel *label)
 {
+	gl_debug (DEBUG_LABEL, "return %d",(label->priv->filename == NULL));
+	return (label->priv->filename == NULL);
+}
 
-	if ( !label->priv->modified_flag ) {
 
-		label->priv->modified_flag = TRUE;
+/****************************************************************************/
+/* Set compression level.                                                   */
+/****************************************************************************/
+void
+gl_label_set_compression (glLabel  *label,
+			  gint      compression)
+{
+	gl_debug (DEBUG_LABEL, "set %d", compression);
 
-		g_signal_emit (G_OBJECT(label), signals[MODIFIED_CHANGED], 0);
+	/* Older versions of libxml2 always return a -1 for documents "read in," so
+	 * default to 9.  Also, default to 9 for anything else out of range. */
+	if ((compression < 0) || (compression >9))
+        {
+		compression = 9;
 	}
 
-	g_signal_emit (G_OBJECT(label), signals[CHANGED], 0);
+	gl_debug (DEBUG_LABEL, "actual set %d", compression);
+	label->priv->compression = compression;
 }
 
 
-/*---------------------------------------------------------------------------*/
-/* PRIVATE.  Object moved callback.                                          */
-/*---------------------------------------------------------------------------*/
-static void
-object_moved_cb (glLabelObject *object,
-		 gdouble        x,
-		 gdouble        y,
-		 glLabel       *label)
+/****************************************************************************/
+/* Get compression level.                                                   */
+/****************************************************************************/
+gint
+gl_label_get_compression (glLabel *label)
+{
+	gl_debug (DEBUG_LABEL, "return %d", label->priv->compression);
+	return label->priv->compression;
+}
+
+
+/****************************************************************************/
+/* Set modified flag.                                                       */
+/****************************************************************************/
+void
+gl_label_set_modified (glLabel *label)
 {
 
-	if ( !label->priv->modified_flag ) {
+	if ( !label->priv->modified_flag )
+        {
 
 		label->priv->modified_flag = TRUE;
 
 		g_signal_emit (G_OBJECT(label), signals[MODIFIED_CHANGED], 0);
 	}
 
-	g_signal_emit (G_OBJECT(label), signals[CHANGED], 0);
 }
 
 
 /****************************************************************************/
-/* Bring label object to front/top.                                         */
+/* Clear modified flag.                                                     */
 /****************************************************************************/
 void
-gl_label_raise_object_to_top (glLabel       *label,
-			      glLabelObject *object)
+gl_label_clear_modified (glLabel *label)
 {
-	gl_debug (DEBUG_LABEL, "START");
 
-	/* Move to end of list, representing front most object */
-	label->objects = g_list_remove (label->objects, object);
-	label->objects = g_list_append (label->objects, object);
+	if ( label->priv->modified_flag )
+        {
+		label->priv->modified_flag = FALSE;
 
-	label->priv->modified_flag = TRUE;
+		g_signal_emit (G_OBJECT(label), signals[MODIFIED_CHANGED], 0);
+	}
 
-	g_signal_emit (G_OBJECT(label), signals[MODIFIED_CHANGED], 0);
-	g_signal_emit (G_OBJECT(label), signals[CHANGED], 0);
+}
 
-	gl_debug (DEBUG_LABEL, "END");
+
+/****************************************************************************/
+/* Is label modified?                                                       */
+/****************************************************************************/
+gboolean
+gl_label_is_modified (glLabel *label)
+{
+	gl_debug (DEBUG_LABEL, "return %d", label->priv->modified_flag);
+	return label->priv->modified_flag;
 }
 
 
 /****************************************************************************/
-/* Send label object to rear/bottom.                                        */
+/* Object "changed" callback.                                               */
 /****************************************************************************/
-void
-gl_label_lower_object_to_bottom (glLabel       *label,
-				 glLabelObject *object)
+static void
+object_changed_cb (glLabelObject *object,
+                   glLabel       *label)
 {
-	gl_debug (DEBUG_LABEL, "START");
+        do_modify (label);
+}
 
-	/* Move to front of list, representing rear most object */
-	label->objects = g_list_remove (label->objects, object);
-	label->objects = g_list_prepend (label->objects, object);
 
-	label->priv->modified_flag = TRUE;
+/****************************************************************************/
+/* Do modify.                                                               */
+/****************************************************************************/
+static void
+do_modify (glLabel  *label)
+{
+        if ( label->priv->selection_op_flag )
+        {
+                label->priv->delayed_change_flag = TRUE;
+        }
+        else
+        {
+                label->priv->modified_flag = TRUE;
 
-	g_signal_emit (G_OBJECT(label), signals[MODIFIED_CHANGED], 0);
-	g_signal_emit (G_OBJECT(label), signals[CHANGED], 0);
+                g_signal_emit (G_OBJECT(label), signals[MODIFIED_CHANGED], 0);
+                g_signal_emit (G_OBJECT(label), signals[CHANGED], 0);
+        }
+}
 
-	gl_debug (DEBUG_LABEL, "END");
+
+/****************************************************************************/
+/* Begin selection operation.                                               */
+/****************************************************************************/
+static void
+begin_selection_op (glLabel  *label)
+{
+        label->priv->selection_op_flag = TRUE;
+}
+
+
+/****************************************************************************/
+/* End selection operation.                                                 */
+/****************************************************************************/
+static void
+end_selection_op (glLabel  *label)
+{
+        label->priv->selection_op_flag = FALSE;
+        if ( label->priv->delayed_change_flag )
+        {
+                label->priv->delayed_change_flag = FALSE;
+                do_modify (label);
+        }
 }
 
 
 /****************************************************************************/
 /* set template.                                                            */
 /****************************************************************************/
-extern void
-gl_label_set_template (glLabel     *label,
-		       lglTemplate *template)
+void
+gl_label_set_template (glLabel           *label,
+		       const lglTemplate *template)
 {
         gchar *name;
 
@@ -395,17 +502,15 @@ gl_label_set_template (glLabel     *label,
 	g_return_if_fail (label && GL_IS_LABEL (label));
 	g_return_if_fail (template);
 
-	if ((label->template == NULL) ||
-            !lgl_template_do_templates_match (template, label->template)) {
-
-		lgl_template_free (label->template);
-		label->template = lgl_template_dup (template);
+	if ((label->priv->template == NULL) ||
+            !lgl_template_do_templates_match (template, label->priv->template))
+        {
 
-		label->priv->modified_flag = TRUE;
+		lgl_template_free (label->priv->template);
+		label->priv->template = lgl_template_dup (template);
 
-		g_signal_emit (G_OBJECT(label), signals[MODIFIED_CHANGED], 0);
+                do_modify (label);
 		g_signal_emit (G_OBJECT(label), signals[SIZE_CHANGED], 0);
-		g_signal_emit (G_OBJECT(label), signals[CHANGED], 0);
 
                 name = lgl_template_get_name (template);
                 gl_template_history_model_add_name (gl_template_history, name);
@@ -417,9 +522,19 @@ gl_label_set_template (glLabel     *label,
 
 
 /****************************************************************************/
+/* get template.                                                            */
+/****************************************************************************/
+const lglTemplate *
+gl_label_get_template (glLabel            *label)
+{
+        return label->priv->template;
+}
+
+
+/****************************************************************************/
 /* set rotate flag.                                                         */
 /****************************************************************************/
-extern void
+void
 gl_label_set_rotate_flag (glLabel *label,
 			  gboolean rotate_flag)
 {
@@ -427,16 +542,12 @@ gl_label_set_rotate_flag (glLabel *label,
 
 	g_return_if_fail (label && GL_IS_LABEL (label));
 
-	if (rotate_flag != label->rotate_flag) {
-
-		label->rotate_flag = rotate_flag;
-
-		label->priv->modified_flag = TRUE;
+	if (rotate_flag != label->priv->rotate_flag)
+        {
+		label->priv->rotate_flag = rotate_flag;
 
-		g_signal_emit (G_OBJECT(label), signals[MODIFIED_CHANGED], 0);
+                do_modify (label);
 		g_signal_emit (G_OBJECT(label), signals[SIZE_CHANGED], 0);
-		g_signal_emit (G_OBJECT(label), signals[CHANGED], 0);
-
 	}
 
 	gl_debug (DEBUG_LABEL, "END");
@@ -444,6 +555,16 @@ gl_label_set_rotate_flag (glLabel *label,
 
 
 /****************************************************************************/
+/* Get rotate flag.                                                         */
+/****************************************************************************/
+gboolean
+gl_label_get_rotate_flag (glLabel       *label)
+{
+        return label->priv->rotate_flag;
+}
+
+
+/****************************************************************************/
 /* Get label size.                                                          */
 /****************************************************************************/
 void
@@ -458,17 +579,21 @@ gl_label_get_size (glLabel *label,
 
 	g_return_if_fail (label && GL_IS_LABEL (label));
 
-	template = label->template;
-	if ( !template ) {
+	template = label->priv->template;
+	if ( !template )
+        {
 		gl_debug (DEBUG_LABEL, "END -- template NULL");
 		*w = *h = 0;
 		return;
 	}
         frame = (lglTemplateFrame *)template->frames->data;
 
-	if (!label->rotate_flag) {
+	if (!label->priv->rotate_flag)
+        {
 		lgl_template_frame_get_size (frame, w, h);
-	} else {
+	}
+        else
+        {
 		lgl_template_frame_get_size (frame, h, w);
 	}
 
@@ -479,7 +604,7 @@ gl_label_get_size (glLabel *label,
 /****************************************************************************/
 /* set merge information structure.                                         */
 /****************************************************************************/
-extern void
+void
 gl_label_set_merge (glLabel *label,
 		    glMerge *merge)
 {
@@ -487,16 +612,14 @@ gl_label_set_merge (glLabel *label,
 
 	g_return_if_fail (label && GL_IS_LABEL (label));
 
-	if ( label->priv->merge != NULL ) {
+	if ( label->priv->merge != NULL )
+        {
 		g_object_unref (G_OBJECT(label->priv->merge));
 	}
 	label->priv->merge = gl_merge_dup (merge);
 
-	label->priv->modified_flag = TRUE;
-
+        do_modify (label);
 	g_signal_emit (G_OBJECT(label), signals[MERGE_CHANGED], 0);
-	g_signal_emit (G_OBJECT(label), signals[MODIFIED_CHANGED], 0);
-	g_signal_emit (G_OBJECT(label), signals[CHANGED], 0);
 
 	gl_debug (DEBUG_LABEL, "END");
 }
@@ -519,156 +642,1989 @@ gl_label_get_merge (glLabel *label)
 
 
 /****************************************************************************/
-/* return filename.                                                         */
+/* Get pixbuf cache.                                                        */
 /****************************************************************************/
-gchar *
-gl_label_get_filename (glLabel *label)
+GHashTable *
+gl_label_get_pixbuf_cache (glLabel       *label)
+{
+	return label->priv->pixbuf_cache;
+}
+
+
+/*****************************************************************************/
+/* Add object to label.                                                      */
+/*****************************************************************************/
+void
+gl_label_add_object (glLabel       *label,
+		     glLabelObject *object)
+{
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
+
+	object->parent = label;
+	label->priv->object_list = g_list_append (label->priv->object_list, object);
+
+        g_signal_connect (G_OBJECT (object), "changed",
+                          G_CALLBACK (object_changed_cb), label);
+
+        do_modify (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Delete object from label.                                                 */
+/*****************************************************************************/
+void
+gl_label_delete_object (glLabel       *label,
+                        glLabelObject *object)
+{
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
+
+        label->priv->object_list = g_list_remove (label->priv->object_list, object);
+
+        g_signal_handlers_disconnect_by_func (G_OBJECT (object),
+                                              G_CALLBACK (object_changed_cb), label);
+        g_object_unref (object);
+
+        do_modify (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Get object list.                                                          */
+/*****************************************************************************/
+const GList *
+gl_label_get_object_list (glLabel       *label)
+{
+        return label->priv->object_list;
+}
+
+
+/*****************************************************************************/
+/* Select object.                                                            */
+/*****************************************************************************/
+void
+gl_label_select_object (glLabel       *label,
+                        glLabelObject *object)
+{
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
+
+        gl_label_object_select (object);
+
+	g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Unselect object.                                                          */
+/*****************************************************************************/
+void
+gl_label_unselect_object (glLabel       *label,
+                          glLabelObject *object)
+{
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
+
+        gl_label_object_unselect (object);
+
+	g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Select all objects.                                                       */
+/*****************************************************************************/
+void
+gl_label_select_all (glLabel       *label)
+{
+	GList         *p;
+        glLabelObject *object;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+        for ( p = label->priv->object_list; p != NULL; p = p->next )
+        {
+                object = GL_LABEL_OBJECT (p->data);
+
+                gl_label_object_select (object);
+        }
+
+	g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Unselect all objects.                                                     */
+/*****************************************************************************/
+void
+gl_label_unselect_all (glLabel       *label)
+{
+	GList         *p;
+        glLabelObject *object;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+        for ( p = label->priv->object_list; p != NULL; p = p->next )
+        {
+                object = GL_LABEL_OBJECT (p->data);
+
+                gl_label_object_unselect (object);
+        }
+
+	g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Select all objects contained in region.                                   */
+/*****************************************************************************/
+void
+gl_label_select_region (glLabel       *label,
+                        glLabelRegion *region)
+{
+	GList         *p;
+	glLabelObject *object;
+        gdouble        r_x1, r_y1;
+        gdouble        r_x2, r_y2;
+        glLabelRegion  obj_extent;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+        r_x1 = MIN (region->x1, region->x2);
+        r_y1 = MIN (region->y1, region->y2);
+        r_x2 = MAX (region->x1, region->x2);
+        r_y2 = MAX (region->y1, region->y2);
+
+	for (p = label->priv->object_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT(p->data);
+
+                gl_label_object_get_extent (object, &obj_extent);
+                if ((obj_extent.x1 >= r_x1) &&
+                    (obj_extent.x2 <= r_x2) &&
+                    (obj_extent.y1 >= r_y1) &&
+                    (obj_extent.y2 <= r_y2))
+                {
+                        gl_label_object_select (object);
+                }
+	}
+
+	g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Is selection empty?                                                       */
+/*****************************************************************************/
+gboolean
+gl_label_is_selection_empty (glLabel       *label)
+{
+        GList         *p;
+        glLabelObject *object;
+
+        for ( p = label->priv->object_list; p != NULL; p = p->next )
+        {
+                object = GL_LABEL_OBJECT (p->data);
+
+                if ( gl_label_object_is_selected (object) )
+                {
+                        return FALSE;
+                }
+        }
+
+        return TRUE;
+}
+
+
+/*****************************************************************************/
+/* Is selection atomic?                                                      */
+/*****************************************************************************/
+gboolean
+gl_label_is_selection_atomic (glLabel       *label)
+{
+        GList         *p;
+        glLabelObject *object;
+        gint           n_selected = 0;
+
+        for ( p = label->priv->object_list; p != NULL; p = p->next )
+        {
+                object = GL_LABEL_OBJECT (p->data);
+
+                if ( gl_label_object_is_selected (object) )
+                {
+                        n_selected++;
+
+                        if (n_selected > 1)
+                        {
+                                return FALSE;
+                        }
+                }
+        }
+
+        return (n_selected == 1);
+}
+
+
+/*****************************************************************************/
+/* Get first selected object.                                                */
+/*****************************************************************************/
+glLabelObject *
+gl_label_get_1st_selected_object (glLabel  *label)
+{
+        GList         *p;
+        glLabelObject *object;
+
+        for ( p = label->priv->object_list; p != NULL; p = p->next )
+        {
+                object = GL_LABEL_OBJECT (p->data);
+
+                if ( gl_label_object_is_selected (object) )
+                {
+                        return object;
+                }
+        }
+
+        return NULL;
+}
+
+
+/*****************************************************************************/
+/* Get list of selected objects.                                             */
+/*****************************************************************************/
+GList *
+gl_label_get_selection_list (glLabel *label)
+{
+        GList         *selection_list = NULL;
+        GList         *p;
+        glLabelObject *object;
+
+        for ( p = label->priv->object_list; p != NULL; p = p->next )
+        {
+                object = GL_LABEL_OBJECT (p->data);
+
+                if ( gl_label_object_is_selected (object) )
+                {
+                        selection_list = g_list_append (selection_list, object);
+                }
+        }
+
+        return (selection_list);
+}
+
+
+/*****************************************************************************/
+/* Can text properties be set for selection?                                 */
+/*****************************************************************************/
+gboolean
+gl_label_can_selection_text (glLabel *label)
 {
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+
 	gl_debug (DEBUG_LABEL, "");
 
-	return g_strdup ( label->priv->filename );
+	g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
+
+        selection_list = gl_label_get_selection_list (label);
+
+	for (p = selection_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+
+		if (gl_label_object_can_text (object))
+                {
+                        g_list_free (selection_list);
+			return TRUE;
+		}
+	}
+
+        g_list_free (selection_list);
+	return FALSE;
+}
+
+
+/*****************************************************************************/
+/* Can fill properties be set for selection?                                 */
+/*****************************************************************************/
+gboolean
+gl_label_can_selection_fill (glLabel *label)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+
+	gl_debug (DEBUG_LABEL, "");
+
+	g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
+
+        selection_list = gl_label_get_selection_list (label);
+
+	for (p = selection_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+
+		if (gl_label_object_can_fill (object))
+                {
+                        g_list_free (selection_list);
+			return TRUE;
+		}
+
+	}
+
+        g_list_free (selection_list);
+	return FALSE;
+}
+
+
+/*****************************************************************************/
+/* Can line color properties be set for selection?                           */
+/*****************************************************************************/
+gboolean
+gl_label_can_selection_line_color (glLabel *label)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+
+	gl_debug (DEBUG_LABEL, "");
+
+	g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
+
+        selection_list = gl_label_get_selection_list (label);
+
+	for (p = selection_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+
+		if (gl_label_object_can_line_color (object))
+                {
+                        g_list_free (selection_list);
+			return TRUE;
+		}
+	}
+
+        g_list_free (selection_list);
+	return FALSE;
+}
+
+
+/*****************************************************************************/
+/* Can line width properties be set for selection?                           */
+/*****************************************************************************/
+gboolean
+gl_label_can_selection_line_width (glLabel *label)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+
+	gl_debug (DEBUG_LABEL, "");
+
+	g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
+
+        selection_list = gl_label_get_selection_list (label);
+
+	for (p = selection_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+
+		if (gl_label_object_can_line_width (object))
+                {
+                        g_list_free (selection_list);
+			return TRUE;
+		}
+
+	}
+
+        g_list_free (selection_list);
+	return FALSE;
+}
+
+
+/*****************************************************************************/
+/* Delete selection from label.                                              */
+/*****************************************************************************/
+void
+gl_label_delete_selection (glLabel       *label)
+{
+        GList         *selection_list;
+        GList         *p;
+        glLabelObject *object;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+        begin_selection_op (label);
+
+        selection_list = gl_label_get_selection_list (label);
+
+        for ( p = selection_list; p != NULL; p = p->next )
+        {
+                object = GL_LABEL_OBJECT (p->data);
+
+                gl_label_delete_object (label, object);
+        }
+
+        g_list_free (selection_list);
+
+        end_selection_op (label);
+
+	gl_debug (DEBUG_LABEL, "END");
 }
 
 
 /****************************************************************************/
-/* return short filename.                                                   */
+/* Bring selection object to front/top.                                     */
 /****************************************************************************/
-gchar *
-gl_label_get_short_name (glLabel *label)
+void
+gl_label_raise_selection_to_top (glLabel       *label)
 {
-	gl_debug (DEBUG_LABEL, "");
+        GList         *selection_list;
+        GList         *p;
+        glLabelObject *object;
 
-	if ( label->priv->filename == NULL ) {
+	gl_debug (DEBUG_LABEL, "START");
 
-		if ( label->priv->untitled_instance == 0 ) {
-			label->priv->untitled_instance = ++untitled;
+        selection_list = gl_label_get_selection_list (label);
+
+        for ( p = selection_list; p != NULL; p = p->next )
+        {
+                object = GL_LABEL_OBJECT (p->data);
+
+                label->priv->object_list = g_list_remove (label->priv->object_list, object);
+        }
+
+	/* Move to end of list, representing front most object */
+	label->priv->object_list = g_list_concat (label->priv->object_list, selection_list);
+
+        do_modify (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/****************************************************************************/
+/* Send selection to rear/bottom.                                           */
+/****************************************************************************/
+void
+gl_label_lower_selection_to_bottom (glLabel       *label)
+{
+        GList         *selection_list;
+        GList         *p;
+        glLabelObject *object;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+        selection_list = gl_label_get_selection_list (label);
+
+        for ( p = selection_list; p != NULL; p = p->next )
+        {
+                object = GL_LABEL_OBJECT (p->data);
+
+                label->priv->object_list = g_list_remove (label->priv->object_list, object);
+        }
+
+	/* Move to front of list, representing rear most object */
+	label->priv->object_list = g_list_concat (selection_list, label->priv->object_list);
+
+        do_modify (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Rotate selected objects by given angle.                                   */
+/*****************************************************************************/
+void
+gl_label_rotate_selection (glLabel *label,
+                           gdouble  theta_degs)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+        begin_selection_op (label);
+
+        selection_list = gl_label_get_selection_list (label);
+
+        for ( p = selection_list; p != NULL; p = p->next )
+        {
+		object = GL_LABEL_OBJECT (p->data);
+
+		gl_label_object_rotate (object, theta_degs);
+	}
+
+        g_list_free (selection_list);
+
+        end_selection_op (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Rotate selected objects 90 degrees left.                                  */
+/*****************************************************************************/
+void
+gl_label_rotate_selection_left (glLabel *label)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+        begin_selection_op (label);
+
+        selection_list = gl_label_get_selection_list (label);
+
+        for ( p = selection_list; p != NULL; p = p->next )
+        {
+		object = GL_LABEL_OBJECT (p->data);
+
+		gl_label_object_rotate (object, -90.0);
+	}
+
+        g_list_free (selection_list);
+
+        end_selection_op (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Rotate selected objects 90 degrees right.                                 */
+/*****************************************************************************/
+void
+gl_label_rotate_selection_right (glLabel *label)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+        begin_selection_op (label);
+
+        selection_list = gl_label_get_selection_list (label);
+
+        for ( p = selection_list; p != NULL; p = p->next )
+        {
+		object = GL_LABEL_OBJECT (p->data);
+
+		gl_label_object_rotate (object, 90.0);
+	}
+
+        g_list_free (selection_list);
+
+        end_selection_op (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Flip selected objects horizontally.                                       */
+/*****************************************************************************/
+void
+gl_label_flip_selection_horiz (glLabel *label)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+        begin_selection_op (label);
+
+        selection_list = gl_label_get_selection_list (label);
+
+        for ( p = selection_list; p != NULL; p = p->next )
+        {
+		object = GL_LABEL_OBJECT (p->data);
+
+		gl_label_object_flip_horiz (object);
+	}
+
+        g_list_free (selection_list);
+
+        end_selection_op (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Flip selected objects vertically.                                         */
+/*****************************************************************************/
+void
+gl_label_flip_selection_vert (glLabel *label)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+        begin_selection_op (label);
+
+        selection_list = gl_label_get_selection_list (label);
+
+        for ( p = selection_list; p != NULL; p = p->next )
+        {
+		object = GL_LABEL_OBJECT (p->data);
+
+		gl_label_object_flip_vert (object);
+	}
+
+        g_list_free (selection_list);
+
+        end_selection_op (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Align selected objects to left most edge.                                 */
+/*****************************************************************************/
+void
+gl_label_align_selection_left (glLabel *label)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+	gdouble        dx, x1_min;
+        glLabelRegion  obj_extent;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+	g_return_if_fail (!gl_label_is_selection_empty (label) &&
+			  !gl_label_is_selection_atomic (label));
+
+        begin_selection_op (label);
+
+        selection_list = gl_label_get_selection_list (label);
+
+	/* find left most edge */
+	p = selection_list;
+	object = GL_LABEL_OBJECT (p->data);
+
+	gl_label_object_get_extent (object, &obj_extent);
+        x1_min = obj_extent.x1;
+	for (p = p->next; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+
+		gl_label_object_get_extent (object, &obj_extent);
+		if ( obj_extent.x1 < x1_min ) x1_min = obj_extent.x1;
+	}
+
+	/* now adjust the object positions to line up the left edges */
+	for (p = selection_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+
+		gl_label_object_get_extent (object, &obj_extent);
+		dx = x1_min - obj_extent.x1;
+		gl_label_object_set_position_relative (object, dx, 0.0);
+	}
+
+        g_list_free (selection_list);
+
+        end_selection_op (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Align selected objects to right most edge.                                */
+/*****************************************************************************/
+void
+gl_label_align_selection_right (glLabel *label)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+	gdouble        dx, x2_max;
+        glLabelRegion  obj_extent;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+	g_return_if_fail (!gl_label_is_selection_empty (label) &&
+			  !gl_label_is_selection_atomic (label));
+
+        begin_selection_op (label);
+
+        selection_list = gl_label_get_selection_list (label);
+
+	/* find left most edge */
+	p = selection_list;
+	object = GL_LABEL_OBJECT (p->data);
+
+	gl_label_object_get_extent (object, &obj_extent);
+        x2_max = obj_extent.x2;
+	for (p = p->next; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+
+		gl_label_object_get_extent (object, &obj_extent);
+		if ( obj_extent.x2 > x2_max ) x2_max = obj_extent.x2;
+	}
+
+	/* now adjust the object positions to line up the left edges */
+	for (p = selection_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+
+		gl_label_object_get_extent (object, &obj_extent);
+		dx = x2_max - obj_extent.x2;
+		gl_label_object_set_position_relative (object, dx, 0.0);
+	}
+
+        g_list_free (selection_list);
+
+        end_selection_op (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Align selected objects to horizontal center of objects.                   */
+/*****************************************************************************/
+void
+gl_label_align_selection_hcenter (glLabel *label)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+	gdouble        dx;
+	gdouble        dxmin;
+	gdouble        xsum, xavg;
+        glLabelRegion  obj_extent;
+	gdouble        xcenter;
+	gint           n;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+	g_return_if_fail (!gl_label_is_selection_empty (label) &&
+			  !gl_label_is_selection_atomic (label));
+
+        begin_selection_op (label);
+
+        selection_list = gl_label_get_selection_list (label);
+
+	/* find average center of objects */
+	xsum = 0.0;
+	n = 0;
+	for (p = selection_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+
+		gl_label_object_get_extent (object, &obj_extent);
+		xsum += (obj_extent.x1 + obj_extent.x2) / 2.0;
+		n++;
+	}
+	xavg = xsum / n;
+
+	/* find center of object closest to average center */
+	p = selection_list;
+	object = GL_LABEL_OBJECT (p->data);
+
+	gl_label_object_get_extent (object, &obj_extent);
+	dxmin = fabs (xavg - (obj_extent.x1 + obj_extent.x2)/2.0);
+	xcenter = (obj_extent.x1 + obj_extent.x2)/2.0;
+	for (p = p->next; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+
+		gl_label_object_get_extent (object, &obj_extent);
+		dx = fabs (xavg - (obj_extent.x1 + obj_extent.x2)/2.0);
+		if ( dx < dxmin )
+                {
+			dxmin = dx;
+			xcenter = (obj_extent.x1 + obj_extent.x2)/2.0;
 		}
+	}
 
-		return g_strdup_printf ( "%s %d", _("Untitled"),
-					 label->priv->untitled_instance );
+	/* now adjust the object positions to line up this center */
+	for (p = selection_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
 
-	} else {
-		gchar *temp_name, *short_name;
+		gl_label_object_get_extent (object, &obj_extent);
+		dx = xcenter - (obj_extent.x1 + obj_extent.x2)/2.0;
+		gl_label_object_set_position_relative (object, dx, 0.0);
+	}
 
-		temp_name = g_path_get_basename ( label->priv->filename );
-		short_name = gl_file_util_remove_extension (temp_name);
-		g_free (temp_name);
+        g_list_free (selection_list);
 
-		return short_name;
+        end_selection_op (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Align selected objects to top most edge.                                  */
+/*****************************************************************************/
+void
+gl_label_align_selection_top (glLabel *label)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+	gdouble        dy, y1_min;
+        glLabelRegion  obj_extent;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+	g_return_if_fail (!gl_label_is_selection_empty (label) &&
+			  !gl_label_is_selection_atomic (label));
+
+        begin_selection_op (label);
+
+        selection_list = gl_label_get_selection_list (label);
+
+	/* find top most edge */
+	p = selection_list;
+	object = GL_LABEL_OBJECT (p->data);
+
+	gl_label_object_get_extent (object, &obj_extent);
+        y1_min = obj_extent.y1;
+	for (p = p->next; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+
+		gl_label_object_get_extent (object, &obj_extent);
+		if ( obj_extent.y1 < y1_min ) y1_min = obj_extent.y1;
+	}
+
+	/* now adjust the object positions to line up the top edges */
+	for (p = selection_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+
+		gl_label_object_get_extent (object, &obj_extent);
+		dy = y1_min - obj_extent.y1;
+		gl_label_object_set_position_relative (object, 0.0, dy);
+	}
+
+        g_list_free (selection_list);
+
+        end_selection_op (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Align selected objects to bottom most edge.                               */
+/*****************************************************************************/
+void
+gl_label_align_selection_bottom (glLabel *label)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+	gdouble        dy, y2_max;
+        glLabelRegion  obj_extent;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+	g_return_if_fail (!gl_label_is_selection_empty (label) &&
+			  !gl_label_is_selection_atomic (label));
+
+        begin_selection_op (label);
+
+        selection_list = gl_label_get_selection_list (label);
+
+	/* find bottom most edge */
+	p = selection_list;
+	object = GL_LABEL_OBJECT (p->data);
+
+	gl_label_object_get_extent (object, &obj_extent);
+        y2_max = obj_extent.y2;
+	for (p = p->next; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+
+		gl_label_object_get_extent (object, &obj_extent);
+		if ( obj_extent.y2 > y2_max ) y2_max = obj_extent.y2;
+	}
+
+	/* now adjust the object positions to line up the bottom edges */
+	for (p = selection_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+
+		gl_label_object_get_extent (object, &obj_extent);
+		dy = y2_max - obj_extent.y2;
+		gl_label_object_set_position_relative (object, 0.0, dy);
+	}
+
+        g_list_free (selection_list);
+
+        end_selection_op (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Align selected objects to viertical center of objects.                    */
+/*****************************************************************************/
+void
+gl_label_align_selection_vcenter (glLabel *label)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+	gdouble        dy;
+	gdouble        dymin;
+	gdouble        ysum, yavg;
+        glLabelRegion  obj_extent;
+	gdouble        ycenter;
+	gint           n;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+	g_return_if_fail (!gl_label_is_selection_empty (label) &&
+			  !gl_label_is_selection_atomic (label));
+
+        begin_selection_op (label);
+
+        selection_list = gl_label_get_selection_list (label);
+
+	/* find average center of objects */
+	ysum = 0.0;
+	n = 0;
+	for (p = selection_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+
+		gl_label_object_get_extent (object, &obj_extent);
+		ysum += (obj_extent.y1 + obj_extent.y2) / 2.0;
+		n++;
+	}
+	yavg = ysum / n;
+
+	/* find center of object closest to average center */
+	p = selection_list;
+	object = GL_LABEL_OBJECT (p->data);
+
+	gl_label_object_get_extent (object, &obj_extent);
+	dymin = fabs (yavg - (obj_extent.y1 + obj_extent.y2)/2.0);
+	ycenter = (obj_extent.y1 + obj_extent.y2)/2.0;
+	for (p = p->next; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+
+		gl_label_object_get_extent (object, &obj_extent);
+		dy = fabs (yavg - (obj_extent.y1 + obj_extent.y2)/2.0);
+		if ( dy < dymin )
+                {
+			dymin = dy;
+			ycenter = (obj_extent.y1 + obj_extent.y2)/2.0;
+		}
+	}
+
+	/* now adjust the object positions to line up this center */
+	for (p = selection_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+
+		gl_label_object_get_extent (object, &obj_extent);
+		dy = ycenter - (obj_extent.y1 + obj_extent.y2)/2.0;
+		gl_label_object_set_position_relative (object, 0.0, dy);
 	}
+
+        g_list_free (selection_list);
+
+        end_selection_op (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Center selected objects to in center of label.                            */
+/*****************************************************************************/
+void
+gl_label_center_selection_horiz (glLabel *label)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+	gdouble        dx;
+	gdouble        x_label_center;
+	gdouble        x_obj_center;
+	glLabelRegion  obj_extent;
+	gdouble        w, h;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+	g_return_if_fail (!gl_label_is_selection_empty (label));
+
+        begin_selection_op (label);
+
+	gl_label_get_size (label, &w, &h);
+	x_label_center = w / 2.0;
+
+	/* adjust the object positions */
+        selection_list = gl_label_get_selection_list (label);
+	for (p = selection_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+
+		gl_label_object_get_extent (object, &obj_extent);
+		x_obj_center = (obj_extent.x1 + obj_extent.x2) / 2.0;
+		dx = x_label_center - x_obj_center;
+		gl_label_object_set_position_relative (object, dx, 0.0);
+	}
+        g_list_free (selection_list);
+
+        end_selection_op (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Center selected objects to in center of label.                            */
+/*****************************************************************************/
+void
+gl_label_center_selection_vert (glLabel *label)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+	gdouble        dy;
+	gdouble        y_label_center;
+	gdouble        y_obj_center;
+	glLabelRegion  obj_extent;
+	gdouble        w, h;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+	g_return_if_fail (!gl_label_is_selection_empty (label));
+
+        begin_selection_op (label);
+
+	gl_label_get_size (label, &w, &h);
+	y_label_center = h / 2.0;
+
+	/* adjust the object positions */
+        selection_list = gl_label_get_selection_list (label);
+	for (p = selection_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+
+		gl_label_object_get_extent (object, &obj_extent);
+		y_obj_center = (obj_extent.y1 + obj_extent.y2) / 2.0;
+		dy = y_label_center - y_obj_center;
+		gl_label_object_set_position_relative (object, 0.0, dy);
+	}
+        g_list_free (selection_list);
+
+        end_selection_op (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Move selected objects                                                     */
+/*****************************************************************************/
+void
+gl_label_move_selection (glLabel  *label,
+                         gdouble   dx,
+                         gdouble   dy)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+        begin_selection_op (label);
+
+        selection_list = gl_label_get_selection_list (label);
+
+	for (p = selection_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+
+		gl_label_object_set_position_relative (object, dx, dy);
+	}
+
+        g_list_free (selection_list);
+
+        end_selection_op (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Set font family for all text contained in selected objects.               */
+/*****************************************************************************/
+void
+gl_label_set_selection_font_family (glLabel      *label,
+                                    const gchar  *font_family)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+        begin_selection_op (label);
+
+        selection_list = gl_label_get_selection_list (label);
+
+	for (p = selection_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+		gl_label_object_set_font_family (object, font_family);
+	}
+
+        g_list_free (selection_list);
+
+        end_selection_op (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Set font size for all text contained in selected objects.                 */
+/*****************************************************************************/
+void
+gl_label_set_selection_font_size (glLabel  *label,
+				 gdouble  font_size)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+        begin_selection_op (label);
+
+        selection_list = gl_label_get_selection_list (label);
+
+	for (p = selection_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+		gl_label_object_set_font_size (object, font_size);
+	}
+
+        g_list_free (selection_list);
+
+        end_selection_op (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Set font weight for all text contained in selected objects.               */
+/*****************************************************************************/
+void
+gl_label_set_selection_font_weight (glLabel      *label,
+                                    PangoWeight   font_weight)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+        selection_list = gl_label_get_selection_list (label);
+
+	for (p = selection_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+		gl_label_object_set_font_weight (object, font_weight);
+	}
+
+        g_list_free (selection_list);
+
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Set font italic flag for all text contained in selected objects.          */
+/*****************************************************************************/
+void
+gl_label_set_selection_font_italic_flag (glLabel   *label,
+                                         gboolean   font_italic_flag)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+        begin_selection_op (label);
+
+        selection_list = gl_label_get_selection_list (label);
+
+	for (p = selection_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+		gl_label_object_set_font_italic_flag (object, font_italic_flag);
+	}
+
+        g_list_free (selection_list);
+
+        end_selection_op (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Set text alignment for all text contained in selected objects.            */
+/*****************************************************************************/
+void
+gl_label_set_selection_text_alignment (glLabel        *label,
+                                       PangoAlignment  text_alignment)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+        begin_selection_op (label);
+
+        selection_list = gl_label_get_selection_list (label);
+
+	for (p = selection_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+		gl_label_object_set_text_alignment (object, text_alignment);
+	}
+
+        g_list_free (selection_list);
+
+        end_selection_op (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Set text line spacing for all text contained in selected objects.         */
+/*****************************************************************************/
+void
+gl_label_set_selection_text_line_spacing (glLabel  *label,
+				         gdouble  text_line_spacing)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+        begin_selection_op (label);
+
+        selection_list = gl_label_get_selection_list (label);
+
+	for (p = selection_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+		gl_label_object_set_text_line_spacing (object, text_line_spacing);
+	}
+
+        g_list_free (selection_list);
+
+        end_selection_op (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Set text color for all text contained in selected objects.                */
+/*****************************************************************************/
+void
+gl_label_set_selection_text_color (glLabel      *label,
+				  glColorNode *text_color_node)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+        begin_selection_op (label);
+
+        selection_list = gl_label_get_selection_list (label);
+
+	for (p = selection_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+		gl_label_object_set_text_color (object, text_color_node);
+	}
+
+        g_list_free (selection_list);
+
+        end_selection_op (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Set fill color for all selected objects.                                  */
+/*****************************************************************************/
+void
+gl_label_set_selection_fill_color (glLabel      *label,
+				  glColorNode *fill_color_node)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+        begin_selection_op (label);
+
+        selection_list = gl_label_get_selection_list (label);
+
+	for (p = selection_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+		gl_label_object_set_fill_color (object, fill_color_node);
+	}
+
+        g_list_free (selection_list);
+
+        end_selection_op (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Set line color for all selected objects.                                  */
+/*****************************************************************************/
+void
+gl_label_set_selection_line_color (glLabel      *label,
+				  glColorNode *line_color_node)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+        begin_selection_op (label);
+
+        selection_list = gl_label_get_selection_list (label);
+
+	for (p = selection_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+		gl_label_object_set_line_color (object, line_color_node);
+	}
+
+        g_list_free (selection_list);
+
+        end_selection_op (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* Set line width for all selected objects.                                  */
+/*****************************************************************************/
+void
+gl_label_set_selection_line_width (glLabel  *label,
+				  gdouble  line_width)
+{
+        GList         *selection_list;
+	GList         *p;
+	glLabelObject *object;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+        begin_selection_op (label);
+
+        selection_list = gl_label_get_selection_list (label);
+
+	for (p = selection_list; p != NULL; p = p->next)
+        {
+		object = GL_LABEL_OBJECT (p->data);
+		gl_label_object_set_line_width (object, line_width);
+	}
+
+        g_list_free (selection_list);
+
+        end_selection_op (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* "Cut" selected items and place on clipboard.                              */
+/*****************************************************************************/
+void
+gl_label_cut_selection (glLabel       *label,
+                        GtkWidget     *owner)
+{
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+	g_return_if_fail (owner && GTK_IS_WIDGET (owner));
+
+	gl_label_copy_selection (label, owner);
+	gl_label_delete_selection (label);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* "Copy" selected items to clipboard.                                       */
+/*****************************************************************************/
+void
+gl_label_copy_selection (glLabel       *label,
+                         GtkWidget     *owner)
+{
+	GList             *selection_list;
+        GtkClipboard      *clipboard;
+        glLabel           *label_copy;
+	GList             *p;
+	glLabelObject     *object;
+        gchar             *buffer;
+        glXMLLabelStatus   status;
+        const GdkPixbuf   *pixbuf;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+	g_return_if_fail (owner && GTK_IS_WIDGET (owner));
+
+        selection_list = gl_label_get_selection_list (label);
+
+	if (selection_list)
+        {
+                clipboard = gtk_widget_get_clipboard (owner, GLABELS_CLIPBOARD);
+		label_copy = GL_LABEL(gl_label_new ());
+
+		gl_label_set_template (label_copy, label->priv->template);
+		gl_label_set_rotate_flag (label_copy, label->priv->rotate_flag);
+
+		for (p = selection_list; p != NULL; p = p->next)
+                {
+			object = GL_LABEL_OBJECT (p->data);
+
+			gl_label_object_dup (object, label_copy);
+		}
+
+                buffer = gl_xml_label_save_buffer (label_copy, &status);
+                
+                gtk_clipboard_set_text (clipboard, buffer, -1);
+
+                g_free (buffer);
+                g_object_unref (G_OBJECT (label_copy));
+
+	}
+
+        /*
+         * We may also want to make text and images available on standard
+         * clipboard.
+         */
+        if ( gl_label_is_selection_atomic (label) )
+        {
+                clipboard = gtk_widget_get_clipboard (owner, GDK_SELECTION_CLIPBOARD);
+
+                object = GL_LABEL_OBJECT (selection_list->data);
+
+                gl_label_object_copy_to_clipboard (object, clipboard);
+        }
+
+        g_list_free (selection_list);
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/*****************************************************************************/
+/* "Paste" from private clipboard selection.                                 */
+/*****************************************************************************/
+void
+gl_label_paste (glLabel       *label,
+                GtkWidget     *owner)
+{
+        GtkClipboard      *clipboard;
+
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+	g_return_if_fail (owner && GTK_IS_WIDGET (owner));
+
+        clipboard = gtk_widget_get_clipboard (owner, GLABELS_CLIPBOARD);
+
+        gtk_clipboard_request_text (clipboard,
+                                    (GtkClipboardTextReceivedFunc)paste_received_cb,
+                                    label);
+
+	gl_debug (DEBUG_LABEL, "END");
 }
 
 
 /****************************************************************************/
-/* Get pixbuf cache.                                                        */
+/* Paste received callback.                                                 */
 /****************************************************************************/
-GHashTable *
-gl_label_get_pixbuf_cache (glLabel       *label)
+static void
+paste_received_cb (GtkClipboard *clipboard,
+                   const gchar  *buffer,
+                   glLabel      *label)
 {
-	return label->priv->pixbuf_cache;
+        glLabel          *label_copy;
+        glXMLLabelStatus  status;
+        GList            *p;
+        glLabelObject    *object, *newobject;
+
+        label_copy = gl_xml_label_open_buffer (buffer, &status);
+
+        if ( label_copy )
+        {
+                for (p = label_copy->priv->object_list; p != NULL; p = p->next)
+                {
+                        object = (glLabelObject *) p->data;
+                        newobject = gl_label_object_dup (object, label);
+
+                        gl_debug (DEBUG_LABEL, "object pasted");
+                }
+
+                g_object_unref (G_OBJECT (label_copy));
+        }
 }
 
 
 /****************************************************************************/
-/* Is label modified?                                                       */
+/* Set default font family.                                                 */
 /****************************************************************************/
-gboolean
-gl_label_is_modified (glLabel *label)
+void
+gl_label_set_default_font_family (glLabel     *label,
+                                  const gchar *font_family)
 {
-	gl_debug (DEBUG_LABEL, "return %d", label->priv->modified_flag);
-	return label->priv->modified_flag;
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+        g_free (label->priv->default_font_family);
+	label->priv->default_font_family = g_strdup (font_family);
+
+	gl_debug (DEBUG_LABEL, "END");
 }
 
 
 /****************************************************************************/
-/* Is label untitled?                                                       */
+/* Set default font size.                                                   */
 /****************************************************************************/
-gboolean
-gl_label_is_untitled (glLabel *label)
+void
+gl_label_set_default_font_size (glLabel *label,
+                                gdouble  font_size)
 {
-	gl_debug (DEBUG_LABEL, "return %d",(label->priv->filename == NULL));
-	return (label->priv->filename == NULL);
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+	label->priv->default_font_size = font_size;
+
+	gl_debug (DEBUG_LABEL, "END");
 }
 
 
 /****************************************************************************/
-/* Can undo?                                                                */
+/* Set default font weight.                                                 */
 /****************************************************************************/
-gboolean
-gl_label_can_undo (glLabel *label)
+void
+gl_label_set_default_font_weight (glLabel     *label,
+                                  PangoWeight  font_weight)
 {
-	return FALSE;
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+	label->priv->default_font_weight = font_weight;
+
+	gl_debug (DEBUG_LABEL, "END");
 }
 
 
 /****************************************************************************/
-/* Can redo?                                                                */
+/* Set default font italic flag.                                            */
 /****************************************************************************/
-gboolean
-gl_label_can_redo (glLabel *label)
+void
+gl_label_set_default_font_italic_flag (glLabel  *label,
+                                       gboolean  font_italic_flag)
 {
-	return FALSE;
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+	label->priv->default_font_italic_flag = font_italic_flag;
+
+	gl_debug (DEBUG_LABEL, "END");
 }
 
 
 /****************************************************************************/
-/* Set filename.                                                            */
+/* Set default text color.                                                  */
 /****************************************************************************/
 void
-gl_label_set_filename (glLabel     *label,
-		       const gchar *filename)
+gl_label_set_default_text_color (glLabel *label,
+                                 guint    text_color)
 {
-	label->priv->filename = g_strdup (filename);
+	gl_debug (DEBUG_LABEL, "START");
 
-	g_signal_emit (G_OBJECT(label), signals[NAME_CHANGED], 0);
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+	label->priv->default_text_color = text_color;
+
+	gl_debug (DEBUG_LABEL, "END");
 }
 
 
 /****************************************************************************/
-/* Clear modified flag.                                                     */
+/* Set default text alignment.                                              */
 /****************************************************************************/
 void
-gl_label_clear_modified (glLabel *label)
+gl_label_set_default_text_alignment (glLabel        *label,
+                                     PangoAlignment  text_alignment)
 {
+	gl_debug (DEBUG_LABEL, "START");
 
-	if ( label->priv->modified_flag ) {
+	g_return_if_fail (label && GL_IS_LABEL (label));
 
-		label->priv->modified_flag = FALSE;
+	label->priv->default_text_alignment = text_alignment;
+	gl_debug (DEBUG_LABEL, "END");
+}
 
-		g_signal_emit (G_OBJECT(label), signals[MODIFIED_CHANGED], 0);
-	}
 
+/****************************************************************************/
+/* Set default text line spacing.                                           */
+/****************************************************************************/
+void
+gl_label_set_default_text_line_spacing (glLabel *label,
+                                        gdouble  text_line_spacing)
+{
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+	label->priv->default_text_line_spacing = text_line_spacing;
+
+	gl_debug (DEBUG_LABEL, "END");
 }
 
 
 /****************************************************************************/
-/* Set compression level.                                                   */
+/* Set default line width.                                                  */
 /****************************************************************************/
 void
-gl_label_set_compression (glLabel  *label,
-			  gint      compression)
+gl_label_set_default_line_width (glLabel *label,
+                                 gdouble  line_width)
 {
-	gl_debug (DEBUG_LABEL, "set %d", compression);
+	gl_debug (DEBUG_LABEL, "START");
 
-	/* Older versions of libxml2 always return a -1 for documents "read in," so
-	 * default to 9.  Also, default to 9 for anything else out of range. */
-	if ((compression < 0) || (compression >9)) {
-		compression = 9;
-	}
+	g_return_if_fail (label && GL_IS_LABEL (label));
 
-	gl_debug (DEBUG_LABEL, "actual set %d", compression);
-	label->priv->compression = compression;
+	label->priv->default_line_width = line_width;
+
+	gl_debug (DEBUG_LABEL, "END");
 }
 
 
 /****************************************************************************/
-/* Get compression level.                                                   */
+/* Set default line color.                                                  */
 /****************************************************************************/
-gint
-gl_label_get_compression (glLabel *label)
+void
+gl_label_set_default_line_color (glLabel *label,
+                                 guint    line_color)
 {
-	gl_debug (DEBUG_LABEL, "return %d", label->priv->compression);
-	return label->priv->compression;
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+	label->priv->default_line_color = line_color;
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/****************************************************************************/
+/* Set default fill color.                                                  */
+/****************************************************************************/
+void
+gl_label_set_default_fill_color (glLabel *label,
+                                 guint    fill_color)
+{
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+
+	label->priv->default_fill_color = fill_color;
+
+	gl_debug (DEBUG_LABEL, "END");
+}
+
+
+/****************************************************************************/
+/* Get default font family.                                                 */
+/****************************************************************************/
+gchar *
+gl_label_get_default_font_family (glLabel *label)
+{
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
+
+	gl_debug (DEBUG_LABEL, "END");
+
+	return g_strdup (label->priv->default_font_family);
+}
+
+
+/****************************************************************************/
+/* Get default font size.                                                   */
+/****************************************************************************/
+gdouble
+gl_label_get_default_font_size (glLabel *label)
+{
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_val_if_fail (label && GL_IS_LABEL (label), 12.0);
+
+	gl_debug (DEBUG_LABEL, "END");
+
+	return label->priv->default_font_size;
+}
+
+
+/****************************************************************************/
+/* Get default font weight.                                                 */
+/****************************************************************************/
+PangoWeight
+gl_label_get_default_font_weight (glLabel *label)
+{
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_val_if_fail (label && GL_IS_LABEL (label), PANGO_WEIGHT_NORMAL);
+
+	gl_debug (DEBUG_LABEL, "END");
+
+	return label->priv->default_font_weight;
+}
+
+
+/****************************************************************************/
+/* Get default font italic flag.                                            */
+/****************************************************************************/
+gboolean
+gl_label_get_default_font_italic_flag (glLabel *label)
+{
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
+
+	gl_debug (DEBUG_LABEL, "END");
+
+	return label->priv->default_font_italic_flag;
+}
+
+
+/****************************************************************************/
+/* Get default text color.                                                  */
+/****************************************************************************/
+guint
+gl_label_get_default_text_color (glLabel *label)
+{
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_val_if_fail (label && GL_IS_LABEL (label), 0);
+
+	gl_debug (DEBUG_LABEL, "END");
+
+	return label->priv->default_text_color;
+}
+
+
+/****************************************************************************/
+/* Get default text alignment.                                              */
+/****************************************************************************/
+PangoAlignment
+gl_label_get_default_text_alignment (glLabel *label)
+{
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_val_if_fail (label && GL_IS_LABEL (label), PANGO_ALIGN_LEFT);
+
+	gl_debug (DEBUG_LABEL, "END");
+
+	return label->priv->default_text_alignment;
+}
+
+
+/****************************************************************************/
+/* Get default text line spacing.                                           */
+/****************************************************************************/
+gdouble
+gl_label_get_default_text_line_spacing (glLabel *label)
+{
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_val_if_fail (label && GL_IS_LABEL (label), 1.0);
+
+	gl_debug (DEBUG_LABEL, "END");
+
+	return label->priv->default_text_line_spacing;
+}
+
+
+/****************************************************************************/
+/* Get default line width.                                                  */
+/****************************************************************************/
+gdouble
+gl_label_get_default_line_width (glLabel *label)
+{
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_val_if_fail (label && GL_IS_LABEL (label), 1.0);
+
+	gl_debug (DEBUG_LABEL, "END");
+
+	return label->priv->default_line_width;
+}
+
+
+/****************************************************************************/
+/* Get default line color.                                                  */
+/****************************************************************************/
+guint
+gl_label_get_default_line_color (glLabel *label)
+{
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_val_if_fail (label && GL_IS_LABEL (label), 0);
+
+	gl_debug (DEBUG_LABEL, "END");
+
+	return label->priv->default_line_color;
+}
+
+
+/****************************************************************************/
+/* Get default fill color.                                                  */
+/****************************************************************************/
+guint
+gl_label_get_default_fill_color (glLabel *label)
+{
+	gl_debug (DEBUG_LABEL, "START");
+
+	g_return_val_if_fail (label && GL_IS_LABEL (label), 0);
+
+	gl_debug (DEBUG_LABEL, "END");
+
+	return label->priv->default_fill_color;
 }
 
 
@@ -686,7 +2642,7 @@ gl_label_draw (glLabel       *label,
 
 	g_return_if_fail (label && GL_IS_LABEL (label));
 
-	for (p_obj = label->objects; p_obj != NULL; p_obj = p_obj->next)
+	for (p_obj = label->priv->object_list; p_obj != NULL; p_obj = p_obj->next)
         {
 		object = GL_LABEL_OBJECT (p_obj->data);
 
@@ -695,6 +2651,92 @@ gl_label_draw (glLabel       *label,
 }
 
 
+/****************************************************************************/
+/* Get object located at coordinates.                                       */
+/****************************************************************************/
+glLabelObject *gl_label_object_at              (glLabel       *label,
+                                                cairo_t       *cr,
+                                                gdouble        x_pixels,
+                                                gdouble        y_pixels)
+{
+	GList            *p_obj;
+	glLabelObject    *object;
+
+	g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
+
+	for (p_obj = g_list_last (label->priv->object_list); p_obj != NULL; p_obj = p_obj->prev)
+        {
+		object = GL_LABEL_OBJECT (p_obj->data);
+
+                if (gl_label_object_is_located_at (object, cr, x_pixels, y_pixels))
+                {
+                        return object;
+                }
+
+	}
+
+        return NULL;
+}
+
+
+/****************************************************************************/
+/* Return handle and associated object at coordinates.                      */
+/****************************************************************************/
+glLabelObject *
+gl_label_get_handle_at (glLabel             *label,
+                        cairo_t             *cr,
+                        gdouble              x_pixels,
+                        gdouble              y_pixels,
+                        glLabelObjectHandle *handle)
+{
+        GList            *selection_list;
+	GList            *p_obj;
+	glLabelObject    *object;
+
+	g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
+
+        selection_list = gl_label_get_selection_list (label);
+
+	for (p_obj = g_list_last (selection_list); p_obj != NULL; p_obj = p_obj->prev)
+        {
+
+		object = GL_LABEL_OBJECT (p_obj->data);
+
+                if ((*handle = gl_label_object_handle_at (object, cr, x_pixels, y_pixels)))
+                {
+                        g_list_free (selection_list);
+                        return object;
+                }
+
+	}
+
+        g_list_free (selection_list);
+
+        *handle = GL_LABEL_OBJECT_HANDLE_NONE;
+        return NULL;
+}
+
+
+/****************************************************************************/
+/* Can undo?                                                                */
+/****************************************************************************/
+gboolean
+gl_label_can_undo (glLabel *label)
+{
+	return FALSE;
+}
+
+
+/****************************************************************************/
+/* Can redo?                                                                */
+/****************************************************************************/
+gboolean
+gl_label_can_redo (glLabel *label)
+{
+	return FALSE;
+}
+
+
 
 
 /*
diff --git a/src/label.h b/src/label.h
index 73f0d89..0eb73cd 100644
--- a/src/label.h
+++ b/src/label.h
@@ -21,11 +21,12 @@
 #ifndef __LABEL_H__
 #define __LABEL_H__
 
-#include <glib-object.h>
+#include <gtk/gtk.h>
 #include <cairo.h>
 
 #include <libglabels/libglabels.h>
 #include "merge.h"
+#include "color.h"
 #include "pixbuf-cache.h"
 
 G_BEGIN_DECLS
@@ -52,31 +53,29 @@ typedef struct _glLabelPrivate   glLabelPrivate;
 struct _glLabel {
 	GObject         object;
 
-        lglTemplate    *template;
-        gboolean        rotate_flag;
-
-	GList          *objects;
-
 	glLabelPrivate *priv;
 };
 
 struct _glLabelClass {
 	GObjectClass         parent_class;
 
-	void (*changed)          (glLabel *label, gpointer user_data);
-
-	void (*name_changed)     (glLabel *label, gpointer user_data);
+	void (*selection_changed) (glLabel       *view,
+				   gpointer       user_data);
 
-	void (*modified_changed) (glLabel *label, gpointer user_data);
+	void (*changed)           (glLabel       *label,
+				   gpointer       user_data);
 
-	void (*merge_changed)    (glLabel *label, gpointer user_data);
+	void (*name_changed)      (glLabel       *label,
+				   gpointer       user_data);
 
-	void (*size_changed)     (glLabel *label, gpointer user_data);
+	void (*modified_changed)  (glLabel       *label,
+				   gpointer       user_data);
 
-	void (*object_added)     (glLabel       *label,
-                                  glLabelObject *object,
-                                  gpointer       user_data);
+	void (*merge_changed)     (glLabel       *label,
+				   gpointer       user_data);
 
+	void (*size_changed)      (glLabel       *label,
+				   gpointer       user_data);
 };
 
 
@@ -85,25 +84,39 @@ GType         gl_label_get_type                (void) G_GNUC_CONST;
 GObject      *gl_label_new                     (void);
 
 
-void          gl_label_add_object              (glLabel       *label,
-						glLabelObject *object);
+void          gl_label_set_filename            (glLabel       *label,
+						const gchar   *filename);
 
-void          gl_label_remove_object           (glLabel       *label,
-						glLabelObject *object);
+gchar        *gl_label_get_filename            (glLabel       *label);
 
-void          gl_label_raise_object_to_top     (glLabel       *label,
-						glLabelObject *object);
+gchar        *gl_label_get_short_name          (glLabel       *label);
 
-void          gl_label_lower_object_to_bottom  (glLabel       *label,
-						glLabelObject *object);
+gboolean      gl_label_is_untitled             (glLabel       *label);
+
+
+void          gl_label_set_compression         (glLabel       *label,
+						gint           compression);
 
+gint          gl_label_get_compression         (glLabel       *label);
+
+
+void          gl_label_set_modified            (glLabel       *label);
+
+void          gl_label_clear_modified          (glLabel       *label);
+
+gboolean      gl_label_is_modified             (glLabel       *label);
+
+
+void               gl_label_set_template       (glLabel            *label,
+						const lglTemplate  *template);
 
-void          gl_label_set_template            (glLabel       *label,
-						lglTemplate   *template);
+const lglTemplate *gl_label_get_template       (glLabel            *label);
 
 void          gl_label_set_rotate_flag         (glLabel       *label,
 						gboolean       rotate_flag);
 
+gboolean      gl_label_get_rotate_flag         (glLabel       *label);
+
 void          gl_label_get_size                (glLabel       *label,
 						gdouble       *w,
 						gdouble       *h);
@@ -114,37 +127,226 @@ void          gl_label_set_merge               (glLabel       *label,
 
 glMerge      *gl_label_get_merge               (glLabel       *label);
 
+GHashTable   *gl_label_get_pixbuf_cache        (glLabel       *label);
 
-gchar        *gl_label_get_filename            (glLabel       *label);
 
-gchar        *gl_label_get_short_name          (glLabel       *label);
+void          gl_label_add_object              (glLabel       *label,
+						glLabelObject *object);
 
-GHashTable   *gl_label_get_pixbuf_cache        (glLabel       *label);
 
-gboolean      gl_label_is_modified             (glLabel       *label);
+void          gl_label_delete_object           (glLabel       *label,
+						glLabelObject *object);
 
-gboolean      gl_label_is_untitled             (glLabel       *label);
+const GList  *gl_label_get_object_list         (glLabel       *label);
 
-gboolean      gl_label_can_undo                (glLabel       *label);
 
-gboolean      gl_label_can_redo                (glLabel       *label);
 
+/*
+ * Modify selection methods
+ */
+void          gl_label_select_object           (glLabel       *label,
+                                                glLabelObject *object);
 
-void          gl_label_set_filename            (glLabel       *label,
-						const gchar   *filename);
+void          gl_label_unselect_object         (glLabel       *label,
+                                                glLabelObject *object);
 
-void          gl_label_clear_modified          (glLabel       *label);
+void          gl_label_select_all              (glLabel       *label);
 
-void          gl_label_set_compression         (glLabel       *label,
-						gint           compression);
+void          gl_label_unselect_all            (glLabel       *label);
 
-gint          gl_label_get_compression         (glLabel       *label);
+void          gl_label_select_region           (glLabel       *label,
+                                                glLabelRegion *region);
+
+
+/*
+ * Selection query methods
+ */
+gboolean       gl_label_is_selection_empty      (glLabel       *label);
+
+gboolean       gl_label_is_selection_atomic     (glLabel       *label);
+
+glLabelObject *gl_label_get_1st_selected_object (glLabel       *label);
+
+GList         *gl_label_get_selection_list      (glLabel       *label);
+
+gboolean       gl_label_can_selection_text      (glLabel       *label);
+
+gboolean       gl_label_can_selection_fill      (glLabel       *label);
+
+gboolean       gl_label_can_selection_line_color(glLabel       *label);
+
+gboolean       gl_label_can_selection_line_width(glLabel       *label);
+
+
+/*
+ * Perform operations on selections
+ */
+void          gl_label_delete_selection          (glLabel       *label);
+
+void          gl_label_raise_selection_to_top    (glLabel       *label);
+
+void          gl_label_lower_selection_to_bottom (glLabel       *label);
+
+void          gl_label_rotate_selection          (glLabel       *label,
+                                                  gdouble        theta_degs);
+
+void          gl_label_rotate_selection_left     (glLabel       *label);
+
+void          gl_label_rotate_selection_right    (glLabel       *label);
+
+void          gl_label_flip_selection_horiz      (glLabel       *label);
 
-void          gl_label_draw                    (glLabel       *label,
+void          gl_label_flip_selection_vert       (glLabel       *label);
+
+void          gl_label_align_selection_left      (glLabel       *label);
+
+void          gl_label_align_selection_right     (glLabel       *label);
+
+void          gl_label_align_selection_hcenter   (glLabel       *label);
+
+void          gl_label_align_selection_top       (glLabel       *label);
+
+void          gl_label_align_selection_bottom    (glLabel       *label);
+
+void          gl_label_align_selection_vcenter   (glLabel       *label);
+
+void          gl_label_center_selection_horiz    (glLabel       *label);
+
+void          gl_label_center_selection_vert     (glLabel       *label);
+
+void          gl_label_move_selection            (glLabel       *label,
+                                                  gdouble        dx,
+                                                  gdouble        dy);
+
+void          gl_label_set_selection_font_family(glLabel        *label,
+                                                 const gchar    *font_family);
+
+void          gl_label_set_selection_font_size  (glLabel        *label,
+                                                 gdouble         font_size);
+
+void          gl_label_set_selection_font_weight(glLabel        *label,
+                                                 PangoWeight     font_weight);
+
+void          gl_label_set_selection_font_italic_flag (glLabel   *label,
+                                                       gboolean   font_italic_flag);
+
+void          gl_label_set_selection_text_alignment (glLabel        *label,
+                                                     PangoAlignment  text_alignment);
+
+void          gl_label_set_selection_text_line_spacing (glLabel  *label,
+                                                        gdouble   text_line_spacing);
+
+void          gl_label_set_selection_text_color (glLabel        *label,
+                                                 glColorNode    *text_color_node);
+
+void          gl_label_set_selection_fill_color (glLabel        *label,
+                                                 glColorNode    *fill_color_node);
+
+void          gl_label_set_selection_line_color (glLabel        *label,
+                                                 glColorNode    *line_color_node);
+
+void          gl_label_set_selection_line_width (glLabel        *label,
+                                                 gdouble         line_width);
+
+
+/*
+ * Clipboard operations
+ */
+void          gl_label_cut_selection             (glLabel       *label,
+                                                  GtkWidget     *owner);
+
+void          gl_label_copy_selection            (glLabel       *label,
+                                                  GtkWidget     *owner);
+
+void          gl_label_paste                     (glLabel       *label,
+                                                  GtkWidget     *owner);
+
+
+/*
+ * Set/get current default values.
+ */
+void       gl_label_set_default_font_family      (glLabel            *label,
+                                                  const gchar       *font_family);
+
+void       gl_label_set_default_font_size        (glLabel            *label,
+                                                  gdouble            font_size);
+
+void       gl_label_set_default_font_weight      (glLabel            *label,
+                                                  PangoWeight        font_weight);
+
+void       gl_label_set_default_font_italic_flag (glLabel            *label,
+                                                  gboolean           font_italic_flag);
+
+void       gl_label_set_default_text_color       (glLabel            *label,
+                                                  guint              text_color);
+
+void       gl_label_set_default_text_alignment   (glLabel            *label,
+                                                  PangoAlignment     text_alignment);
+
+void       gl_label_set_default_line_width       (glLabel            *label,
+                                                  gdouble            line_width);
+
+void       gl_label_set_default_line_color       (glLabel            *label,
+                                                  guint              line_color);
+
+void       gl_label_set_default_fill_color       (glLabel            *label,
+                                                  guint              fill_color);
+
+void       gl_label_set_default_text_line_spacing(glLabel            *label,
+                                                  gdouble            text_line_spacing);
+
+gchar           *gl_label_get_default_font_family      (glLabel            *label);
+
+gdouble          gl_label_get_default_font_size        (glLabel            *label);
+
+PangoWeight      gl_label_get_default_font_weight      (glLabel            *label);
+
+gboolean         gl_label_get_default_font_italic_flag (glLabel            *label);
+
+guint            gl_label_get_default_text_color       (glLabel            *label);
+
+PangoAlignment   gl_label_get_default_text_alignment   (glLabel            *label);
+
+gdouble          gl_label_get_default_text_line_spacing(glLabel            *label);
+
+gdouble          gl_label_get_default_line_width       (glLabel            *label);
+
+guint            gl_label_get_default_line_color       (glLabel            *label);
+
+guint            gl_label_get_default_fill_color       (glLabel            *view);
+
+
+/*
+ * Drawing methods
+ */
+void           gl_label_draw                   (glLabel       *label,
                                                 cairo_t       *cr,
                                                 gboolean       screen_flag,
                                                 glMergeRecord *record);
 
+glLabelObject *gl_label_object_at              (glLabel       *label,
+                                                cairo_t       *cr,
+                                                gdouble        x_pixels,
+                                                gdouble        y_pixels);
+
+glLabelObject *gl_label_get_handle_at          (glLabel             *label,
+                                                cairo_t             *cr,
+                                                gdouble              x_pixels,
+                                                gdouble              y_pixels,
+                                                glLabelObjectHandle *handle);
+
+
+
+
+
+/*
+ * Undo/Redo methods
+ */
+gboolean      gl_label_can_undo                (glLabel       *label);
+
+gboolean      gl_label_can_redo                (glLabel       *label);
+
+
 G_END_DECLS
 
 
diff --git a/src/object-editor-bc-page.c b/src/object-editor-bc-page.c
index caea8c8..2412951 100644
--- a/src/object-editor-bc-page.c
+++ b/src/object-editor-bc-page.c
@@ -205,8 +205,7 @@ style_changed_cb (glObjectEditor       *editor)
 						  !editor->priv->data_format_fixed_flag);
 		}
  
-                /* Emit our "changed" signal */
-                g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[CHANGED], 0);
+                gl_object_editor_changed_cb (editor);
         }
                                                                                 
         g_free (style_string);
@@ -411,16 +410,13 @@ bc_radio_toggled_cb (glObjectEditor *editor)
 	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (editor->priv->bc_color_radio))) {
                 gtk_widget_set_sensitive (editor->priv->bc_color_combo, TRUE);
                 gtk_widget_set_sensitive (editor->priv->bc_key_combo, FALSE);
-    } else {
+        } else {
                 gtk_widget_set_sensitive (editor->priv->bc_color_combo, FALSE);
                 gtk_widget_set_sensitive (editor->priv->bc_key_combo, TRUE);
 		
 	}
  
-    /* Emit our "changed" signal */
-    g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[CHANGED], 0);
- 
-    gl_debug (DEBUG_EDITOR, "END");
+        gl_object_editor_changed_cb (editor);
 }
 
 
diff --git a/src/object-editor-data-page.c b/src/object-editor-data-page.c
index 284fd5c..3c48369 100644
--- a/src/object-editor-data-page.c
+++ b/src/object-editor-data-page.c
@@ -130,8 +130,7 @@ data_radio_toggled_cb (glObjectEditor *editor)
 					  !editor->priv->data_format_fixed_flag);
 	}
  
-        /* Emit our "changed" signal */
-        g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[CHANGED], 0);
+        gl_object_editor_changed_cb (editor);
  
         gl_debug (DEBUG_WDGT, "END");
 }
diff --git a/src/object-editor-fill-page.c b/src/object-editor-fill-page.c
index ba4f9ab..ac60772 100644
--- a/src/object-editor-fill-page.c
+++ b/src/object-editor-fill-page.c
@@ -126,6 +126,11 @@ gl_object_editor_set_fill_color (glObjectEditor      *editor,
 {
 	gl_debug (DEBUG_EDITOR, "START");
 
+        if (color_node == NULL)
+        {
+                return;
+        }
+
         editor->priv->stop_signals = TRUE;
 
 	gtk_widget_set_sensitive (editor->priv->fill_key_radio, merge_flag);
@@ -217,8 +222,7 @@ fill_radio_toggled_cb (glObjectEditor *editor)
 		
 	}
  
-        /* Emit our "changed" signal */
-        g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[CHANGED], 0);
+        gl_object_editor_changed_cb (editor);
  
         gl_debug (DEBUG_EDITOR, "END");
 }
diff --git a/src/object-editor-image-page.c b/src/object-editor-image-page.c
index d52c1b4..072334e 100644
--- a/src/object-editor-image-page.c
+++ b/src/object-editor-image-page.c
@@ -136,8 +136,7 @@ img_radio_toggled_cb (glObjectEditor *editor)
                 gtk_widget_set_sensitive (editor->priv->img_key_combo, TRUE);
         }
  
-        /* Emit our "changed" signal */
-        g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[CHANGED], 0);
+        gl_object_editor_changed_cb (editor);
  
         gl_debug (DEBUG_WDGT, "END");
 }
@@ -228,24 +227,29 @@ update_preview_cb (GtkFileChooser *file_chooser, gpointer data)
         GtkWidget *preview;
         char *filename;
         GdkPixbuf *pixbuf;
-        gboolean have_preview;
+
+        gl_debug (DEBUG_EDITOR, "START");
 
         preview = GTK_WIDGET (data);
         filename = gtk_file_chooser_get_preview_filename (file_chooser);
 
         if (filename) {
+                gl_debug (DEBUG_EDITOR, "filename =\"%s\"", filename);
                 pixbuf = gdk_pixbuf_new_from_file_at_size (filename, 128, 128, NULL);
-                have_preview = (pixbuf != NULL);
-                g_free (filename);
-
-                gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf);
-                g_object_unref (G_OBJECT (pixbuf));
+                if (pixbuf != NULL)
+                {
+                        gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf);
+                        g_object_unref (G_OBJECT (pixbuf));
 
-                gtk_file_chooser_set_preview_widget_active (file_chooser,
-                                                            have_preview);
+                        gtk_file_chooser_set_preview_widget_active (file_chooser,
+                                                                    TRUE);
+                }
+                g_free (filename);
         } else {
                 gtk_file_chooser_set_preview_widget_active (file_chooser, FALSE);
         }
+
+        gl_debug (DEBUG_EDITOR, "END");
 }
 
 
@@ -341,8 +345,7 @@ img_selection_changed_cb (glObjectEditor *editor)
         filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(editor->priv->img_file_button));
         if (filename != NULL)
         {
-                /* Emit our "changed" signal */
-                g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[CHANGED], 0);
+                gl_object_editor_changed_cb (editor);
         }
         g_free (filename);
 
diff --git a/src/object-editor-line-page.c b/src/object-editor-line-page.c
index 8ba5316..957f262 100644
--- a/src/object-editor-line-page.c
+++ b/src/object-editor-line-page.c
@@ -172,6 +172,11 @@ gl_object_editor_set_line_color (glObjectEditor      *editor,
 {
 	gl_debug (DEBUG_EDITOR, "START");
 
+        if (color_node == NULL)
+        {
+                return;
+        }
+
         editor->priv->stop_signals = TRUE;
 
 	gl_debug (DEBUG_EDITOR, "color field %s(%d) / %X", color_node->key, color_node->field_flag, color_node->color);
@@ -264,8 +269,7 @@ line_radio_toggled_cb (glObjectEditor *editor)
 		
 	}
  
-        /* Emit our "changed" signal */
-        g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[CHANGED], 0);
+        gl_object_editor_changed_cb (editor);
  
         gl_debug (DEBUG_EDITOR, "END");
 }
diff --git a/src/object-editor-lsize-page.c b/src/object-editor-lsize-page.c
index a1b8365..f283d7f 100644
--- a/src/object-editor-lsize-page.c
+++ b/src/object-editor-lsize-page.c
@@ -100,11 +100,11 @@ gl_object_editor_prepare_lsize_page (glObjectEditor       *editor)
 	/* Connect signals */
 	g_signal_connect_swapped (G_OBJECT (editor->priv->lsize_r_spin),
 				  "changed",
-				  G_CALLBACK (gl_object_editor_changed_cb),
+				  G_CALLBACK (gl_object_editor_size_changed_cb),
 				  G_OBJECT (editor));
 	g_signal_connect_swapped (G_OBJECT (editor->priv->lsize_theta_spin),
 				  "changed",
-				  G_CALLBACK (gl_object_editor_changed_cb),
+				  G_CALLBACK (gl_object_editor_size_changed_cb),
 				  G_OBJECT (editor));
 
 	gl_debug (DEBUG_EDITOR, "END");
diff --git a/src/object-editor-private.h b/src/object-editor-private.h
index d585f31..a17efb2 100644
--- a/src/object-editor-private.h
+++ b/src/object-editor-private.h
@@ -30,7 +30,8 @@ struct _glObjectEditorPrivate {
 	GtkBuilder *builder;
 	GtkWidget  *editor_vbox;
 
-        glLabel    *label;
+        glLabel        *label;
+        glLabelObject  *object;
 
 	gdouble     units_per_point;
 
@@ -171,8 +172,7 @@ extern gint gl_object_editor_signals[LAST_SIGNAL];
 
 void gl_object_editor_prepare_position_page     (glObjectEditor        *editor);
 
-void gl_object_editor_prepare_size_page         (glObjectEditor        *editor,
-						 glObjectEditorOption   option);
+void gl_object_editor_prepare_size_page         (glObjectEditor        *editor);
 
 void gl_object_editor_prepare_lsize_page        (glObjectEditor        *editor);
 
@@ -201,6 +201,209 @@ void size_prefs_changed_cb                      (glObjectEditor        *editor);
 void position_prefs_changed_cb                  (glObjectEditor        *editor);
 void shadow_prefs_changed_cb                    (glObjectEditor        *editor);
 
+
+/*
+ * Position Page
+ */
+void        gl_object_editor_set_position         (glObjectEditor      *editor,
+						   gdouble              x,
+						   gdouble              y);
+
+void        gl_object_editor_set_max_position     (glObjectEditor      *editor,
+						   gdouble              x_max,
+						   gdouble              y_max);
+
+void        gl_object_editor_get_position         (glObjectEditor      *editor,
+						   gdouble             *x,
+						   gdouble             *y);
+
+/*
+ * Size Page
+ */
+void        gl_object_editor_set_size             (glObjectEditor      *editor,
+						   gdouble              w,
+						   gdouble              h);
+
+void        gl_object_editor_set_max_size         (glObjectEditor      *editor,
+						   gdouble              w_max,
+						   gdouble              h_max);
+
+void        gl_object_editor_set_base_size        (glObjectEditor      *editor,
+						   gdouble              w_max,
+						   gdouble              h_max);
+
+void        gl_object_editor_get_size             (glObjectEditor      *editor,
+						   gdouble             *w,
+						   gdouble             *h);
+
+
+/*
+ * Line Size Page
+ */
+void        gl_object_editor_set_lsize            (glObjectEditor      *editor,
+						   gdouble              dx,
+						   gdouble              dy);
+
+void        gl_object_editor_set_max_lsize        (glObjectEditor      *editor,
+						   gdouble              dx_max,
+						   gdouble              dy_max);
+
+void        gl_object_editor_get_lsize            (glObjectEditor      *editor,
+						   gdouble             *dx,
+						   gdouble             *dy);
+
+
+/*
+ * Fill Page
+ */
+void        gl_object_editor_set_fill_color       (glObjectEditor      *editor,
+						   gboolean             merge_flag,
+						   glColorNode         *color_node);
+
+glColorNode* gl_object_editor_get_fill_color      (glObjectEditor      *editor);
+
+
+/*
+ * Line/Outline Page
+ */
+void        gl_object_editor_set_line_color       (glObjectEditor      *editor,
+						   gboolean             merge_flag,
+						   glColorNode         *color_node);
+
+glColorNode* gl_object_editor_get_line_color      (glObjectEditor      *editor);
+
+void        gl_object_editor_set_line_width       (glObjectEditor      *editor,
+						   gdouble              width);
+
+gdouble     gl_object_editor_get_line_width       (glObjectEditor      *editor);
+
+
+/*
+ * Image Page
+ */
+void        gl_object_editor_set_image            (glObjectEditor      *editor,
+						   gboolean             merge_flag,
+						   glTextNode          *text_node);
+
+glTextNode *gl_object_editor_get_image            (glObjectEditor      *editor);
+
+
+/*
+ * Text Page
+ */
+void        gl_object_editor_set_font_family      (glObjectEditor      *editor,
+						   const gchar         *font_family);
+
+gchar      *gl_object_editor_get_font_family      (glObjectEditor      *editor);
+
+void        gl_object_editor_set_font_size        (glObjectEditor      *editor,
+						   gdouble              font_size);
+
+gdouble     gl_object_editor_get_font_size        (glObjectEditor      *editor);
+
+void        gl_object_editor_set_font_weight      (glObjectEditor      *editor,
+						   PangoWeight          font_weight);
+
+PangoWeight gl_object_editor_get_font_weight      (glObjectEditor      *editor);
+
+void        gl_object_editor_set_font_italic_flag (glObjectEditor      *editor,
+						   gboolean             font_italic_flag);
+
+gboolean    gl_object_editor_get_font_italic_flag (glObjectEditor      *editor);
+
+void        gl_object_editor_set_text_alignment   (glObjectEditor      *editor,
+						   PangoAlignment       text_alignment);
+
+PangoAlignment gl_object_editor_get_text_alignment (glObjectEditor      *editor);
+
+void        gl_object_editor_set_text_line_spacing (glObjectEditor      *editor,
+						   gdouble               text_line_spacing);
+
+gdouble     gl_object_editor_get_text_line_spacing (glObjectEditor      *editor);
+
+void        gl_object_editor_set_text_color       (glObjectEditor       *editor,
+						   gboolean              merge_flag,
+						   glColorNode          *text_color_node);
+
+glColorNode* gl_object_editor_get_text_color      (glObjectEditor      *editor);
+
+void        gl_object_editor_set_text_auto_shrink (glObjectEditor      *editor,
+						   gboolean             auto_shrink);
+
+gboolean    gl_object_editor_get_text_auto_shrink (glObjectEditor      *editor);
+
+
+/*
+ * Edit Text Page
+ */
+void        gl_object_editor_set_text_buffer      (glObjectEditor      *editor,
+						   GtkTextBuffer       *buffer);
+
+/*
+ * Barcode Page
+ */
+void        gl_object_editor_set_bc_style         (glObjectEditor      *editor,
+						   gchar               *id,
+						   gboolean             text_flag,
+						   gboolean             checksum_flag,
+						   guint                format_digits);
+
+void        gl_object_editor_get_bc_style         (glObjectEditor      *editor,
+						   gchar              **id,
+						   gboolean            *text_flag,
+						   gboolean            *checksum_flag,
+						   guint               *format_digits);
+
+void        gl_object_editor_set_bc_color         (glObjectEditor      *editor,
+						   gboolean             merge_flag,
+						   glColorNode         *color_node);
+
+glColorNode* gl_object_editor_get_bc_color        (glObjectEditor      *editor);
+
+
+/*
+ * Barcode Data Page
+ */
+void        gl_object_editor_set_data             (glObjectEditor      *editor,
+						   gboolean             merge_flag,
+						   glTextNode          *text_node);
+
+glTextNode *gl_object_editor_get_data             (glObjectEditor      *editor);
+
+
+/*
+ * Shadow Page
+ */
+void        gl_object_editor_set_shadow_state     (glObjectEditor      *editor,
+						   gboolean             state);
+
+void        gl_object_editor_set_shadow_offset    (glObjectEditor      *editor,
+						   gdouble              x,
+						   gdouble              y);
+
+void        gl_object_editor_set_shadow_color     (glObjectEditor      *editor,
+						   gboolean             merge_flag,
+						   glColorNode         *color_node);
+
+void        gl_object_editor_set_shadow_opacity   (glObjectEditor      *editor,
+						   gdouble              alpha);
+
+void        gl_object_editor_set_max_shadow_offset(glObjectEditor      *editor,
+						   gdouble              x_max,
+						   gdouble              y_max);
+
+
+gboolean    gl_object_editor_get_shadow_state     (glObjectEditor      *editor);
+
+void        gl_object_editor_get_shadow_offset    (glObjectEditor      *editor,
+						   gdouble             *x,
+						   gdouble             *y);
+
+glColorNode* gl_object_editor_get_shadow_color    (glObjectEditor      *editor);
+
+gdouble     gl_object_editor_get_shadow_opacity   (glObjectEditor      *editor);
+
+
 G_END_DECLS
 
 #endif
diff --git a/src/object-editor-shadow-page.c b/src/object-editor-shadow-page.c
index e89ecf7..4afadc9 100644
--- a/src/object-editor-shadow-page.c
+++ b/src/object-editor-shadow-page.c
@@ -213,6 +213,11 @@ gl_object_editor_set_shadow_color (glObjectEditor      *editor,
 {
 	gl_debug (DEBUG_EDITOR, "START");
 
+        if (color_node == NULL)
+        {
+                return;
+        }
+
         editor->priv->stop_signals = TRUE;
 
 	gtk_widget_set_sensitive (editor->priv->shadow_key_radio, merge_flag);
@@ -466,8 +471,7 @@ shadow_enable_check_toggled_cb (glObjectEditor *editor)
 
         gtk_widget_set_sensitive (editor->priv->shadow_controls_table, state);
 
-        /* Emit our "changed" signal */
-        g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[CHANGED], 0);
+        gl_object_editor_changed_cb (editor);
 
         gl_debug (DEBUG_EDITOR, "END");
 }
@@ -492,8 +496,7 @@ shadow_color_radio_toggled_cb (glObjectEditor *editor)
 		
 	}
  
-        /* Emit our "changed" signal */
-        g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[CHANGED], 0);
+        gl_object_editor_changed_cb (editor);
  
         gl_debug (DEBUG_EDITOR, "END");
 }
diff --git a/src/object-editor-size-page.c b/src/object-editor-size-page.c
index 34d7ad6..038e513 100644
--- a/src/object-editor-size-page.c
+++ b/src/object-editor-size-page.c
@@ -65,8 +65,7 @@ static void h_spin_cb                           (glObjectEditor        *editor);
 /* PRIVATE.  Prepare size page.                                             */
 /*--------------------------------------------------------------------------*/
 void
-gl_object_editor_prepare_size_page (glObjectEditor       *editor,
-				    glObjectEditorOption  option)
+gl_object_editor_prepare_size_page (glObjectEditor       *editor)
 {
         lglUnits      units;
 	const gchar  *units_string;
@@ -111,11 +110,6 @@ gl_object_editor_prepare_size_page (glObjectEditor       *editor,
 					climb_rate, 10.0*climb_rate);
 	gtk_label_set_text (GTK_LABEL(editor->priv->size_h_units_label), units_string);
 
-	/* Un-hide */
-	gtk_widget_show_all (editor->priv->size_page_vbox);
-	if (option != GL_OBJECT_EDITOR_SIZE_IMAGE_PAGE) {
-		gtk_widget_hide (editor->priv->size_reset_image_button);
-	}
 
 	/* Connect signals */
 	g_signal_connect_swapped (G_OBJECT (editor->priv->size_aspect_checkbutton),
@@ -130,13 +124,10 @@ gl_object_editor_prepare_size_page (glObjectEditor       *editor,
 				  "changed",
 				  G_CALLBACK (h_spin_cb),
 				  G_OBJECT (editor));
-
-	if (option == GL_OBJECT_EDITOR_SIZE_IMAGE_PAGE) {
-		g_signal_connect_swapped (G_OBJECT (editor->priv->size_reset_image_button),
-					  "clicked",
-					  G_CALLBACK (size_reset_cb),
-					  G_OBJECT (editor));
-	}
+        g_signal_connect_swapped (G_OBJECT (editor->priv->size_reset_image_button),
+                                  "clicked",
+                                  G_CALLBACK (size_reset_cb),
+                                  G_OBJECT (editor));
 
 	gl_debug (DEBUG_EDITOR, "END");
 }
@@ -197,9 +188,7 @@ w_spin_cb (glObjectEditor *editor)
                 editor->priv->stop_signals = FALSE;
         }
                                                                                 
-        /* Emit our "changed" signal */
-        g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[CHANGED], 0);
-        g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[SIZE_CHANGED], 0);
+        gl_object_editor_size_changed_cb (editor);
                                                                                 
 	gl_debug (DEBUG_EDITOR, "END");
 }
@@ -232,9 +221,7 @@ h_spin_cb (glObjectEditor *editor)
                 editor->priv->stop_signals = FALSE;
         }
                                                                                 
-        /* Emit our "changed" signal */
-        g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[CHANGED], 0);
-        g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[SIZE_CHANGED], 0);
+        gl_object_editor_size_changed_cb (editor);
                                                                                 
 	gl_debug (DEBUG_EDITOR, "END");
 }
@@ -285,12 +272,10 @@ size_reset_cb (glObjectEditor *editor)
 	gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin),
 				   h_base);
 
-        /* Emit our "changed" signal */
-        g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[CHANGED], 0);
-        g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[SIZE_CHANGED], 0);
-
         editor->priv->stop_signals = FALSE;
 
+        gl_object_editor_size_changed_cb (editor);
+
 	gl_debug (DEBUG_EDITOR, "END");
 }
 
diff --git a/src/object-editor-text-page.c b/src/object-editor-text-page.c
index ab26252..8da1b87 100644
--- a/src/object-editor-text-page.c
+++ b/src/object-editor-text-page.c
@@ -208,8 +208,7 @@ align_toggle_cb (GtkToggleButton *toggle,
                                                       FALSE);
                 }
 
-		/* Emit our "changed" signal */
-		g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[CHANGED], 0);
+                gl_object_editor_changed_cb (editor);
         }
 
 }
@@ -224,6 +223,11 @@ gl_object_editor_set_font_family (glObjectEditor      *editor,
 {
 	gchar    *old_font_family;
 
+        if (font_family == NULL)
+        {
+                return;
+        }
+
 	gl_debug (DEBUG_EDITOR, "START");
 
         editor->priv->stop_signals = TRUE;
@@ -449,6 +453,11 @@ gl_object_editor_set_text_color (glObjectEditor      *editor,
 {
 	gl_debug (DEBUG_EDITOR, "START");
 
+        if (text_color_node == NULL)
+        {
+                return;
+        }
+
         editor->priv->stop_signals = TRUE;
 
 	gl_debug (DEBUG_EDITOR, "color field %s(%d) / %X", text_color_node->key, text_color_node->field_flag, text_color_node->color);
@@ -622,8 +631,7 @@ text_radio_toggled_cb (glObjectEditor *editor)
 		
 	}
  
-        /* Emit our "changed" signal */
-        g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[CHANGED], 0);
+        gl_object_editor_changed_cb (editor);
  
         gl_debug (DEBUG_EDITOR, "END");
 }
diff --git a/src/object-editor.c b/src/object-editor.c
index e63831a..ba112d7 100644
--- a/src/object-editor.c
+++ b/src/object-editor.c
@@ -27,6 +27,7 @@
 #include <math.h>
 
 #include "prefs.h"
+#include "stock.h"
 #include "color-combo.h"
 #include "color.h"
 #include "wdgt-chain-button.h"
@@ -34,6 +35,12 @@
 #include "marshal.h"
 #include "combo-util.h"
 #include "builder-util.h"
+#include "label-box.h"
+#include "label-ellipse.h"
+#include "label-line.h"
+#include "label-image.h"
+#include "label-text.h"
+#include "label-barcode.h"
 
 #include "object-editor-private.h"
 
@@ -49,15 +56,11 @@
 /* Private data types                        */
 /*===========================================*/
 
-typedef void (*ChangedSignal) (GObject * object, gpointer data);
-
 
 /*===========================================*/
 /* Private globals                           */
 /*===========================================*/
 
-gint gl_object_editor_signals[LAST_SIGNAL] = { 0 };
-
 
 /*===========================================*/
 /* Local function prototypes                 */
@@ -65,16 +68,28 @@ gint gl_object_editor_signals[LAST_SIGNAL] = { 0 };
 
 static void gl_object_editor_finalize           (GObject              *object);
 
-static void gl_object_notebook_construct_valist (glObjectEditor       *editor,
-                                                 glLabel              *label,
-						 glObjectEditorOption  first_option,
-						 va_list               args);
+static void set_object                          (glObjectEditor       *editor,
+                                                 glLabelObject        *object);
 
 static void prefs_changed_cb                    (glObjectEditor       *editor);
 
 static void label_changed_cb                    (glLabel              *label,
                                                  glObjectEditor       *editor);
 
+static void selection_changed_cb                (glLabel              *label,
+                                                 glObjectEditor       *editor);
+
+static void merge_changed_cb                    (glLabel              *label,
+                                                 glObjectEditor       *editor);
+
+static void set_key_names                       (glObjectEditor       *editor,
+                                                 glMerge              *merge);
+
+static void object_changed_cb                   (glLabelObject        *object,
+                                                 glObjectEditor       *editor);
+
+
+
 /*****************************************************************************/
 /* Boilerplate object stuff.                                                 */
 /*****************************************************************************/
@@ -91,26 +106,6 @@ gl_object_editor_class_init (glObjectEditorClass *class)
   	gl_object_editor_parent_class = g_type_class_peek_parent (class);
 
   	object_class->finalize = gl_object_editor_finalize;  	
-
-	gl_object_editor_signals[CHANGED] =
-	    g_signal_new ("changed",
-			  G_OBJECT_CLASS_TYPE(object_class),
-			  G_SIGNAL_RUN_LAST,
-			  G_STRUCT_OFFSET (glObjectEditorClass, changed),
-			  NULL, NULL,
-			  gl_marshal_VOID__VOID,
-			  G_TYPE_NONE, 0);
-
-	gl_object_editor_signals[SIZE_CHANGED] =
-	    g_signal_new ("size_changed",
-			  G_OBJECT_CLASS_TYPE(object_class),
-			  G_SIGNAL_RUN_LAST,
-			  G_STRUCT_OFFSET (glObjectEditorClass, size_changed),
-			  NULL, NULL,
-			  gl_marshal_VOID__VOID,
-			  G_TYPE_NONE, 0);
-
-	gl_debug (DEBUG_EDITOR, "END");
 }
 
 
@@ -125,6 +120,7 @@ gl_object_editor_init (glObjectEditor *editor)
                                        "adjustment13",
                                        NULL };
         GError       *error = NULL;
+        gchar        *s;
 
 	gl_debug (DEBUG_EDITOR, "START");
 	
@@ -155,6 +151,19 @@ gl_object_editor_init (glObjectEditor *editor)
 
 	gtk_widget_show_all (GTK_WIDGET(editor));
 
+        gtk_image_set_from_stock (GTK_IMAGE(editor->priv->title_image),
+                                  GL_STOCK_PROPERTIES,
+                                  GTK_ICON_SIZE_LARGE_TOOLBAR);
+
+        s = g_strdup_printf ("<span weight=\"bold\">%s</span>",
+                             _("Object properties"));
+        gtk_label_set_text (GTK_LABEL(editor->priv->title_label), s);
+        gtk_label_set_use_markup (GTK_LABEL(editor->priv->title_label), TRUE);
+        g_free (s);
+
+        gtk_widget_set_sensitive (editor->priv->title_image, FALSE);
+        gtk_widget_set_sensitive (editor->priv->title_label, FALSE);
+
 	/* Hide all notebook pages to start with. */
 	gtk_widget_hide_all (editor->priv->notebook);
 	gtk_widget_set_no_show_all (editor->priv->notebook, TRUE);
@@ -176,10 +185,25 @@ gl_object_editor_finalize (GObject *object)
 
 	g_signal_handlers_disconnect_by_func (G_OBJECT(gl_prefs),
 					      prefs_changed_cb, editor);
-	g_signal_handlers_disconnect_by_func (G_OBJECT(editor->priv->label),
-					      label_changed_cb, editor);
+
+        if (editor->priv->label)
+        {
+                g_signal_handlers_disconnect_by_func (G_OBJECT(editor->priv->label),
+                                                      label_changed_cb, editor);
+                g_signal_handlers_disconnect_by_func (G_OBJECT(editor->priv->label),
+                                                      merge_changed_cb, editor);
+                g_object_unref (editor->priv->label);
+        }
+
+        if (editor->priv->object)
+        {
+                g_signal_handlers_disconnect_by_func (G_OBJECT(editor->priv->object),
+                                                      object_changed_cb, editor);
+                g_object_unref (editor->priv->object);
+        }
 
         g_object_unref (editor->priv->builder);
+
 	g_free (editor->priv);
 
 	G_OBJECT_CLASS (gl_object_editor_parent_class)->finalize (object);
@@ -189,200 +213,355 @@ gl_object_editor_finalize (GObject *object)
 
 
 /*****************************************************************************/
-/* NEW object editor.                                                      */
+/* NEW object editor.                                                        */
 /*****************************************************************************/
 GtkWidget*
-gl_object_editor_new (gchar                *image,
-		      gchar                *title,
-                      glLabel              *label,
-		      glObjectEditorOption  first_option, ...)
+gl_object_editor_new (void)
 {
 	glObjectEditor *editor;
-	va_list         args;
 
 	gl_debug (DEBUG_EDITOR, "START");
 
 	editor = GL_OBJECT_EDITOR (g_object_new (GL_TYPE_OBJECT_EDITOR, NULL));
 
-	if (image) {
-		gtk_image_set_from_stock (GTK_IMAGE(editor->priv->title_image),
-					  image,
-					  GTK_ICON_SIZE_LARGE_TOOLBAR);
-	}
+        gtk_widget_set_sensitive (editor->priv->title_image, FALSE);
+        gtk_widget_set_sensitive (editor->priv->title_label, FALSE);
+
+        gl_object_editor_prepare_position_page (editor);
+        gl_object_editor_prepare_size_page (editor);
+        gl_object_editor_prepare_lsize_page (editor);
+        gl_object_editor_prepare_fill_page (editor);
+        gl_object_editor_prepare_line_page (editor);
+        gl_object_editor_prepare_image_page (editor);
+        gl_object_editor_prepare_text_page (editor);
+        gl_object_editor_prepare_edit_page (editor);
+        gl_object_editor_prepare_bc_page (editor);
+        gl_object_editor_prepare_data_page (editor);
+        gl_object_editor_prepare_shadow_page (editor);
+
+	g_signal_connect_swapped (G_OBJECT (gl_prefs), "changed",
+				  G_CALLBACK (prefs_changed_cb), editor);
+
+	gl_debug (DEBUG_EDITOR, "END");
+
+	return GTK_WIDGET(editor);
+}
+
+
+/*****************************************************************************/
+/* Set label.                                                                */
+/*****************************************************************************/
+void
+gl_object_editor_set_label (glObjectEditor  *editor,
+                            glLabel         *label)
+{
+	gl_debug (DEBUG_EDITOR, "START");
+
+        editor->priv->label = g_object_ref (label);
+
+        label_changed_cb (label, editor);
+        merge_changed_cb (label, editor);
 
-	if (title) {
-		gchar *s;
+	g_signal_connect (G_OBJECT(label), "selection_changed",
+			  G_CALLBACK(selection_changed_cb), editor);
+        g_signal_connect (G_OBJECT (label), "size_changed",
+                          G_CALLBACK (label_changed_cb), editor);
+        g_signal_connect (G_OBJECT (label), "merge_changed",
+                          G_CALLBACK (merge_changed_cb), editor);
+
+	gl_debug (DEBUG_EDITOR, "END");
+}
+
+
+/*--------------------------------------------------------------------------*/
+/* Private. Set object.                                                     */
+/*--------------------------------------------------------------------------*/
+static void
+set_object (glObjectEditor  *editor,
+            glLabelObject   *object)
+{
+        gchar         *image;
+        gchar         *title;
+        gchar         *s;
+        GtkTextBuffer *buffer;
+
+	gl_debug (DEBUG_EDITOR, "START");
+
+        if ( editor->priv->object != NULL )
+        {
+                g_signal_handlers_disconnect_by_func (G_OBJECT(editor->priv->object),
+                                                      object_changed_cb, editor);
+                g_object_unref (editor->priv->object);
+        }
+
+        if (object)
+        {
+                editor->priv->object = g_object_ref (object);
+
+                object_changed_cb (object, editor);
+
+                if (GL_IS_LABEL_BOX (object))
+                {
+                        image = GL_STOCK_BOX;
+                        title = _("Box object properties");
+
+                        gtk_widget_show_all (editor->priv->pos_page_vbox);
+                        gtk_widget_show_all (editor->priv->size_page_vbox);
+                        gtk_widget_hide     (editor->priv->lsize_page_vbox);
+                        gtk_widget_show_all (editor->priv->fill_page_vbox);
+                        gtk_widget_show_all (editor->priv->line_page_vbox);
+                        gtk_widget_hide     (editor->priv->img_page_vbox);
+                        gtk_widget_hide     (editor->priv->text_page_vbox);
+                        gtk_widget_hide     (editor->priv->edit_page_vbox);
+                        gtk_widget_hide     (editor->priv->bc_page_vbox);
+                        gtk_widget_hide     (editor->priv->data_page_vbox);
+                        gtk_widget_show_all (editor->priv->shadow_page_vbox);
+
+                        gtk_widget_hide     (editor->priv->size_reset_image_button);
+                }
+                else if (GL_IS_LABEL_ELLIPSE (object))
+                {
+                        image = GL_STOCK_ELLIPSE;
+                        title = _("Ellipse object properties");
+
+                        gtk_widget_show_all (editor->priv->pos_page_vbox);
+                        gtk_widget_show_all (editor->priv->size_page_vbox);
+                        gtk_widget_hide     (editor->priv->lsize_page_vbox);
+                        gtk_widget_show_all (editor->priv->fill_page_vbox);
+                        gtk_widget_show_all (editor->priv->line_page_vbox);
+                        gtk_widget_hide     (editor->priv->img_page_vbox);
+                        gtk_widget_hide     (editor->priv->text_page_vbox);
+                        gtk_widget_hide     (editor->priv->edit_page_vbox);
+                        gtk_widget_hide     (editor->priv->bc_page_vbox);
+                        gtk_widget_hide     (editor->priv->data_page_vbox);
+                        gtk_widget_show_all (editor->priv->shadow_page_vbox);
+
+                        gtk_widget_hide     (editor->priv->size_reset_image_button);
+                }
+                else if (GL_IS_LABEL_LINE (object))
+                {
+                        image = GL_STOCK_LINE;
+                        title = _("Line object properties");
+
+                        gtk_widget_show_all (editor->priv->pos_page_vbox);
+                        gtk_widget_hide     (editor->priv->size_page_vbox);
+                        gtk_widget_show_all (editor->priv->lsize_page_vbox);
+                        gtk_widget_hide     (editor->priv->fill_page_vbox);
+                        gtk_widget_show_all (editor->priv->line_page_vbox);
+                        gtk_widget_hide     (editor->priv->img_page_vbox);
+                        gtk_widget_hide     (editor->priv->text_page_vbox);
+                        gtk_widget_hide     (editor->priv->edit_page_vbox);
+                        gtk_widget_hide     (editor->priv->bc_page_vbox);
+                        gtk_widget_hide     (editor->priv->data_page_vbox);
+                        gtk_widget_show_all (editor->priv->shadow_page_vbox);
+                }
+                else if (GL_IS_LABEL_IMAGE (object))
+                {
+                        image = GL_STOCK_IMAGE;
+                        title = _("Image object properties");
+
+                        gtk_widget_show_all (editor->priv->pos_page_vbox);
+                        gtk_widget_show_all (editor->priv->size_page_vbox);
+                        gtk_widget_hide     (editor->priv->lsize_page_vbox);
+                        gtk_widget_hide     (editor->priv->fill_page_vbox);
+                        gtk_widget_hide     (editor->priv->line_page_vbox);
+                        gtk_widget_show_all (editor->priv->img_page_vbox);
+                        gtk_widget_hide     (editor->priv->text_page_vbox);
+                        gtk_widget_hide     (editor->priv->edit_page_vbox);
+                        gtk_widget_hide     (editor->priv->bc_page_vbox);
+                        gtk_widget_hide     (editor->priv->data_page_vbox);
+                        gtk_widget_hide     (editor->priv->shadow_page_vbox);
+                }
+                else if (GL_IS_LABEL_TEXT (object))
+                {
+                        image = GL_STOCK_TEXT;
+                        title = _("Text object properties");
+
+                        gtk_widget_show_all (editor->priv->pos_page_vbox);
+                        gtk_widget_show_all (editor->priv->size_page_vbox);
+                        gtk_widget_hide     (editor->priv->lsize_page_vbox);
+                        gtk_widget_hide     (editor->priv->fill_page_vbox);
+                        gtk_widget_hide     (editor->priv->line_page_vbox);
+                        gtk_widget_hide     (editor->priv->img_page_vbox);
+                        gtk_widget_show_all (editor->priv->text_page_vbox);
+                        gtk_widget_show_all (editor->priv->edit_page_vbox);
+                        gtk_widget_hide     (editor->priv->bc_page_vbox);
+                        gtk_widget_hide     (editor->priv->data_page_vbox);
+                        gtk_widget_show_all (editor->priv->shadow_page_vbox);
+
+                        gtk_widget_hide     (editor->priv->size_reset_image_button);
+
+                        buffer = gl_label_text_get_buffer (GL_LABEL_TEXT(object));
+                        gl_object_editor_set_text_buffer (editor, buffer);
+                }
+                else if (GL_IS_LABEL_BARCODE (object))
+                {
+                        image = GL_STOCK_BARCODE;
+                        title = _("Barcode object properties");
+
+                        gtk_widget_show_all (editor->priv->pos_page_vbox);
+                        gtk_widget_show_all (editor->priv->size_page_vbox);
+                        gtk_widget_hide     (editor->priv->lsize_page_vbox);
+                        gtk_widget_hide     (editor->priv->fill_page_vbox);
+                        gtk_widget_hide     (editor->priv->line_page_vbox);
+                        gtk_widget_hide     (editor->priv->img_page_vbox);
+                        gtk_widget_hide     (editor->priv->text_page_vbox);
+                        gtk_widget_hide     (editor->priv->edit_page_vbox);
+                        gtk_widget_show_all (editor->priv->bc_page_vbox);
+                        gtk_widget_show_all (editor->priv->data_page_vbox);
+                        gtk_widget_hide     (editor->priv->shadow_page_vbox);
+
+                        gtk_widget_hide     (editor->priv->size_reset_image_button);
+                }
+
+                gtk_image_set_from_stock (GTK_IMAGE(editor->priv->title_image),
+                                          image,
+					  GTK_ICON_SIZE_LARGE_TOOLBAR);
 
 		s = g_strdup_printf ("<span weight=\"bold\">%s</span>",
 				     title);
 		gtk_label_set_text (GTK_LABEL(editor->priv->title_label), s);
+		gtk_label_set_use_markup (GTK_LABEL(editor->priv->title_label), TRUE);
 		g_free (s);
 
+                gtk_widget_set_sensitive (editor->priv->title_image, TRUE);
+                gtk_widget_set_sensitive (editor->priv->title_label, TRUE);
+
+                gtk_widget_show (editor->priv->notebook);
+
+                g_signal_connect (G_OBJECT (object), "changed",
+                                  G_CALLBACK (object_changed_cb), editor);
+        }
+        else
+        {
+                editor->priv->object = NULL;
+
+                gtk_image_set_from_stock (GTK_IMAGE(editor->priv->title_image),
+					  GL_STOCK_PROPERTIES,
+					  GTK_ICON_SIZE_LARGE_TOOLBAR);
+
+		s = g_strdup_printf ("<span weight=\"bold\">%s</span>",
+				     _("Object properties"));
+		gtk_label_set_text (GTK_LABEL(editor->priv->title_label), s);
 		gtk_label_set_use_markup (GTK_LABEL(editor->priv->title_label), TRUE);
-					  
-	}
+		g_free (s);
 
-	va_start (args, first_option);
-	gl_object_notebook_construct_valist (editor, label, first_option, args);
-	va_end (args);
+                gtk_widget_set_sensitive (editor->priv->title_image, FALSE);
+                gtk_widget_set_sensitive (editor->priv->title_label, FALSE);
 
-	gl_debug (DEBUG_EDITOR, "END");
+                gtk_widget_hide (editor->priv->notebook);
+        }
 
-	return GTK_WIDGET(editor);
+	gl_debug (DEBUG_EDITOR, "END");
 }
 
 
 /*--------------------------------------------------------------------------*/
-/* PRIVATE.  Construct notebook.                                            */
+/* PRIVATE. Prefs changed callback.  Update units related items.            */
 /*--------------------------------------------------------------------------*/
 static void
-gl_object_notebook_construct_valist (glObjectEditor       *editor,
-                                     glLabel              *label,
-				     glObjectEditorOption  first_option,
-				     va_list               args)
+prefs_changed_cb (glObjectEditor *editor)
 {
-	glObjectEditorOption option;
-	gint pages = 0;
 
 	gl_debug (DEBUG_EDITOR, "START");
 
-        editor->priv->label = label;
-
-	option = first_option;
-
-	for ( option=first_option; option; option=va_arg (args, glObjectEditorOption) ) {
-
-		switch (option) {
-
-		case GL_OBJECT_EDITOR_EMPTY:
-			gtk_widget_set_sensitive (editor->priv->title_image, FALSE);
-			gtk_widget_set_sensitive (editor->priv->title_label, FALSE);
-			break;
-
-		case GL_OBJECT_EDITOR_POSITION_PAGE:
-			gl_object_editor_prepare_position_page (editor);
-			pages++;
-			break;
-
-		case GL_OBJECT_EDITOR_SIZE_PAGE:
-		case GL_OBJECT_EDITOR_SIZE_IMAGE_PAGE:
-			gl_object_editor_prepare_size_page (editor, option);
-			pages++;
-			break;
-
-		case GL_OBJECT_EDITOR_SIZE_LINE_PAGE:
-			gl_object_editor_prepare_lsize_page (editor);
-			pages++;
-			break;
-
-		case GL_OBJECT_EDITOR_FILL_PAGE:
-			gl_object_editor_prepare_fill_page (editor);
-			pages++;
-			break;
-
-		case GL_OBJECT_EDITOR_LINE_PAGE:
-			gl_object_editor_prepare_line_page (editor);
-			pages++;
-			break;
-
-		case GL_OBJECT_EDITOR_IMAGE_PAGE:
-			gl_object_editor_prepare_image_page (editor);
-			pages++;
-			break;
-
-		case GL_OBJECT_EDITOR_TEXT_PAGE:
-			gl_object_editor_prepare_text_page (editor);
-			pages++;
-			break;
-
-		case GL_OBJECT_EDITOR_EDIT_PAGE:
-			gl_object_editor_prepare_edit_page (editor);
-			pages++;
-			break;
-
-		case GL_OBJECT_EDITOR_BC_PAGE:
-			gl_object_editor_prepare_bc_page (editor);
-			pages++;
-			break;
-
-		case GL_OBJECT_EDITOR_DATA_PAGE:
-			gl_object_editor_prepare_data_page (editor);
-			pages++;
-			break;
-
-		case GL_OBJECT_EDITOR_SHADOW_PAGE:
-			gl_object_editor_prepare_shadow_page (editor);
-			pages++;
-			break;
-
-		default:
-			g_message ("option = %d", option);
-			g_assert_not_reached ();
-		}
+	if (editor->priv->lsize_r_spin) {
+		lsize_prefs_changed_cb (editor);
+	}
 		
+	if (editor->priv->size_w_spin) {
+		size_prefs_changed_cb (editor);
 	}
-	if (pages) {
-		gtk_widget_show (editor->priv->notebook);
+		
+	if (editor->priv->pos_x_spin) {
+		position_prefs_changed_cb (editor);
 	}
 
-	g_signal_connect_swapped (G_OBJECT (gl_prefs), "changed",
-				  G_CALLBACK (prefs_changed_cb),
-				  editor);
-        if (label)
+	if (editor->priv->shadow_x_spin) {
+		shadow_prefs_changed_cb (editor);
+	}
+
+	gl_debug (DEBUG_EDITOR, "END");
+}
+
+
+/*---------------------------------------------------------------------------*/
+/* PRIVATE.  Label "selection state changed" callback.                       */
+/*---------------------------------------------------------------------------*/
+static void 
+selection_changed_cb (glLabel        *label,
+		      glObjectEditor *editor)
+{
+        glLabelObject *object;
+
+	gl_debug (DEBUG_EDITOR, "START");
+
+	g_return_if_fail (label && GL_IS_LABEL (label));
+	g_return_if_fail (editor && GL_IS_OBJECT_EDITOR (editor));
+
+	if (!gl_label_is_selection_atomic (label))
         {
-                label_changed_cb (label, editor);
-                g_signal_connect (G_OBJECT (label), "size_changed",
-                                  G_CALLBACK (label_changed_cb),
-                                  editor);
-                g_signal_connect (G_OBJECT (label), "merge_changed",
-                                  G_CALLBACK (label_changed_cb),
-                                  editor);
-        }
+                set_object (editor, NULL);
+	}
+        else
+        {
+                object = gl_label_get_1st_selected_object (label);
+                set_object (editor, object);
+	}
 
 	gl_debug (DEBUG_EDITOR, "END");
 }
 
 
-/*--------------------------------------------------------------------------*/
-/* PRIVATE. Widget changed callback.  Emit our "changed" signal.            */
-/*--------------------------------------------------------------------------*/
-void
-gl_object_editor_changed_cb (glObjectEditor *editor)
+/*---------------------------------------------------------------------------*/
+/* PRIVATE. label "size_changed" callback.                                   */
+/*---------------------------------------------------------------------------*/
+static void
+label_changed_cb (glLabel        *label,
+                  glObjectEditor *editor)
 {
-        if (editor->priv->stop_signals) return;
+	gdouble   label_width, label_height;
 
 	gl_debug (DEBUG_EDITOR, "START");
 
-	/* Emit our "changed" signal */
-	g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[CHANGED], 0);
+	gl_label_get_size (label, &label_width, &label_height);
+	gl_object_editor_set_max_position (GL_OBJECT_EDITOR (editor),
+					   label_width, label_height);
+	gl_object_editor_set_max_size (GL_OBJECT_EDITOR (editor),
+				       label_width, label_height);
+	gl_object_editor_set_max_lsize (GL_OBJECT_EDITOR (editor),
+				       label_width, label_height);
+	gl_object_editor_set_max_shadow_offset (GL_OBJECT_EDITOR (editor),
+						label_width, label_height);
 
 	gl_debug (DEBUG_EDITOR, "END");
 }
 
 
-/*--------------------------------------------------------------------------*/
-/* PRIVATE. Widget size changed callback.  Emit our "size-changed" signal.  */
-/*--------------------------------------------------------------------------*/
-void
-gl_object_editor_size_changed_cb (glObjectEditor *editor)
+/*---------------------------------------------------------------------------*/
+/* PRIVATE. label "merge_changed" callback.                                  */
+/*---------------------------------------------------------------------------*/
+static void
+merge_changed_cb (glLabel        *label,
+                  glObjectEditor *editor)
 {
-        if (editor->priv->stop_signals) return;
+	glMerge	 *merge;
 
 	gl_debug (DEBUG_EDITOR, "START");
 
-	/* Emit our "size_changed" signal */
-	g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[SIZE_CHANGED], 0);
+	merge = gl_label_get_merge (label);
+	set_key_names (editor, merge);
 
 	gl_debug (DEBUG_EDITOR, "END");
 }
 
 
-/*****************************************************************************/
-/* Set possible key names from merge object.                                 */
-/*****************************************************************************/
-void
-gl_object_editor_set_key_names (glObjectEditor      *editor,
-				glMerge             *merge)
+/*---------------------------------------------------------------------------*/
+/* PRIVATE. Load up possible key names from merge into various widgets.      */
+/*---------------------------------------------------------------------------*/
+static void
+set_key_names (glObjectEditor      *editor,
+               glMerge             *merge)
 {
         GList     *keys;
 	GtkWidget *combo;
@@ -392,132 +571,106 @@ gl_object_editor_set_key_names (glObjectEditor      *editor,
  
         gl_debug (DEBUG_EDITOR, "START");
 
-	if (editor->priv->text_auto_shrink_check) {
-		gtk_widget_set_sensitive (editor->priv->text_auto_shrink_check,
-					  merge != NULL);
-	}
+        gtk_widget_set_sensitive (editor->priv->text_auto_shrink_check,
+                                  merge != NULL);
  
-	if (editor->priv->text_page_vbox) {
-		gtk_widget_set_sensitive (editor->priv->text_color_key_radio, merge != NULL);
-		if (merge == NULL) {
-			gtk_toggle_button_set_active (
-				GTK_TOGGLE_BUTTON(editor->priv->text_color_radio), TRUE);
-			gtk_widget_set_sensitive (editor->priv->text_color_combo, TRUE);
-			gtk_widget_set_sensitive (editor->priv->text_color_key_combo, FALSE);
-		} else {
-			state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(editor->priv->text_color_key_radio));
-			gtk_widget_set_sensitive (editor->priv->text_color_combo, !state);
-			gtk_widget_set_sensitive (editor->priv->text_color_key_combo, state);
-						  
-		}
+        gtk_widget_set_sensitive (editor->priv->text_color_key_radio, merge != NULL);
+        if (merge == NULL)
+        {
+                gtk_toggle_button_set_active (
+                        GTK_TOGGLE_BUTTON(editor->priv->text_color_radio), TRUE);
+                gtk_widget_set_sensitive (editor->priv->text_color_combo, TRUE);
+                gtk_widget_set_sensitive (editor->priv->text_color_key_combo, FALSE);
+        }
+        else
+        {
+                state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(editor->priv->text_color_key_radio));
+                gtk_widget_set_sensitive (editor->priv->text_color_combo, !state);
+                gtk_widget_set_sensitive (editor->priv->text_color_key_combo, state);
 	}
 
-	if (editor->priv->edit_insert_field_button) {
-		gtk_widget_set_sensitive (editor->priv->edit_insert_field_button,
-					  merge != NULL);
-	}
+        gtk_widget_set_sensitive (editor->priv->edit_insert_field_button,
+                                  merge != NULL);
 
-	if (editor->priv->img_key_combo) {
-		gtk_widget_set_sensitive (editor->priv->img_key_combo, merge != NULL);
-	}
+        gtk_widget_set_sensitive (editor->priv->img_key_combo, merge != NULL);
  
-	if (editor->priv->img_key_radio) {
-		gtk_widget_set_sensitive (editor->priv->img_key_radio, merge != NULL);
-		if (merge == NULL) {
-			gtk_toggle_button_set_active (
-				GTK_TOGGLE_BUTTON(editor->priv->img_file_radio), TRUE);
-		}
-	}
+        gtk_widget_set_sensitive (editor->priv->img_key_radio, merge != NULL);
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(editor->priv->img_file_radio),
+                                      merge == NULL);
 
-	if (editor->priv->data_key_combo) {
-		gtk_widget_set_sensitive (editor->priv->data_key_combo, merge != NULL);
-	}
+        gtk_widget_set_sensitive (editor->priv->data_key_combo, merge != NULL);
  
-	if (editor->priv->data_key_radio) {
-		gtk_widget_set_sensitive (editor->priv->data_key_radio, merge != NULL);
-		if (merge == NULL) {
-			gtk_toggle_button_set_active (
-				GTK_TOGGLE_BUTTON(editor->priv->data_literal_radio), TRUE);
-		}
-	}
+        gtk_widget_set_sensitive (editor->priv->data_key_radio, merge != NULL);
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(editor->priv->data_literal_radio),
+                                      merge == NULL);
 	
 	fixed_flag = editor->priv->data_format_fixed_flag;
-	if (editor->priv->data_format_label) {
-		gtk_widget_set_sensitive (editor->priv->data_format_label,
-					  (merge != NULL));
-	}
-	if (editor->priv->data_ex_label) {
-		gtk_widget_set_sensitive (editor->priv->data_ex_label,
-					  (merge != NULL));
-	}
-	if (editor->priv->data_digits_label) {
-		gtk_widget_set_sensitive (editor->priv->data_digits_label,
-					  (merge != NULL) && !fixed_flag);
-	}
-	if (editor->priv->data_digits_spin) {
-		gtk_widget_set_sensitive (editor->priv->data_digits_spin,
-					  (merge != NULL) && !fixed_flag);
-	}
-
-	if (editor->priv->fill_page_vbox) {
-		gtk_widget_set_sensitive (editor->priv->fill_key_radio, merge != NULL);
-		if (merge == NULL) {
-			gtk_toggle_button_set_active (
-				GTK_TOGGLE_BUTTON(editor->priv->fill_color_radio), TRUE);
-			gtk_widget_set_sensitive (editor->priv->fill_color_combo, TRUE);
-			gtk_widget_set_sensitive (editor->priv->fill_key_combo, FALSE);
-		} else {
-			state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(editor->priv->fill_key_radio));
-			gtk_widget_set_sensitive (editor->priv->fill_color_combo, !state);
-			gtk_widget_set_sensitive (editor->priv->fill_key_combo, state);
-						  
-		}
-	}
+        gtk_widget_set_sensitive (editor->priv->data_format_label, merge != NULL);
+        gtk_widget_set_sensitive (editor->priv->data_ex_label, merge != NULL);
+        gtk_widget_set_sensitive (editor->priv->data_digits_label,
+                                  (merge != NULL) && !fixed_flag);
+        gtk_widget_set_sensitive (editor->priv->data_digits_spin,
+                                  (merge != NULL) && !fixed_flag);
+
+        gtk_widget_set_sensitive (editor->priv->fill_key_radio, merge != NULL);
+        if (merge == NULL)
+        {
+                gtk_toggle_button_set_active (
+                        GTK_TOGGLE_BUTTON(editor->priv->fill_color_radio), TRUE);
+                gtk_widget_set_sensitive (editor->priv->fill_color_combo, TRUE);
+                gtk_widget_set_sensitive (editor->priv->fill_key_combo, FALSE);
+        }
+        else
+        {
+                state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(editor->priv->fill_key_radio));
+                gtk_widget_set_sensitive (editor->priv->fill_color_combo, !state);
+                gtk_widget_set_sensitive (editor->priv->fill_key_combo, state);
+        }
 
-	if (editor->priv->line_page_vbox) {
-		gtk_widget_set_sensitive (editor->priv->line_key_radio, merge != NULL);
-		if (merge == NULL) {
-			gtk_toggle_button_set_active (
-				GTK_TOGGLE_BUTTON(editor->priv->line_color_radio), TRUE);
-			gtk_widget_set_sensitive (editor->priv->line_color_combo, TRUE);
-			gtk_widget_set_sensitive (editor->priv->line_key_combo, FALSE);
-		} else {
-			state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(editor->priv->line_key_radio));
-			gtk_widget_set_sensitive (editor->priv->line_color_combo, !state);
-			gtk_widget_set_sensitive (editor->priv->line_key_combo, state);
-						  
-		}
-	}
+        gtk_widget_set_sensitive (editor->priv->line_key_radio, merge != NULL);
+        if (merge == NULL)
+        {
+                gtk_toggle_button_set_active (
+                        GTK_TOGGLE_BUTTON(editor->priv->line_color_radio), TRUE);
+                gtk_widget_set_sensitive (editor->priv->line_color_combo, TRUE);
+                gtk_widget_set_sensitive (editor->priv->line_key_combo, FALSE);
+        }
+        else
+        {
+                state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(editor->priv->line_key_radio));
+                gtk_widget_set_sensitive (editor->priv->line_color_combo, !state);
+                gtk_widget_set_sensitive (editor->priv->line_key_combo, state);
+        }
 
-	if (editor->priv->bc_page_vbox) {
-		gtk_widget_set_sensitive (editor->priv->bc_key_radio, merge != NULL);
-		if (merge == NULL) {
-			gtk_toggle_button_set_active (
-				GTK_TOGGLE_BUTTON(editor->priv->bc_color_radio), TRUE);
-			gtk_widget_set_sensitive (editor->priv->bc_color_combo, TRUE);
-			gtk_widget_set_sensitive (editor->priv->bc_key_combo, FALSE);
-		} else {
-			state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(editor->priv->bc_key_radio));
-			gtk_widget_set_sensitive (editor->priv->bc_color_combo, !state);
-			gtk_widget_set_sensitive (editor->priv->bc_key_combo, state);
-						  
-		}
-	}
+        gtk_widget_set_sensitive (editor->priv->bc_key_radio, merge != NULL);
+        if (merge == NULL)
+        {
+                gtk_toggle_button_set_active (
+                        GTK_TOGGLE_BUTTON(editor->priv->bc_color_radio), TRUE);
+                gtk_widget_set_sensitive (editor->priv->bc_color_combo, TRUE);
+                gtk_widget_set_sensitive (editor->priv->bc_key_combo, FALSE);
+        }
+        else
+        {
+                state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(editor->priv->bc_key_radio));
+                gtk_widget_set_sensitive (editor->priv->bc_color_combo, !state);
+                gtk_widget_set_sensitive (editor->priv->bc_key_combo, state);
+        }
 
-	if (editor->priv->shadow_page_vbox) {
-		gtk_widget_set_sensitive (editor->priv->shadow_key_radio, merge != NULL);
-		if (merge == NULL) {
-			gtk_toggle_button_set_active (
-				GTK_TOGGLE_BUTTON(editor->priv->shadow_color_radio), TRUE);
-			gtk_widget_set_sensitive (editor->priv->shadow_color_combo, TRUE);
-			gtk_widget_set_sensitive (editor->priv->shadow_key_combo, FALSE);
-		} else {
-			state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(editor->priv->shadow_key_radio));
-			gtk_widget_set_sensitive (editor->priv->shadow_color_combo, !state);
-			gtk_widget_set_sensitive (editor->priv->shadow_key_combo, state);
-						  
-		}
-	}
+        gtk_widget_set_sensitive (editor->priv->shadow_key_radio, merge != NULL);
+        if (merge == NULL)
+        {
+                gtk_toggle_button_set_active (
+                        GTK_TOGGLE_BUTTON(editor->priv->shadow_color_radio), TRUE);
+                gtk_widget_set_sensitive (editor->priv->shadow_color_combo, TRUE);
+                gtk_widget_set_sensitive (editor->priv->shadow_key_combo, FALSE);
+        }
+        else
+        {
+                state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(editor->priv->shadow_key_radio));
+                gtk_widget_set_sensitive (editor->priv->shadow_color_combo, !state);
+                gtk_widget_set_sensitive (editor->priv->shadow_key_combo, state);
+        }
 
         keys = gl_merge_get_key_list (merge);
         if ( keys == NULL ) {
@@ -525,44 +678,28 @@ gl_object_editor_set_key_names (glObjectEditor      *editor,
 	}
 
 	combo = editor->priv->img_key_combo;
-	if (combo) {
-		gl_combo_util_set_strings (GTK_COMBO_BOX (combo), keys);
-	}
+        gl_combo_util_set_strings (GTK_COMBO_BOX (combo), keys);
 
 	button = editor->priv->edit_insert_field_button;
-	if (button) {
-		gl_field_button_set_keys (GL_FIELD_BUTTON(button), keys);
-	}
+        gl_field_button_set_keys (GL_FIELD_BUTTON(button), keys);
 
 	combo = editor->priv->data_key_combo;
-	if (combo) {
-		gl_combo_util_set_strings (GTK_COMBO_BOX (combo), keys);
-	}
+        gl_combo_util_set_strings (GTK_COMBO_BOX (combo), keys);
 		
 	combo = editor->priv->fill_key_combo;
-	if (combo) {
-		gl_combo_util_set_strings (GTK_COMBO_BOX (combo), keys);
-	}
+        gl_combo_util_set_strings (GTK_COMBO_BOX (combo), keys);
 
 	combo = editor->priv->text_color_key_combo;
-	if (combo) {
-		gl_combo_util_set_strings (GTK_COMBO_BOX (combo), keys);
-	}
+        gl_combo_util_set_strings (GTK_COMBO_BOX (combo), keys);
 
 	combo = editor->priv->line_key_combo;
-	if (combo) {
-		gl_combo_util_set_strings (GTK_COMBO_BOX (combo), keys);
-	}
+        gl_combo_util_set_strings (GTK_COMBO_BOX (combo), keys);
 		
 	combo = editor->priv->bc_key_combo;
-	if (combo) {
-		gl_combo_util_set_strings (GTK_COMBO_BOX (combo), keys);
-	}
+        gl_combo_util_set_strings (GTK_COMBO_BOX (combo), keys);
 		
 	combo = editor->priv->shadow_key_combo;
-	if (combo) {
-		gl_combo_util_set_strings (GTK_COMBO_BOX (combo), keys);
-	}
+        gl_combo_util_set_strings (GTK_COMBO_BOX (combo), keys);
 
 	gl_merge_free_key_list (&keys);
  
@@ -570,61 +707,361 @@ gl_object_editor_set_key_names (glObjectEditor      *editor,
 }
 
 
-/*--------------------------------------------------------------------------*/
-/* PRIVATE. Prefs changed callback.  Update units related items.            */
-/*--------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/* PRIVATE. object "changed" callback.                                       */
+/*---------------------------------------------------------------------------*/
 static void
-prefs_changed_cb (glObjectEditor *editor)
+object_changed_cb (glLabelObject  *object,
+                   glObjectEditor *editor)
 {
+        gdouble          x, y;
+        gdouble          w, h;
+        glColorNode     *line_color_node;
+        gdouble          line_width;
+        glColorNode     *fill_color_node;
+        gchar           *font_family;
+        gdouble          font_size;
+        PangoWeight      font_weight;
+        gboolean         font_italic_flag;
+        glColorNode     *text_color_node;
+        PangoAlignment   align;
+        gdouble          text_line_spacing;
+        gboolean         auto_shrink;
+        const GdkPixbuf *pixbuf;
+        gdouble          image_w, image_h;
+        glTextNode      *filename;
+        glTextNode      *bc_data;
+        gchar           *id;
+        gboolean         text_flag, cs_flag;
+        guint            format_digits;
+        gboolean         shadow_state;
+        gdouble          shadow_x, shadow_y;
+        glColorNode     *shadow_color_node;
+        gdouble          shadow_opacity;
+        glMerge         *merge;
+
+        gl_debug (DEBUG_EDITOR, "BEGIN");
 
-	gl_debug (DEBUG_EDITOR, "START");
+        if (editor->priv->stop_signals) return;
+        editor->priv->stop_signals = TRUE;
 
-	if (editor->priv->lsize_r_spin) {
-		lsize_prefs_changed_cb (editor);
-	}
-		
-	if (editor->priv->size_w_spin) {
-		size_prefs_changed_cb (editor);
-	}
-		
-	if (editor->priv->pos_x_spin) {
-		position_prefs_changed_cb (editor);
-	}
 
-	if (editor->priv->shadow_x_spin) {
-		shadow_prefs_changed_cb (editor);
-	}
+        gl_label_object_get_position (object, &x, &y);
+        gl_object_editor_set_position (editor, x, y);
 
-	gl_debug (DEBUG_EDITOR, "END");
+        merge = gl_label_get_merge (GL_LABEL(object->parent));
+
+
+        if ( GL_IS_LABEL_BOX (object) || GL_IS_LABEL_ELLIPSE (object) )
+        {
+
+                gl_label_object_get_size (object, &w, &h);
+                fill_color_node   = gl_label_object_get_fill_color (GL_LABEL_OBJECT(object));
+                line_color_node   = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
+                line_width        = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
+
+                gl_object_editor_set_size (editor, w, h);
+                gl_object_editor_set_fill_color (editor, (merge != NULL), fill_color_node);
+                gl_object_editor_set_line_color (editor, (merge != NULL), line_color_node);
+                gl_object_editor_set_line_width (editor, line_width);
+
+                gl_color_node_free (&fill_color_node);
+                gl_color_node_free (&line_color_node);
+
+        }
+        else if ( GL_IS_LABEL_LINE (object) )
+        {
+
+                gl_label_object_get_size (object, &w, &h);
+                line_color_node   = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
+                line_width        = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
+
+                gl_object_editor_set_lsize (editor, w, h);
+                gl_object_editor_set_line_color (editor, (merge != NULL), line_color_node);
+                gl_object_editor_set_line_width (editor, line_width);
+
+                gl_color_node_free (&line_color_node);
+
+        }
+        else if ( GL_IS_LABEL_IMAGE (object) )
+        {
+
+                gl_label_object_get_size (object, &w, &h);
+                pixbuf   = gl_label_image_get_pixbuf (GL_LABEL_IMAGE(object), NULL);
+                filename = gl_label_image_get_filename (GL_LABEL_IMAGE(object));
+
+                image_w = gdk_pixbuf_get_width (pixbuf);
+                image_h = gdk_pixbuf_get_height (pixbuf);
+
+                gl_object_editor_set_size (editor, w, h);
+                gl_object_editor_set_base_size (editor, image_w, image_h);
+                gl_object_editor_set_image (editor, (merge != NULL), filename);
+
+                gl_text_node_free (&filename);
+
+        }
+        else if ( GL_IS_LABEL_TEXT (object) )
+        {
+
+                gl_label_object_get_size (object, &w, &h);
+                font_family       = gl_label_object_get_font_family (object);
+                font_size         = gl_label_object_get_font_size (object);
+                font_weight       = gl_label_object_get_font_weight (object);
+                font_italic_flag  = gl_label_object_get_font_italic_flag (object);
+                text_color_node   = gl_label_object_get_text_color (object);
+                align             = gl_label_object_get_text_alignment (object);
+                text_line_spacing = gl_label_object_get_text_line_spacing (object);
+                auto_shrink       = gl_label_text_get_auto_shrink (GL_LABEL_TEXT (object));
+
+                gl_object_editor_set_size (editor, w, h);
+                gl_object_editor_set_font_family (editor, font_family);
+                gl_object_editor_set_font_size (editor, font_size);
+                gl_object_editor_set_font_weight (editor, font_weight);
+                gl_object_editor_set_font_italic_flag (editor, font_italic_flag);
+                gl_object_editor_set_text_color (editor, (merge != NULL), text_color_node);
+                gl_object_editor_set_text_alignment (editor, align);
+                gl_object_editor_set_text_line_spacing (editor, text_line_spacing);
+                gl_object_editor_set_text_auto_shrink (editor, auto_shrink);
+
+                gl_color_node_free (&text_color_node);
+                g_free (font_family);
+
+        }
+        else if ( GL_IS_LABEL_BARCODE (object) )
+        {
+
+                gl_label_object_get_size (object, &w, &h);
+                bc_data = gl_label_barcode_get_data (GL_LABEL_BARCODE(object));
+                gl_label_barcode_get_props (GL_LABEL_BARCODE(object),
+                                            &id, &text_flag, &cs_flag, &format_digits);
+
+                gl_object_editor_set_size (editor, w, h);
+                gl_object_editor_set_data (editor, (merge != NULL), bc_data);
+                gl_object_editor_set_bc_style (editor, id, text_flag, cs_flag, format_digits);
+                gl_object_editor_set_bc_color (editor, (merge != NULL), line_color_node);
+
+                gl_text_node_free (&bc_data);
+
+        }
+
+
+        shadow_state      = gl_label_object_get_shadow_state (object);
+        gl_label_object_get_shadow_offset (object, &shadow_x, &shadow_y);
+        shadow_color_node = gl_label_object_get_shadow_color (object);
+        shadow_opacity    = gl_label_object_get_shadow_opacity (object);
+
+        gl_object_editor_set_shadow_state (editor, shadow_state);
+        gl_object_editor_set_shadow_offset (editor, shadow_x, shadow_y);
+        gl_object_editor_set_shadow_color (editor, (merge != NULL), shadow_color_node);
+        gl_object_editor_set_shadow_opacity (editor, shadow_opacity);
+
+        gl_color_node_free (&shadow_color_node);
+
+
+        editor->priv->stop_signals = FALSE;
+
+        gl_debug (DEBUG_EDITOR, "END");
 }
 
 
-/*---------------------------------------------------------------------------*/
-/* PRIVATE. label "changed" callback.                                        */
-/*---------------------------------------------------------------------------*/
-static void
-label_changed_cb (glLabel        *label,
-                  glObjectEditor *editor)
+/*****************************************************************************/
+/* Object editor "changed" callback.                                         */
+/*****************************************************************************/
+void
+gl_object_editor_changed_cb (glObjectEditor *editor)
 {
-	gdouble   label_width, label_height;
-	glMerge	 *merge;
+        glLabelObject     *object = editor->priv->object;
+        gdouble            x, y;
+        gdouble            w, h;
+        glColorNode       *line_color_node;
+        gdouble            line_width;
+        glColorNode       *fill_color_node;
+        gchar             *font_family;
+        gdouble            font_size;
+        PangoWeight        font_weight;
+        gboolean           font_italic_flag;
+        glColorNode       *text_color_node;
+        PangoAlignment     align;
+        gdouble            text_line_spacing;
+        gboolean           auto_shrink;
+        glTextNode        *filename;
+        const GdkPixbuf   *pixbuf;
+        gdouble            image_w, image_h;
+        gdouble            new_w, new_h;
+        glTextNode        *bc_data;
+        gchar             *id;
+        gboolean           text_flag, cs_flag;
+        guint              format_digits;
+        gboolean           shadow_state;
+        gdouble            shadow_x, shadow_y;
+        glColorNode       *shadow_color_node;
+        gdouble            shadow_opacity;
+
+        gl_debug (DEBUG_EDITOR, "BEGIN");
 
-	gl_debug (DEBUG_EDITOR, "START");
+        if (editor->priv->stop_signals) return;
+        editor->priv->stop_signals = TRUE;
 
-	gl_label_get_size (label, &label_width, &label_height);
-	gl_object_editor_set_max_position (GL_OBJECT_EDITOR (editor),
-					   label_width, label_height);
-	gl_object_editor_set_max_size (GL_OBJECT_EDITOR (editor),
-				       label_width, label_height);
-	gl_object_editor_set_max_lsize (GL_OBJECT_EDITOR (editor),
-				       label_width, label_height);
-	gl_object_editor_set_max_shadow_offset (GL_OBJECT_EDITOR (editor),
-						label_width, label_height);
-	
-	merge = gl_label_get_merge (label);
-	gl_object_editor_set_key_names (editor, merge);
 
-	gl_debug (DEBUG_EDITOR, "END");
+        gl_object_editor_get_position (editor, &x, &y);
+        gl_label_object_set_position (object, x, y);
+
+
+        if ( GL_IS_LABEL_BOX (object) || GL_IS_LABEL_ELLIPSE (object) )
+        {
+
+                gl_object_editor_get_size (editor, &w, &h);
+                fill_color_node   = gl_object_editor_get_fill_color (editor);
+                line_color_node   = gl_object_editor_get_line_color (editor);
+                line_width        = gl_object_editor_get_line_width (editor);
+
+                gl_label_object_set_size (object, w, h);
+                gl_label_object_set_fill_color (object, fill_color_node);
+                gl_label_object_set_line_color (object, line_color_node);
+                gl_label_object_set_line_width (object, line_width);
+
+                gl_color_node_free (&fill_color_node);
+                gl_color_node_free (&line_color_node);
+
+        }
+        else if (GL_IS_LABEL_LINE (object))
+        {
+
+                gl_object_editor_get_lsize (editor, &w, &h);
+                line_color_node   = gl_object_editor_get_line_color (editor);
+                line_width        = gl_object_editor_get_line_width (editor);
+
+                gl_label_object_set_size (object, w, h);
+                gl_label_object_set_line_color (object, line_color_node);
+                gl_label_object_set_line_width (object, line_width);
+
+                gl_color_node_free (&line_color_node);
+
+        }
+        else if ( GL_IS_LABEL_IMAGE (object) )
+        {
+
+                gl_object_editor_get_size (editor, &w, &h);
+                filename = gl_object_editor_get_image (editor);
+
+                gl_label_object_set_size (object, w, h);
+                gl_label_image_set_filename (GL_LABEL_IMAGE(object), filename);
+
+                /* Setting filename may have modified the size. */
+                gl_label_object_get_size (object, &new_w, &new_h);
+                if ( (new_w != w) || (new_h != h) )
+                {
+                        gl_object_editor_set_size (editor, new_w, new_h);
+                }
+
+                /* It may also have a new base size. */
+                pixbuf = gl_label_image_get_pixbuf (GL_LABEL_IMAGE(object), NULL);
+                image_w = gdk_pixbuf_get_width (pixbuf);
+                image_h = gdk_pixbuf_get_height (pixbuf);
+                gl_object_editor_set_base_size (editor, image_w, image_h);
+
+                gl_text_node_free (&filename);
+
+        }
+        else if (GL_IS_LABEL_TEXT (object))
+        {
+
+                gl_object_editor_get_size (editor, &w, &h);
+                font_family       = gl_object_editor_get_font_family (editor);
+                font_size         = gl_object_editor_get_font_size (editor);
+                font_weight       = gl_object_editor_get_font_weight (editor);
+                font_italic_flag  = gl_object_editor_get_font_italic_flag (editor);
+                text_color_node   = gl_object_editor_get_text_color (editor);
+                align             = gl_object_editor_get_text_alignment (editor);
+                text_line_spacing = gl_object_editor_get_text_line_spacing (editor);
+                auto_shrink       = gl_object_editor_get_text_auto_shrink (editor);
+
+                gl_label_object_set_size (object, w, h);
+                gl_label_object_set_font_family (object, font_family);
+                gl_label_object_set_font_size (object, font_size);
+                gl_label_object_set_font_weight (object, font_weight);
+                gl_label_object_set_font_italic_flag (object, font_italic_flag);
+                gl_label_object_set_text_color (object, text_color_node);
+                gl_label_object_set_text_alignment (object, align);
+                gl_label_object_set_text_line_spacing (object, text_line_spacing);
+                gl_label_text_set_auto_shrink (GL_LABEL_TEXT (object), auto_shrink);
+
+                gl_color_node_free (&text_color_node);
+                g_free (font_family);
+
+        }
+        else if (GL_IS_LABEL_BARCODE (object))
+        {
+
+                gl_object_editor_get_size (editor, &w, &h);
+                line_color_node = gl_object_editor_get_bc_color (editor);
+                bc_data = gl_object_editor_get_data (editor);
+                gl_object_editor_get_bc_style (editor,
+                                               &id, &text_flag, &cs_flag, &format_digits);
+
+                gl_label_object_set_size (object, w, h);
+                gl_label_object_set_line_color (object, line_color_node);
+                gl_label_barcode_set_data (GL_LABEL_BARCODE(object), bc_data);
+                gl_label_barcode_set_props (GL_LABEL_BARCODE(object),
+                                            id, text_flag, cs_flag, format_digits);
+
+                gl_color_node_free (&line_color_node);
+                gl_text_node_free (&bc_data);
+                g_free (id);
+
+        }
+
+
+        shadow_state      = gl_object_editor_get_shadow_state (editor);
+        gl_object_editor_get_shadow_offset (editor, &shadow_x, &shadow_y);
+        shadow_color_node = gl_object_editor_get_shadow_color (editor);
+        shadow_opacity    = gl_object_editor_get_shadow_opacity (editor);
+
+        gl_label_object_set_position (object, x, y);
+        gl_label_object_set_shadow_state (object, shadow_state);
+        gl_label_object_set_shadow_offset (object, shadow_x, shadow_y);
+        gl_label_object_set_shadow_color (object, shadow_color_node);
+        gl_label_object_set_shadow_opacity (object, shadow_opacity);
+
+        gl_color_node_free (&shadow_color_node);
+
+
+        editor->priv->stop_signals = FALSE;
+
+        gl_debug (DEBUG_EDITOR, "END");
+}
+
+
+/*****************************************************************************/
+/* Object editor "size_changed" callback.                                    */
+/*****************************************************************************/
+void
+gl_object_editor_size_changed_cb (glObjectEditor *editor)
+{
+        glLabelObject     *object = editor->priv->object;
+        gdouble            w, h;
+
+        gl_debug (DEBUG_EDITOR, "BEGIN");
+
+        if (editor->priv->stop_signals) return;
+        editor->priv->stop_signals = TRUE;
+
+
+        if ( GL_IS_LABEL_LINE (object) )
+        {
+                gl_object_editor_get_lsize (editor, &w, &h);
+        }
+        else
+        {
+                gl_object_editor_get_size (editor, &w, &h);
+        }
+
+        gl_label_object_set_size (object, w, h);
+
+
+        editor->priv->stop_signals = FALSE;
+
+        gl_debug (DEBUG_EDITOR, "END");
 }
 
 
diff --git a/src/object-editor.h b/src/object-editor.h
index 71d63a3..d8f7095 100644
--- a/src/object-editor.h
+++ b/src/object-editor.h
@@ -31,22 +31,6 @@
 
 G_BEGIN_DECLS
 
-typedef enum {
-	GL_OBJECT_EDITOR_EMPTY = 1,
-	GL_OBJECT_EDITOR_POSITION_PAGE,
-	GL_OBJECT_EDITOR_SIZE_PAGE,
-	GL_OBJECT_EDITOR_SIZE_IMAGE_PAGE,
-	GL_OBJECT_EDITOR_SIZE_LINE_PAGE,
-	GL_OBJECT_EDITOR_FILL_PAGE,
-	GL_OBJECT_EDITOR_LINE_PAGE,
-	GL_OBJECT_EDITOR_IMAGE_PAGE,
-	GL_OBJECT_EDITOR_TEXT_PAGE,
-	GL_OBJECT_EDITOR_EDIT_PAGE,
-	GL_OBJECT_EDITOR_BC_PAGE,
-	GL_OBJECT_EDITOR_DATA_PAGE,
-	GL_OBJECT_EDITOR_SHADOW_PAGE,
-} glObjectEditorOption;
-
 #define GL_TYPE_OBJECT_EDITOR            (gl_object_editor_get_type ())
 #define GL_OBJECT_EDITOR(obj) \
         (G_TYPE_CHECK_INSTANCE_CAST ((obj), GL_TYPE_OBJECT_EDITOR, glObjectEditor))
@@ -76,9 +60,6 @@ struct _glObjectEditor
 struct  _glObjectEditorClass
 {
 	GtkVBoxClass             parent_class;
-
-	void (*changed)      (glObjectEditor *editor, gpointer user_data);
-	void (*size_changed) (glObjectEditor *editor, gpointer user_data);
 };
 
 
@@ -86,215 +67,10 @@ struct  _glObjectEditorClass
 
 GType       gl_object_editor_get_type             (void) G_GNUC_CONST;
 
-GtkWidget  *gl_object_editor_new                  (gchar               *image,
-						   gchar               *title,
-                                                   glLabel             *label,
-						   glObjectEditorOption first_option, ...);
-
-void        gl_object_editor_set_key_names        (glObjectEditor      *editor,
-						   glMerge             *merge);
-
-
-/*
- * Position Page
- */
-void        gl_object_editor_set_position         (glObjectEditor      *editor,
-						   gdouble              x,
-						   gdouble              y);
-
-void        gl_object_editor_set_max_position     (glObjectEditor      *editor,
-						   gdouble              x_max,
-						   gdouble              y_max);
-
-void        gl_object_editor_get_position         (glObjectEditor      *editor,
-						   gdouble             *x,
-						   gdouble             *y);
-
-/*
- * Size Page
- */
-void        gl_object_editor_set_size             (glObjectEditor      *editor,
-						   gdouble              w,
-						   gdouble              h);
-
-void        gl_object_editor_set_max_size         (glObjectEditor      *editor,
-						   gdouble              w_max,
-						   gdouble              h_max);
-
-void        gl_object_editor_set_base_size        (glObjectEditor      *editor,
-						   gdouble              w_max,
-						   gdouble              h_max);
-
-void        gl_object_editor_get_size             (glObjectEditor      *editor,
-						   gdouble             *w,
-						   gdouble             *h);
-
-
-/*
- * Line Size Page
- */
-void        gl_object_editor_set_lsize            (glObjectEditor      *editor,
-						   gdouble              dx,
-						   gdouble              dy);
-
-void        gl_object_editor_set_max_lsize        (glObjectEditor      *editor,
-						   gdouble              dx_max,
-						   gdouble              dy_max);
-
-void        gl_object_editor_get_lsize            (glObjectEditor      *editor,
-						   gdouble             *dx,
-						   gdouble             *dy);
-
-
-/*
- * Fill Page
- */
-void        gl_object_editor_set_fill_color       (glObjectEditor      *editor,
-						   gboolean             merge_flag,
-						   glColorNode         *color_node);
-
-glColorNode* gl_object_editor_get_fill_color      (glObjectEditor      *editor);
-
-
-/*
- * Line/Outline Page
- */
-void        gl_object_editor_set_line_color       (glObjectEditor      *editor,
-						   gboolean             merge_flag,
-						   glColorNode         *color_node);
-
-glColorNode* gl_object_editor_get_line_color      (glObjectEditor      *editor);
-
-void        gl_object_editor_set_line_width       (glObjectEditor      *editor,
-						   gdouble              width);
-
-gdouble     gl_object_editor_get_line_width       (glObjectEditor      *editor);
-
-
-/*
- * Image Page
- */
-void        gl_object_editor_set_image            (glObjectEditor      *editor,
-						   gboolean             merge_flag,
-						   glTextNode          *text_node);
-
-glTextNode *gl_object_editor_get_image            (glObjectEditor      *editor);
-
-
-/*
- * Text Page
- */
-void        gl_object_editor_set_font_family      (glObjectEditor      *editor,
-						   const gchar         *font_family);
-
-gchar      *gl_object_editor_get_font_family      (glObjectEditor      *editor);
-
-void        gl_object_editor_set_font_size        (glObjectEditor      *editor,
-						   gdouble              font_size);
-
-gdouble     gl_object_editor_get_font_size        (glObjectEditor      *editor);
-
-void        gl_object_editor_set_font_weight      (glObjectEditor      *editor,
-						   PangoWeight          font_weight);
-
-PangoWeight gl_object_editor_get_font_weight      (glObjectEditor      *editor);
-
-void        gl_object_editor_set_font_italic_flag (glObjectEditor      *editor,
-						   gboolean             font_italic_flag);
-
-gboolean    gl_object_editor_get_font_italic_flag (glObjectEditor      *editor);
-
-void        gl_object_editor_set_text_alignment   (glObjectEditor      *editor,
-						   PangoAlignment       text_alignment);
-
-PangoAlignment gl_object_editor_get_text_alignment (glObjectEditor      *editor);
-
-void        gl_object_editor_set_text_line_spacing (glObjectEditor      *editor,
-						   gdouble               text_line_spacing);
-
-gdouble     gl_object_editor_get_text_line_spacing (glObjectEditor      *editor);
-
-void        gl_object_editor_set_text_color       (glObjectEditor       *editor,
-						   gboolean              merge_flag,
-						   glColorNode          *text_color_node);
-
-glColorNode* gl_object_editor_get_text_color      (glObjectEditor      *editor);
-
-void        gl_object_editor_set_text_auto_shrink (glObjectEditor      *editor,
-						   gboolean             auto_shrink);
-
-gboolean    gl_object_editor_get_text_auto_shrink (glObjectEditor      *editor);
-
-
-/*
- * Edit Text Page
- */
-void        gl_object_editor_set_text_buffer      (glObjectEditor      *editor,
-						   GtkTextBuffer       *buffer);
-
-/*
- * Barcode Page
- */
-void        gl_object_editor_set_bc_style         (glObjectEditor      *editor,
-						   gchar               *id,
-						   gboolean             text_flag,
-						   gboolean             checksum_flag,
-						   guint                format_digits);
-
-void        gl_object_editor_get_bc_style         (glObjectEditor      *editor,
-						   gchar              **id,
-						   gboolean            *text_flag,
-						   gboolean            *checksum_flag,
-						   guint               *format_digits);
-
-void        gl_object_editor_set_bc_color         (glObjectEditor      *editor,
-						   gboolean             merge_flag,
-						   glColorNode         *color_node);
-
-glColorNode* gl_object_editor_get_bc_color        (glObjectEditor      *editor);
-
-
-/*
- * Barcode Data Page
- */
-void        gl_object_editor_set_data             (glObjectEditor      *editor,
-						   gboolean             merge_flag,
-						   glTextNode          *text_node);
-
-glTextNode *gl_object_editor_get_data             (glObjectEditor      *editor);
-
-
-/*
- * Shadow Page
- */
-void        gl_object_editor_set_shadow_state     (glObjectEditor      *editor,
-						   gboolean             state);
-
-void        gl_object_editor_set_shadow_offset    (glObjectEditor      *editor,
-						   gdouble              x,
-						   gdouble              y);
-
-void        gl_object_editor_set_shadow_color     (glObjectEditor      *editor,
-						   gboolean             merge_flag,
-						   glColorNode         *color_node);
-
-void        gl_object_editor_set_shadow_opacity   (glObjectEditor      *editor,
-						   gdouble              alpha);
-
-void        gl_object_editor_set_max_shadow_offset(glObjectEditor      *editor,
-						   gdouble              x_max,
-						   gdouble              y_max);
-
-
-gboolean    gl_object_editor_get_shadow_state     (glObjectEditor      *editor);
-
-void        gl_object_editor_get_shadow_offset    (glObjectEditor      *editor,
-						   gdouble             *x,
-						   gdouble             *y);
-
-glColorNode* gl_object_editor_get_shadow_color    (glObjectEditor      *editor);
+GtkWidget  *gl_object_editor_new                  (void);
 
-gdouble     gl_object_editor_get_shadow_opacity   (glObjectEditor      *editor);
+void        gl_object_editor_set_label            (glObjectEditor      *editor,
+                                                   glLabel             *label);
 
 
 
diff --git a/src/print-op-dialog.c b/src/print-op-dialog.c
index bae96d5..1a46414 100644
--- a/src/print-op-dialog.c
+++ b/src/print-op-dialog.c
@@ -240,13 +240,15 @@ create_custom_widget_cb (GtkPrintOperation *operation,
                                                  NULL };
         GError                 *error = NULL;
 	glPrintOpDialog        *op = GL_PRINT_OP_DIALOG (operation);
+        const lglTemplate      *template;
         const lglTemplateFrame *frame;
 	GtkWidget              *hbox;
         glMerge                *merge = NULL;
         GdkPixbuf              *pixbuf;
 
 
-        frame = (lglTemplateFrame *)label->template->frames->data;
+        template = gl_label_get_template (label);
+        frame = (lglTemplateFrame *)template->frames->data;
         op->priv->labels_per_sheet = lgl_template_frame_get_n_labels (frame);
 
 	builder = gtk_builder_new ();
@@ -282,7 +284,7 @@ create_custom_widget_cb (GtkPrintOperation *operation,
 
         /* ---- Install preview. ---- */
         op->priv->preview = gl_mini_preview_new (MINI_PREVIEW_MIN_HEIGHT, MINI_PREVIEW_MIN_WIDTH);
-        gl_mini_preview_set_template (GL_MINI_PREVIEW(op->priv->preview), label->template);
+        gl_mini_preview_set_template (GL_MINI_PREVIEW(op->priv->preview), template);
         gl_mini_preview_set_label (GL_MINI_PREVIEW(op->priv->preview), label);
         gtk_box_pack_start (GTK_BOX(hbox), op->priv->preview, TRUE, TRUE, 0);
         gtk_widget_show_all (op->priv->preview);
diff --git a/src/print-op.c b/src/print-op.c
index 2c78f48..8880dbe 100644
--- a/src/print-op.c
+++ b/src/print-op.c
@@ -183,13 +183,15 @@ gl_print_op_construct (glPrintOp      *op,
                        glLabel        *label)
 {
         glMerge                *merge = NULL;
+        const lglTemplate      *template;
         const lglTemplateFrame *frame;
 
 	op->priv->label              = label;
 	op->priv->force_outline_flag = FALSE;
 
-        merge = gl_label_get_merge (label);
-        frame = (lglTemplateFrame *)label->template->frames->data;
+        merge    = gl_label_get_merge (label);
+        template = gl_label_get_template (label);
+        frame    = (lglTemplateFrame *)template->frames->data;
 
         op->priv->merge_flag         = (merge != NULL);
         op->priv->n_sheets           = 1;
@@ -385,13 +387,15 @@ static void
 set_page_size (glPrintOp  *op,
                glLabel    *label)
 {
-        GtkPaperSize *psize;
-        GtkPageSetup *su;
-        lglPaper     *paper;
+        const lglTemplate *template;
+        GtkPaperSize      *psize;
+        GtkPageSetup      *su;
+        lglPaper          *paper;
 
 	gl_debug (DEBUG_PRINT, "begin");
 
-        paper = lgl_db_lookup_paper_from_id (label->template->paper_id);
+        template = gl_label_get_template (label);
+        paper = lgl_db_lookup_paper_from_id (template->paper_id);
 
         if (!paper)
         {
@@ -406,12 +410,12 @@ set_page_size (glPrintOp  *op,
         {
                 psize = gtk_paper_size_new_custom (paper->id,
                                                    paper->name,
-                                                   label->template->page_width,
-                                                   label->template->page_height,
+                                                   template->page_width,
+                                                   template->page_height,
                                                    GTK_UNIT_POINTS);
                 gl_debug (DEBUG_PRINT, "Using custom size = %g x %g points",
-                          label->template->page_width,
-                          label->template->page_height);
+                          template->page_width,
+                          template->page_height);
 
         }
         else
diff --git a/src/print.c b/src/print.c
index 0279bd3..9b9da8f 100644
--- a/src/print.c
+++ b/src/print.c
@@ -54,8 +54,8 @@ typedef struct _PrintInfo {
         cairo_t    *cr;
 
 	/* gLabels Template */
-	lglTemplate *template;
-	gboolean     label_rotate_flag;
+	const lglTemplate *template;
+	gboolean           rotate_flag;
 
 	/* page size */
 	gdouble page_width;
@@ -330,26 +330,31 @@ print_info_new (cairo_t          *cr,
 		glLabel          *label)
 {
 	PrintInfo            *pi = g_new0 (PrintInfo, 1);
+        const lglTemplate    *template;
+        gboolean              rotate_flag;
 
 	gl_debug (DEBUG_PRINT, "START");
 
 	g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
 
-	g_return_val_if_fail (label->template, NULL);
-	g_return_val_if_fail (label->template->paper_id, NULL);
-	g_return_val_if_fail (label->template->page_width > 0, NULL);
-	g_return_val_if_fail (label->template->page_height > 0, NULL);
+        template    = gl_label_get_template (label);
+        rotate_flag = gl_label_get_rotate_flag (label);
+
+	g_return_val_if_fail (template, NULL);
+	g_return_val_if_fail (template->paper_id, NULL);
+	g_return_val_if_fail (template->page_width > 0, NULL);
+	g_return_val_if_fail (template->page_height > 0, NULL);
 
 	pi->cr = cr;
 
 	gl_debug (DEBUG_PRINT,
-		  "setting page size = \"%s\"", label->template->paper_id);
+		  "setting page size = \"%s\"", template->paper_id);
 
-	pi->page_width  = label->template->page_width;
-	pi->page_height = label->template->page_height;
+	pi->page_width  = template->page_width;
+	pi->page_height = template->page_height;
 
-	pi->template = label->template;
-	pi->label_rotate_flag = label->rotate_flag;
+	pi->template = template;
+	pi->rotate_flag = rotate_flag;
 
 	gl_debug (DEBUG_PRINT, "END");
 
@@ -516,7 +521,7 @@ print_label (PrintInfo     *pi,
 	cairo_save (pi->cr);
 
         /* Special transformations. */
-	if (label->rotate_flag) {
+	if (pi->rotate_flag) {
 		gl_debug (DEBUG_PRINT, "Rotate flag set");
 		cairo_rotate (pi->cr, M_PI/2.0);
 		cairo_translate (pi->cr, 0.0, -height);
@@ -556,7 +561,7 @@ draw_outline (PrintInfo *pi,
 	cairo_set_source_rgb (pi->cr, OUTLINE_RGB_ARGS);
 	cairo_set_line_width (pi->cr, OUTLINE_WIDTH);
 
-        gl_cairo_label_path (pi->cr, label->template, FALSE, FALSE);
+        gl_cairo_label_path (pi->cr, pi->template, FALSE, FALSE);
 
         cairo_stroke (pi->cr);
 
@@ -575,7 +580,7 @@ clip_to_outline (PrintInfo *pi,
 {
 	gl_debug (DEBUG_PRINT, "START");
 
-        gl_cairo_label_path (pi->cr, label->template, FALSE, TRUE);
+        gl_cairo_label_path (pi->cr, pi->template, FALSE, TRUE);
 
         cairo_set_fill_rule (pi->cr, CAIRO_FILL_RULE_EVEN_ODD);
         cairo_clip (pi->cr);
diff --git a/src/ui-commands.c b/src/ui-commands.c
index a29f18e..d87f9a5 100644
--- a/src/ui-commands.c
+++ b/src/ui-commands.c
@@ -262,7 +262,9 @@ gl_ui_cmd_edit_cut (GtkAction *action,
         g_return_if_fail (action && GTK_IS_ACTION(action));
         g_return_if_fail (window && GL_IS_WINDOW(window));
 
-        gl_view_cut (GL_VIEW(window->view)); 
+        gl_label_cut_selection (GL_VIEW(window->view)->label,
+                                GTK_WIDGET (window));
+
 
         gl_debug (DEBUG_COMMANDS, "END");
 }
@@ -275,12 +277,15 @@ void
 gl_ui_cmd_edit_copy (GtkAction *action,
                      glWindow  *window)
 {
+        GtkClipboard *clipboard;
+
         gl_debug (DEBUG_COMMANDS, "START");
 
         g_return_if_fail (action && GTK_IS_ACTION(action));
         g_return_if_fail (window && GL_IS_WINDOW(window));
 
-        gl_view_copy (GL_VIEW(window->view)); 
+        gl_label_copy_selection (GL_VIEW(window->view)->label,
+                                 GTK_WIDGET (window));
 
         gl_debug (DEBUG_COMMANDS, "END");
 }
@@ -293,12 +298,15 @@ void
 gl_ui_cmd_edit_paste (GtkAction *action,
                       glWindow  *window)
 {
+        GtkClipboard *clipboard;
+
         gl_debug (DEBUG_COMMANDS, "START");
 
         g_return_if_fail (action && GTK_IS_ACTION(action));
         g_return_if_fail (window && GL_IS_WINDOW(window));
 
-        gl_view_paste (GL_VIEW(window->view)); 
+        gl_label_paste (GL_VIEW(window->view)->label,
+                        GTK_WIDGET (window));
 
         gl_debug (DEBUG_COMMANDS, "END");
 }
@@ -316,7 +324,7 @@ gl_ui_cmd_edit_delete (GtkAction *action,
         g_return_if_fail (action && GTK_IS_ACTION(action));
         g_return_if_fail (window && GL_IS_WINDOW(window));
 
-        gl_view_delete_selection (GL_VIEW(window->view)); 
+        gl_label_delete_selection (GL_VIEW(window->view)->label);
 
         gl_debug (DEBUG_COMMANDS, "END");
 }
@@ -334,7 +342,7 @@ gl_ui_cmd_edit_select_all (GtkAction *action,
         g_return_if_fail (action && GTK_IS_ACTION(action));
         g_return_if_fail (window && GL_IS_WINDOW(window));
 
-        gl_view_select_all (GL_VIEW(window->view)); 
+        gl_label_select_all (GL_VIEW(window->view)->label); 
 
         gl_debug (DEBUG_COMMANDS, "END");
 }
@@ -352,7 +360,7 @@ gl_ui_cmd_edit_unselect_all (GtkAction *action,
         g_return_if_fail (action && GTK_IS_ACTION(action));
         g_return_if_fail (window && GL_IS_WINDOW(window));
 
-        gl_view_unselect_all (GL_VIEW(window->view)); 
+        gl_label_unselect_all (GL_VIEW(window->view)->label); 
 
         gl_debug (DEBUG_COMMANDS, "END");
 }
@@ -732,7 +740,7 @@ gl_ui_cmd_objects_raise (GtkAction *action,
         g_return_if_fail (window && GL_IS_WINDOW(window));
 
         if (window->view != NULL) {
-                gl_view_raise_selection (GL_VIEW(window->view));
+                gl_label_raise_selection_to_top (GL_VIEW(window->view)->label);
         }
 
         gl_debug (DEBUG_COMMANDS, "END");
@@ -753,7 +761,7 @@ gl_ui_cmd_objects_lower (GtkAction *action,
         g_return_if_fail (window && GL_IS_WINDOW(window));
 
         if (window->view != NULL) {
-                gl_view_lower_selection (GL_VIEW(window->view));
+                gl_label_lower_selection_to_bottom (GL_VIEW(window->view)->label);
         }
 
         gl_debug (DEBUG_COMMANDS, "END");
@@ -774,7 +782,7 @@ gl_ui_cmd_objects_rotate_left (GtkAction *action,
         g_return_if_fail (window && GL_IS_WINDOW(window));
 
         if (window->view != NULL) {
-                gl_view_rotate_selection_left (GL_VIEW(window->view));
+                gl_label_rotate_selection_left (GL_VIEW(window->view)->label);
         }
 
         gl_debug (DEBUG_COMMANDS, "END");
@@ -795,7 +803,7 @@ gl_ui_cmd_objects_rotate_right (GtkAction *action,
         g_return_if_fail (window && GL_IS_WINDOW(window));
 
         if (window->view != NULL) {
-                gl_view_rotate_selection_right (GL_VIEW(window->view));
+                gl_label_rotate_selection_right (GL_VIEW(window->view)->label);
         }
 
         gl_debug (DEBUG_COMMANDS, "END");
@@ -816,7 +824,7 @@ gl_ui_cmd_objects_flip_horiz (GtkAction *action,
         g_return_if_fail (window && GL_IS_WINDOW(window));
 
         if (window->view != NULL) {
-                gl_view_flip_selection_horiz (GL_VIEW(window->view));
+                gl_label_flip_selection_horiz (GL_VIEW(window->view)->label);
         }
 
         gl_debug (DEBUG_COMMANDS, "END");
@@ -837,7 +845,7 @@ gl_ui_cmd_objects_flip_vert (GtkAction *action,
         g_return_if_fail (window && GL_IS_WINDOW(window));
 
         if (window->view != NULL) {
-                gl_view_flip_selection_vert (GL_VIEW(window->view));
+                gl_label_flip_selection_vert (GL_VIEW(window->view)->label);
         }
 
         gl_debug (DEBUG_COMMANDS, "END");
@@ -858,7 +866,7 @@ gl_ui_cmd_objects_align_left (GtkAction *action,
         g_return_if_fail (window && GL_IS_WINDOW(window));
 
         if (window->view != NULL) {
-                gl_view_align_selection_left (GL_VIEW(window->view));
+                gl_label_align_selection_left (GL_VIEW(window->view)->label);
         }
 
         gl_debug (DEBUG_COMMANDS, "END");
@@ -879,7 +887,7 @@ gl_ui_cmd_objects_align_right (GtkAction *action,
         g_return_if_fail (window && GL_IS_WINDOW(window));
 
         if (window->view != NULL) {
-                gl_view_align_selection_right (GL_VIEW(window->view));
+                gl_label_align_selection_right (GL_VIEW(window->view)->label);
         }
 
         gl_debug (DEBUG_COMMANDS, "END");
@@ -900,7 +908,7 @@ gl_ui_cmd_objects_align_hcenter (GtkAction *action,
         g_return_if_fail (window && GL_IS_WINDOW(window));
 
         if (window->view != NULL) {
-                gl_view_align_selection_hcenter (GL_VIEW(window->view));
+                gl_label_align_selection_hcenter (GL_VIEW(window->view)->label);
         }
 
         gl_debug (DEBUG_COMMANDS, "END");
@@ -921,7 +929,7 @@ gl_ui_cmd_objects_align_top (GtkAction *action,
         g_return_if_fail (window && GL_IS_WINDOW(window));
 
         if (window->view != NULL) {
-                gl_view_align_selection_top (GL_VIEW(window->view));
+                gl_label_align_selection_top (GL_VIEW(window->view)->label);
         }
 
         gl_debug (DEBUG_COMMANDS, "END");
@@ -942,7 +950,7 @@ gl_ui_cmd_objects_align_bottom (GtkAction *action,
         g_return_if_fail (window && GL_IS_WINDOW(window));
 
         if (window->view != NULL) {
-                gl_view_align_selection_bottom (GL_VIEW(window->view));
+                gl_label_align_selection_bottom (GL_VIEW(window->view)->label);
         }
 
         gl_debug (DEBUG_COMMANDS, "END");
@@ -963,7 +971,7 @@ gl_ui_cmd_objects_align_vcenter (GtkAction *action,
         g_return_if_fail (window && GL_IS_WINDOW(window));
 
         if (window->view != NULL) {
-                gl_view_align_selection_vcenter (GL_VIEW(window->view));
+                gl_label_align_selection_vcenter (GL_VIEW(window->view)->label);
         }
 
         gl_debug (DEBUG_COMMANDS, "END");
@@ -984,7 +992,7 @@ gl_ui_cmd_objects_center_horiz (GtkAction *action,
         g_return_if_fail (window && GL_IS_WINDOW(window));
 
         if (window->view != NULL) {
-                gl_view_center_selection_horiz (GL_VIEW(window->view));
+                gl_label_center_selection_horiz (GL_VIEW(window->view)->label);
         }
 
         gl_debug (DEBUG_COMMANDS, "END");
@@ -1005,7 +1013,7 @@ gl_ui_cmd_objects_center_vert (GtkAction *action,
         g_return_if_fail (window && GL_IS_WINDOW(window));
 
         if (window->view != NULL) {
-                gl_view_center_selection_vert (GL_VIEW(window->view));
+                gl_label_center_selection_vert (GL_VIEW(window->view)->label);
         }
 
         gl_debug (DEBUG_COMMANDS, "END");
diff --git a/src/ui-property-bar.c b/src/ui-property-bar.c
index 7df4543..bf2139d 100644
--- a/src/ui-property-bar.c
+++ b/src/ui-property-bar.c
@@ -47,7 +47,7 @@
 
 struct _glUIPropertyBarPrivate {
 
-	glView     *view;
+	glLabel    *label;
 
 	GtkBuilder *builder;
 
@@ -94,7 +94,8 @@ static void     gl_ui_property_bar_finalize      (GObject              *object);
 
 static void     gl_ui_property_bar_construct     (glUIPropertyBar      *this);
 
-static void     selection_changed_cb             (glUIPropertyBar      *this);
+static void     selection_changed_cb             (glUIPropertyBar      *this,
+                                                  glLabel              *label);
 
 static void     font_family_changed_cb           (GtkComboBox          *combo,
 						  glUIPropertyBar      *this);
@@ -187,9 +188,9 @@ gl_ui_property_bar_finalize (GObject *object)
 	g_return_if_fail (object != NULL);
 	g_return_if_fail (GL_IS_UI_PROPERTY_BAR (object));
 
-	if (this->priv->view)
+	if (this->priv->label)
         {
-		g_object_unref (G_OBJECT(this->priv->view));
+		g_object_unref (G_OBJECT(this->priv->label));
 	}
         if (this->priv->builder)
         {
@@ -387,67 +388,65 @@ gl_ui_property_bar_construct (glUIPropertyBar   *this)
 /* Fill widgets with default values.                                        */
 /****************************************************************************/
 static void
-reset_to_default_properties (glView          *view,
+reset_to_default_properties (glLabel         *label,
 			     glUIPropertyBar *this)
 {
+        gchar *family;
 
-	gl_font_combo_set_family (GL_FONT_COMBO (this->priv->font_family_combo),
-                                  view->default_font_family);
+        family = gl_label_get_default_font_family (label);
+	gl_font_combo_set_family (GL_FONT_COMBO (this->priv->font_family_combo), family);
+        g_free (family);
 
 	gtk_spin_button_set_value (GTK_SPIN_BUTTON(this->priv->font_size_spin),
-				   view->default_font_size);
+				   gl_label_get_default_font_size (label));
 
 	gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->font_bold_toggle),
-					   (view->default_font_weight == PANGO_WEIGHT_BOLD));
+					   (gl_label_get_default_font_weight (label) == PANGO_WEIGHT_BOLD));
 	gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->font_italic_toggle),
-					   view->default_font_italic_flag);
+					   gl_label_get_default_font_italic_flag (label));
 
 	gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_left_radio),
-					   (view->default_text_alignment == PANGO_ALIGN_LEFT));
+					   (gl_label_get_default_text_alignment (label) == PANGO_ALIGN_LEFT));
 	gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_center_radio),
-					   (view->default_text_alignment == PANGO_ALIGN_CENTER));
+					   (gl_label_get_default_text_alignment (label) == PANGO_ALIGN_CENTER));
 	gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_right_radio),
-					   (view->default_text_alignment == PANGO_ALIGN_RIGHT));
+					   (gl_label_get_default_text_alignment (label) == PANGO_ALIGN_RIGHT));
 
 	gl_color_combo_button_set_color (GL_COLOR_COMBO_BUTTON(this->priv->text_color_button),
-                                         view->default_text_color);
+                                         gl_label_get_default_text_color (label));
 
 	gl_color_combo_button_set_color (GL_COLOR_COMBO_BUTTON(this->priv->fill_color_button),
-                                         view->default_fill_color);
+                                         gl_label_get_default_fill_color (label));
 
 	gl_color_combo_button_set_color (GL_COLOR_COMBO_BUTTON(this->priv->line_color_button),
-                                         view->default_line_color);
+                                         gl_label_get_default_line_color (label));
 
 	gtk_spin_button_set_value (GTK_SPIN_BUTTON(this->priv->line_width_spin),
-				   view->default_line_width);
+				   gl_label_get_default_line_width (label));
 }
 
 
 /****************************************************************************/
-/* Set view associated with property_bar.                                   */
+/* Set label associated with property_bar.                                  */
 /****************************************************************************/
 void
-gl_ui_property_bar_set_view (glUIPropertyBar *this,
-			     glView          *view)
+gl_ui_property_bar_set_label (glUIPropertyBar *this,
+                              glLabel         *label)
 {
-	glLabel   *label;
-
 	gl_debug (DEBUG_PROPERTY_BAR, "START");
 
-	g_return_if_fail (view && GL_IS_VIEW (view));
-	label = view->label;
 	g_return_if_fail (label && GL_IS_LABEL (label));
 
 	set_doc_items_sensitive (this, TRUE);
 
-	this->priv->view = GL_VIEW (g_object_ref (G_OBJECT (view)));
+	this->priv->label = GL_LABEL (g_object_ref (G_OBJECT (label)));
 
-	reset_to_default_properties (view, this);
+	reset_to_default_properties (label, this);
 
-	g_signal_connect_swapped (G_OBJECT(view), "selection_changed",
+	g_signal_connect_swapped (G_OBJECT(label), "selection_changed",
 				  G_CALLBACK(selection_changed_cb), this);
 
-	g_signal_connect_swapped (G_OBJECT(view->label), "changed",
+	g_signal_connect_swapped (G_OBJECT(label), "changed",
 				  G_CALLBACK(selection_changed_cb), this);
 
 	gl_debug (DEBUG_PROPERTY_BAR, "END");
@@ -455,16 +454,17 @@ gl_ui_property_bar_set_view (glUIPropertyBar *this,
 
 
 /*---------------------------------------------------------------------------*/
-/* PRIVATE.  View "selection state changed" callback.                        */
+/* PRIVATE.  Label "selection state changed" callback.                       */
 /*---------------------------------------------------------------------------*/
 static void
-update_text_properties (glView *view,
+update_text_properties (glLabel         *label,
 			glUIPropertyBar *this)
 {
 	gboolean        can_text, is_first_object;
 	gboolean        is_same_font_family, is_same_font_size;
 	gboolean        is_same_text_color, is_same_is_italic;
 	gboolean        is_same_is_bold, is_same_align;
+	GList          *selection_list;
 	GList          *p;
 	glLabelObject  *object;
 	gchar          *selection_font_family, *font_family;
@@ -475,7 +475,7 @@ update_text_properties (glView *view,
 	gboolean        selection_is_bold, is_bold;
 	PangoAlignment  selection_align, align;
 
-	can_text = gl_view_can_selection_text (view);
+	can_text = gl_label_can_selection_text (label);
 	set_text_items_sensitive (this, can_text);
 
 	if (!can_text) 
@@ -496,10 +496,11 @@ update_text_properties (glView *view,
         
 	is_first_object = TRUE;
 	
-	for (p = view->selected_object_list; p != NULL; p = p->next)
+        selection_list = gl_label_get_selection_list (label);
+	for (p = selection_list; p != NULL; p = p->next)
         {
 
-		object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
+		object = GL_LABEL_OBJECT (p->data);
 		if (!gl_label_object_can_text (object)) 
 			continue;
 
@@ -563,6 +564,8 @@ update_text_properties (glView *view,
 		is_first_object = FALSE;
 	}
 
+        g_list_free (selection_list);
+
 	if (is_same_font_family && (selection_font_family != NULL)) 
 		gl_debug (DEBUG_PROPERTY_BAR, "same font family = %s", 
 			  selection_font_family);
@@ -620,17 +623,18 @@ update_text_properties (glView *view,
 
 
 static void
-update_fill_color (glView *view,
+update_fill_color (glLabel         *label,
 		   glUIPropertyBar *this)
 {
 	gboolean can, is_first_object;
 	gboolean is_same_fill_color;
+        GList *selection_list;
 	GList *p;
 	glLabelObject *object;
 	guint selection_fill_color, fill_color;
 	glColorNode *fill_color_node;
 
-	can = gl_view_can_selection_fill (view);
+	can = gl_label_can_selection_fill (label);
 	set_fill_items_sensitive (this, can);
 
 	if (!can) 
@@ -639,11 +643,13 @@ update_fill_color (glView *view,
 	is_same_fill_color = TRUE;
 	is_first_object = TRUE;
         selection_fill_color = 0;
+
+        selection_list = gl_label_get_selection_list (label);
 	
-	for (p = view->selected_object_list; p != NULL; p = p->next)
+	for (p = selection_list; p != NULL; p = p->next)
         {
 
-		object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
+		object = GL_LABEL_OBJECT (p->data);
 		if (!gl_label_object_can_fill (object)) 
 			continue;
 
@@ -674,6 +680,8 @@ update_fill_color (glView *view,
 		is_first_object = FALSE;
 	}
 
+        g_list_free (selection_list);
+
 	if (is_same_fill_color)
         {
 		gl_debug (DEBUG_PROPERTY_BAR, "same fill color = %08x", selection_fill_color);
@@ -684,17 +692,18 @@ update_fill_color (glView *view,
 
 
 static void
-update_line_color (glView *view,
+update_line_color (glLabel         *label,
 		   glUIPropertyBar *this)
 {
 	gboolean can, is_first_object;
 	gboolean is_same_line_color;
+        GList *selection_list;
 	GList *p;
 	glLabelObject *object;
 	guint selection_line_color, line_color;
 	glColorNode *line_color_node;
 
-	can = gl_view_can_selection_line_color (view);
+	can = gl_label_can_selection_line_color (label);
 	set_line_color_items_sensitive (this, can);
 
 	if (!can) 
@@ -703,11 +712,13 @@ update_line_color (glView *view,
 	is_same_line_color = TRUE;
 	is_first_object = TRUE;
         selection_line_color = 0;
+
+        selection_list = gl_label_get_selection_list (label);
 	
-	for (p = view->selected_object_list; p != NULL; p = p->next)
+	for (p = selection_list; p != NULL; p = p->next)
         {
 
-		object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
+		object = GL_LABEL_OBJECT (p->data);
 		if (!gl_label_object_can_line_color (object)) 
 			continue;
 
@@ -738,6 +749,8 @@ update_line_color (glView *view,
 		is_first_object = FALSE;
 	}
 
+        g_list_free (selection_list);
+
 	if (is_same_line_color)
         {
 		gl_debug (DEBUG_PROPERTY_BAR, "same line color = %08x", selection_line_color);
@@ -748,16 +761,17 @@ update_line_color (glView *view,
 
 
 static void
-update_line_width (glView *view,
+update_line_width (glLabel         *label,
 		   glUIPropertyBar *this)
 {
 	gboolean can, is_first_object;
 	gboolean is_same_line_width;
+	GList *selection_list;
 	GList *p;
 	glLabelObject *object;
 	gdouble selection_line_width, line_width;
 
-	can = gl_view_can_selection_line_width (view);
+	can = gl_label_can_selection_line_width (label);
 	set_line_width_items_sensitive (this, can);
 
 	if (!can) 
@@ -766,11 +780,13 @@ update_line_width (glView *view,
 	is_same_line_width = TRUE;
 	is_first_object = TRUE;
         selection_line_width = 0;
+
+        selection_list = gl_label_get_selection_list (label);
 	
-	for (p = view->selected_object_list; p != NULL; p = p->next)
+	for (p = selection_list; p != NULL; p = p->next)
         {
 
-		object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
+		object = GL_LABEL_OBJECT (p->data);
 		if (!gl_label_object_can_line_width (object)) 
 			continue;
 
@@ -790,6 +806,8 @@ update_line_width (glView *view,
 		is_first_object = FALSE;
 	}
 
+        g_list_free (selection_list);
+
 	if (is_same_line_width)
         {
 		gl_debug (DEBUG_PROPERTY_BAR, "same line width = %g", selection_line_width);
@@ -804,11 +822,10 @@ update_line_width (glView *view,
 
 
 static void 
-selection_changed_cb (glUIPropertyBar *this)
+selection_changed_cb (glUIPropertyBar *this,
+                      glLabel         *label)
 {
-	glView *view = this->priv->view;
-	
-	g_return_if_fail (view && GL_IS_VIEW (view));
+	g_return_if_fail (label && GL_IS_LABEL (label));
 	g_return_if_fail (this && GL_IS_UI_PROPERTY_BAR (this));
 
 	if (this->priv->stop_signals) return;
@@ -816,18 +833,18 @@ selection_changed_cb (glUIPropertyBar *this)
 
 	gl_debug (DEBUG_PROPERTY_BAR, "START");
 
-	if (gl_view_is_selection_empty (view))
+	if (gl_label_is_selection_empty (label))
         {
 		/* No selection: make all controls active. */
-		reset_to_default_properties (view, this);
+		reset_to_default_properties (label, this);
 		set_doc_items_sensitive (this, TRUE);
 	}
         else
         {
-		update_text_properties (view, this);
-		update_fill_color (view, this);
-		update_line_color (view, this);
-		update_line_width (view, this);
+		update_text_properties (label, this);
+		update_fill_color (label, this);
+		update_line_color (label, this);
+		update_line_width (label, this);
 	}
 
 	gl_debug (DEBUG_PROPERTY_BAR, "END");
@@ -853,10 +870,10 @@ font_family_changed_cb (GtkComboBox     *combo,
 	font_family = gl_font_combo_get_family (GL_FONT_COMBO (combo));
 	if ( strlen(font_family) )
         {
-		gl_view_set_selection_font_family (this->priv->view,
-						   font_family);
-		gl_view_set_default_font_family   (this->priv->view,
-						   font_family);
+		gl_label_set_selection_font_family (this->priv->label,
+                                                    font_family);
+		gl_label_set_default_font_family   (this->priv->label,
+                                                    font_family);
 	}
 	g_free (font_family);
 
@@ -882,10 +899,10 @@ font_size_changed_cb (GtkSpinButton        *spin,
 
 	font_size = gtk_spin_button_get_value (spin);
 
-	gl_view_set_selection_font_size (this->priv->view,
-					 font_size);
-	gl_view_set_default_font_size   (this->priv->view,
-					 font_size);
+	gl_label_set_selection_font_size (this->priv->label,
+					  font_size);
+	gl_label_set_default_font_size   (this->priv->label,
+                                          font_size);
 
 	gl_debug (DEBUG_PROPERTY_BAR, "END");
 
@@ -920,17 +937,17 @@ text_color_changed_cb (glColorComboButton   *cc,
 	if (is_default)
         {
 		text_color_node->color = gl_prefs_model_get_default_text_color (gl_prefs);
-		gl_view_set_selection_text_color (this->priv->view,
-						  text_color_node);
-		gl_view_set_default_text_color   (this->priv->view,
-						  text_color_node->color);
+		gl_label_set_selection_text_color (this->priv->label,
+                                                   text_color_node);
+		gl_label_set_default_text_color   (this->priv->label,
+						   text_color_node->color);
 	}
         else
         {
-		gl_view_set_selection_text_color (this->priv->view,
-						  text_color_node);
-		gl_view_set_default_text_color   (this->priv->view,
-						  text_color_node->color);
+		gl_label_set_selection_text_color (this->priv->label,
+                                                   text_color_node);
+		gl_label_set_default_text_color   (this->priv->label,
+						   text_color_node->color);
 	}
 
 	gl_color_node_free (&text_color_node);
@@ -970,17 +987,17 @@ fill_color_changed_cb (glColorComboButton   *cc,
         {
 
 		fill_color_node->color = GL_COLOR_NONE;
-		gl_view_set_selection_fill_color (this->priv->view,
-						  fill_color_node);
-		gl_view_set_default_fill_color   (this->priv->view,
-						  fill_color_node->color);
+		gl_label_set_selection_fill_color (this->priv->label,
+                                                   fill_color_node);
+		gl_label_set_default_fill_color   (this->priv->label,
+                                                   fill_color_node->color);
 	}
         else
         {
-		gl_view_set_selection_fill_color (this->priv->view,
-						  fill_color_node);
-		gl_view_set_default_fill_color   (this->priv->view,
-						  fill_color_node->color);
+		gl_label_set_selection_fill_color (this->priv->label,
+                                                   fill_color_node);
+		gl_label_set_default_fill_color   (this->priv->label,
+                                                   fill_color_node->color);
 	}
 	gl_color_node_free (&fill_color_node);
 	
@@ -1017,17 +1034,17 @@ line_color_changed_cb (glColorComboButton   *cc,
 	if (is_default)
         {
 		line_color_node->color = GL_COLOR_NONE;
-		gl_view_set_selection_line_color (this->priv->view,
-						  line_color_node);
-		gl_view_set_default_line_color   (this->priv->view,
-						  line_color_node->color);
+		gl_label_set_selection_line_color (this->priv->label,
+                                                   line_color_node);
+		gl_label_set_default_line_color   (this->priv->label,
+                                                   line_color_node->color);
 	}
         else
         {
-		gl_view_set_selection_line_color (this->priv->view,
-						  line_color_node);
-		gl_view_set_default_line_color   (this->priv->view,
-						  line_color_node->color);
+		gl_label_set_selection_line_color (this->priv->label,
+                                                   line_color_node);
+		gl_label_set_default_line_color   (this->priv->label,
+                                                   line_color_node->color);
 	}
 	gl_color_node_free (&line_color_node);
 
@@ -1051,14 +1068,14 @@ line_width_changed_cb (GtkSpinButton        *spin,
 
 	gl_debug (DEBUG_PROPERTY_BAR, "START");
 
-	if (this->priv->view)
+	if (this->priv->label)
         {
 		line_width = gtk_spin_button_get_value (spin);
 
-		gl_view_set_selection_line_width (this->priv->view,
-						  line_width);
-		gl_view_set_default_line_width   (this->priv->view,
-						  line_width);
+		gl_label_set_selection_line_width (this->priv->label,
+                                                   line_width);
+		gl_label_set_default_line_width   (this->priv->label,
+                                                   line_width);
 	}
 
 	gl_debug (DEBUG_PROPERTY_BAR, "END");
@@ -1087,8 +1104,8 @@ font_bold_toggled_cb (GtkToggleToolButton  *toggle,
 
 	weight = state ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL;
 
-	gl_view_set_selection_font_weight (this->priv->view, weight);
-	gl_view_set_default_font_weight   (this->priv->view, weight);
+	gl_label_set_selection_font_weight (this->priv->label, weight);
+	gl_label_set_default_font_weight   (this->priv->label, weight);
 
 	gl_debug (DEBUG_PROPERTY_BAR, "END");
 
@@ -1112,14 +1129,14 @@ font_italic_toggled_cb (GtkToggleToolButton  *toggle,
 
 	state = gtk_toggle_tool_button_get_active (toggle);
 
-	gl_view_set_selection_font_italic_flag (this->priv->view, state);
-	gl_view_set_default_font_italic_flag   (this->priv->view, state);
+	gl_label_set_selection_font_italic_flag (this->priv->label, state);
+	gl_label_set_default_font_italic_flag   (this->priv->label, state);
 
 	gl_debug (DEBUG_PROPERTY_BAR, "END");
 
 	this->priv->stop_signals = FALSE;
 }
-						  
+
 
 /*---------------------------------------------------------------------------*/
 /* PRIVATE.  Text align toggled callback.                                    */
@@ -1135,26 +1152,26 @@ text_align_toggled_cb (GtkToggleToolButton  *toggle,
 
 	if (gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_left_radio)))
 	{		
-		gl_view_set_selection_text_alignment (this->priv->view,
-						      PANGO_ALIGN_LEFT);
-		gl_view_set_default_text_alignment   (this->priv->view,
-						      PANGO_ALIGN_LEFT);
+		gl_label_set_selection_text_alignment (this->priv->label,
+                                                       PANGO_ALIGN_LEFT);
+		gl_label_set_default_text_alignment   (this->priv->label,
+                                                       PANGO_ALIGN_LEFT);
 	}
 
 	if (gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_center_radio)))
 	{		
-		gl_view_set_selection_text_alignment (this->priv->view,
-						      PANGO_ALIGN_CENTER);
-		gl_view_set_default_text_alignment   (this->priv->view,
-						      PANGO_ALIGN_CENTER);
+		gl_label_set_selection_text_alignment (this->priv->label,
+                                                       PANGO_ALIGN_CENTER);
+		gl_label_set_default_text_alignment   (this->priv->label,
+                                                       PANGO_ALIGN_CENTER);
 	}
 
 	if (gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_right_radio)))
 	{
-		gl_view_set_selection_text_alignment (this->priv->view,
-						      PANGO_ALIGN_RIGHT);
-		gl_view_set_default_text_alignment   (this->priv->view,
-						      PANGO_ALIGN_RIGHT);
+		gl_label_set_selection_text_alignment (this->priv->label,
+                                                       PANGO_ALIGN_RIGHT);
+		gl_label_set_default_text_alignment   (this->priv->label,
+                                                       PANGO_ALIGN_RIGHT);
 	}
 
 	gl_debug (DEBUG_PROPERTY_BAR, "END");
diff --git a/src/ui-property-bar.h b/src/ui-property-bar.h
index 9256827..9bc092b 100644
--- a/src/ui-property-bar.h
+++ b/src/ui-property-bar.h
@@ -23,7 +23,7 @@
 
 #include <gtk/gtk.h>
 
-#include "view.h"
+#include "label.h"
 
 G_BEGIN_DECLS
 
@@ -57,8 +57,8 @@ GType        gl_ui_property_bar_get_type          (void) G_GNUC_CONST;
 
 GtkWidget   *gl_ui_property_bar_new               (void);
 
-void         gl_ui_property_bar_set_view          (glUIPropertyBar *this,
-						   glView          *view);
+void         gl_ui_property_bar_set_label         (glUIPropertyBar *this,
+						   glLabel         *label);
 
 
 G_END_DECLS
diff --git a/src/ui-sidebar.c b/src/ui-sidebar.c
index 1a821ce..7042ef9 100644
--- a/src/ui-sidebar.c
+++ b/src/ui-sidebar.c
@@ -44,10 +44,7 @@
 
 struct _glUISidebarPrivate {
 
-	glView              *view;
-
-	GtkWidget           *child;
-	GtkWidget           *empty_child;
+	GtkWidget           *editor;
 };
 
 /*===========================================================================*/
@@ -63,9 +60,6 @@ static void     gl_ui_sidebar_finalize      (GObject              *object);
 
 static void     gl_ui_sidebar_construct     (glUISidebar          *sidebar);
 
-static void     selection_changed_cb        (glView               *view,
-					     glUISidebar          *sidebar);
-
 
 /****************************************************************************/
 /* Boilerplate Object stuff.                                                */
@@ -109,9 +103,6 @@ gl_ui_sidebar_finalize (GObject *object)
 	g_return_if_fail (object != NULL);
 	g_return_if_fail (GL_IS_UI_SIDEBAR (object));
 
-	if (sidebar->priv->view) {
-		g_object_unref (G_OBJECT(sidebar->priv->view));
-	}
 	g_free (sidebar->priv);
 
 	G_OBJECT_CLASS (gl_ui_sidebar_parent_class)->finalize (object);
@@ -150,71 +141,27 @@ gl_ui_sidebar_construct (glUISidebar       *sidebar)
 {
 	gl_debug (DEBUG_UI, "START");
 
-	sidebar->priv->empty_child = gl_object_editor_new (GL_STOCK_PROPERTIES,
-							   _("Object properties"),
-                                                           NULL,
-							   GL_OBJECT_EDITOR_EMPTY,
-							   NULL);
-
-	sidebar->priv->child = g_object_ref (sidebar->priv->empty_child);
-	gtk_widget_show (sidebar->priv->child);
-	gtk_container_add (GTK_CONTAINER(sidebar), sidebar->priv->child);
+	sidebar->priv->editor = gl_object_editor_new ();
+	gtk_widget_show (sidebar->priv->editor);
 
-	gtk_widget_set_sensitive (GTK_WIDGET (sidebar), FALSE);
+	gtk_container_add (GTK_CONTAINER(sidebar), sidebar->priv->editor);
 
 	gl_debug (DEBUG_UI, "END");
 }
 
 
 /****************************************************************************/
-/* Set view associated with sidebar.                                        */
+/* Set label associated with sidebar.                                       */
 /****************************************************************************/
 void
-gl_ui_sidebar_set_view (glUISidebar *sidebar,
-			glView      *view)
-{
-	gl_debug (DEBUG_UI, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	gtk_widget_set_sensitive (GTK_WIDGET (sidebar), TRUE);
-
-	sidebar->priv->view = GL_VIEW (g_object_ref (G_OBJECT (view)));
-
-	g_signal_connect (G_OBJECT(view), "selection_changed",
-			  G_CALLBACK(selection_changed_cb), sidebar);
-
-	gl_debug (DEBUG_UI, "END");
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE.  View "selection state changed" callback.                        */
-/*---------------------------------------------------------------------------*/
-static void 
-selection_changed_cb (glView      *view,
-		      glUISidebar *sidebar)
+gl_ui_sidebar_set_label (glUISidebar *sidebar,
+                         glLabel     *label)
 {
 	gl_debug (DEBUG_UI, "START");
 
-	g_return_if_fail (view && GL_IS_VIEW (view));
-	g_return_if_fail (sidebar && GL_IS_UI_SIDEBAR (sidebar));
-
-	gtk_container_remove (GTK_CONTAINER(sidebar), sidebar->priv->child);
-
-	if (gl_view_is_selection_empty (view) || !gl_view_is_selection_atomic (view)) {
-
-		sidebar->priv->child = g_object_ref (sidebar->priv->empty_child);
-		
-	} else {
-
-		sidebar->priv->child = g_object_ref (gl_view_get_editor (view));
-
-	}
-
-	gtk_widget_show (sidebar->priv->child);
+	g_return_if_fail (label && GL_IS_LABEL (label));
 
-	gtk_box_pack_start (GTK_BOX(sidebar), sidebar->priv->child, TRUE, TRUE, 0);
+        gl_object_editor_set_label (GL_OBJECT_EDITOR (sidebar->priv->editor), label);
 
 	gl_debug (DEBUG_UI, "END");
 }
diff --git a/src/ui-sidebar.h b/src/ui-sidebar.h
index 7139525..3ff5f91 100644
--- a/src/ui-sidebar.h
+++ b/src/ui-sidebar.h
@@ -56,8 +56,8 @@ GType        gl_ui_sidebar_get_type          (void) G_GNUC_CONST;
 
 GtkWidget   *gl_ui_sidebar_new               (void);
 
-void         gl_ui_sidebar_set_view          (glUISidebar       *sidebar,
-					      glView            *view);
+void         gl_ui_sidebar_set_label         (glUISidebar       *sidebar,
+					      glLabel           *label);
 
 
 G_END_DECLS
diff --git a/src/ui.c b/src/ui.c
index 5449d28..f7d0e9f 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -821,14 +821,14 @@ gl_ui_update_all (GtkUIManager *ui,
 				       !gl_view_is_zoom_min (view));
 
 	gl_ui_util_set_verb_list_sensitive (ui, selection_verbs,
-					    !gl_view_is_selection_empty (view));
+					    !gl_label_is_selection_empty (view->label));
 
 	gl_ui_util_set_verb_list_sensitive (ui, atomic_selection_verbs,
-					    gl_view_is_selection_atomic (view));
+					    gl_label_is_selection_atomic (view->label));
 
 	gl_ui_util_set_verb_list_sensitive (ui, multi_selection_verbs,
-					    !gl_view_is_selection_empty (view)
-					    && !gl_view_is_selection_atomic (view));
+					    !gl_label_is_selection_empty (view->label)
+					    && !gl_label_is_selection_atomic (view->label));
 
 	gl_debug (DEBUG_UI, "END");
 }
@@ -875,14 +875,14 @@ gl_ui_update_selection_verbs (GtkUIManager *ui,
 	gl_debug (DEBUG_UI, "START");
 
 	gl_ui_util_set_verb_list_sensitive (ui, selection_verbs,
-					    !gl_view_is_selection_empty (view));
+					    !gl_label_is_selection_empty (view->label));
 
 	gl_ui_util_set_verb_list_sensitive (ui, atomic_selection_verbs,
-					    gl_view_is_selection_atomic (view));
+					    gl_label_is_selection_atomic (view->label));
 
 	gl_ui_util_set_verb_list_sensitive (ui, multi_selection_verbs,
-					    !gl_view_is_selection_empty (view)
-					    && !gl_view_is_selection_atomic (view));
+					    !gl_label_is_selection_empty (view->label)
+					    && !gl_label_is_selection_atomic (view->label));
 
 	gl_debug (DEBUG_UI, "END");
 }
diff --git a/src/view-barcode.c b/src/view-barcode.c
index 84b9cfa..27a14f2 100644
--- a/src/view-barcode.c
+++ b/src/view-barcode.c
@@ -22,12 +22,7 @@
 
 #include "view-barcode.h"
 
-#include <glib/gi18n.h>
-#include <glib.h>
-
-#include "color.h"
-#include "object-editor.h"
-#include "stock.h"
+#include "label-barcode.h"
 
 #include "pixmaps/cursor_barcode.xbm"
 #include "pixmaps/cursor_barcode_mask.xbm"
@@ -44,9 +39,6 @@
 /* Private types.                                         */
 /*========================================================*/
 
-struct _glViewBarcodePrivate {
-};
-
 
 /*========================================================*/
 /* Private globals.                                       */
@@ -57,286 +49,6 @@ struct _glViewBarcodePrivate {
 /* Private function prototypes.                           */
 /*========================================================*/
 
-static void       gl_view_barcode_finalize          (GObject          *object);
-
-static GtkWidget *construct_properties_editor       (glViewObject     *view_object);
-
-static void       update_object_from_editor_cb      (glObjectEditor   *editor,
-						     glLabelObject    *object);
-
-static void       update_editor_from_object_cb      (glLabelObject    *object,
-						     glObjectEditor   *editor);
-
-static void       update_editor_from_move_cb        (glLabelObject    *object,
-						     gdouble           dx,
-						     gdouble           dy,
-						     glObjectEditor   *editor);
-
-static gboolean   object_at                         (glViewObject     *view_object,
-                                                     cairo_t          *cr,
-                                                     gdouble           x,
-                                                     gdouble           y);
-
-
-/*****************************************************************************/
-/* Boilerplate object stuff.                                                 */
-/*****************************************************************************/
-G_DEFINE_TYPE (glViewBarcode, gl_view_barcode, GL_TYPE_VIEW_OBJECT);
-
-
-static void
-gl_view_barcode_class_init (glViewBarcodeClass *class)
-{
-	GObjectClass      *object_class      = G_OBJECT_CLASS (class);
-	glViewObjectClass *view_object_class = GL_VIEW_OBJECT_CLASS (class);
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	gl_view_barcode_parent_class = g_type_class_peek_parent (class);
-
-	object_class->finalize = gl_view_barcode_finalize;
-
-	view_object_class->construct_editor = construct_properties_editor;
-	view_object_class->object_at        = object_at;
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-static void
-gl_view_barcode_init (glViewBarcode *view_barcode)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	view_barcode->priv = g_new0 (glViewBarcodePrivate, 1);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-static void
-gl_view_barcode_finalize (GObject *object)
-{
-        glViewBarcode *view_barcode = GL_VIEW_BARCODE (object);
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (object && GL_IS_VIEW_BARCODE (object));
-
-        g_free (view_barcode->priv);
-
-	G_OBJECT_CLASS (gl_view_barcode_parent_class)->finalize (object);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* NEW barcode object view.                                                  */
-/*****************************************************************************/
-glViewObject *
-gl_view_barcode_new (glLabelBarcode *object,
-                     glView         *view)
-{
-	glViewBarcode         *view_barcode;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_val_if_fail (object && GL_IS_LABEL_BARCODE (object), NULL);
-	g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
-	
-	view_barcode = g_object_new (gl_view_barcode_get_type(), NULL);
-
-	gl_view_object_set_object (GL_VIEW_OBJECT(view_barcode),
-				   GL_LABEL_OBJECT(object),
-				   GL_VIEW_OBJECT_HANDLES_BOX);
-	gl_view_object_set_view (GL_VIEW_OBJECT(view_barcode), view);
-
-	gl_debug (DEBUG_VIEW, "END");
-
-	return GL_VIEW_OBJECT (view_barcode);
-}
-
-
-/*****************************************************************************/
-/* Create a properties dialog for a barcode object.                          */
-/*****************************************************************************/
-static GtkWidget *
-construct_properties_editor (glViewObject *view_object)
-{
-	GtkWidget          *editor;
-	glViewBarcode      *view_bc = (glViewBarcode *)view_object;
-	glLabelObject      *object;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	object = gl_view_object_get_object (GL_VIEW_OBJECT(view_bc));
-
-	/* Build editor. */
-	editor = gl_object_editor_new (GL_STOCK_BARCODE, _("Barcode object properties"),
-                                       object->parent,
-				       GL_OBJECT_EDITOR_POSITION_PAGE,
-				       GL_OBJECT_EDITOR_SIZE_PAGE,
-				       GL_OBJECT_EDITOR_BC_PAGE,
-				       GL_OBJECT_EDITOR_DATA_PAGE,
-				       0);
-
-	/* Update */
-	update_editor_from_object_cb (object, GL_OBJECT_EDITOR(editor));
-	update_editor_from_move_cb (object, 0, 0, GL_OBJECT_EDITOR(editor));
-
-	/* Connect signals. */
-	g_signal_connect (G_OBJECT (editor), "changed",
-			  G_CALLBACK(update_object_from_editor_cb), object);
-	g_signal_connect (G_OBJECT (object), "changed",
-			  G_CALLBACK (update_editor_from_object_cb), editor);
-	g_signal_connect (G_OBJECT (object), "moved",
-			  G_CALLBACK (update_editor_from_move_cb), editor);
-
-	gl_debug (DEBUG_VIEW, "END");
-
-	return editor;
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE.  editor "changed" callback.                                      */
-/*---------------------------------------------------------------------------*/
-static void
-update_object_from_editor_cb (glObjectEditor *editor,
-			      glLabelObject  *object)
-{
-	gdouble            x, y, w, h;
-	glTextNode        *text_node;
-	gchar             *id;
-	gboolean           text_flag, cs_flag;
-	glColorNode       *color_node;
-	guint              format_digits;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_signal_handlers_block_by_func (G_OBJECT(object),
-					 update_editor_from_object_cb,
-					 editor);
-	g_signal_handlers_block_by_func (G_OBJECT(object),
-					 update_editor_from_move_cb,
-					 editor);
-
-
-	gl_object_editor_get_position (editor, &x, &y);
-	gl_label_object_set_position (object, x, y);
-
-	gl_object_editor_get_size (editor, &w, &h);
-	gl_label_object_set_size (object, w, h);
-
-	text_node = gl_object_editor_get_data (editor);
-	gl_label_barcode_set_data (GL_LABEL_BARCODE(object), text_node);
-	gl_text_node_free (&text_node);
-
-	gl_object_editor_get_bc_style (editor, &id, &text_flag, &cs_flag, &format_digits);
-	color_node = gl_object_editor_get_bc_color (editor);
-	gl_label_barcode_set_props (GL_LABEL_BARCODE(object),
-				    id, text_flag, cs_flag, format_digits);
-	gl_label_object_set_line_color (object, color_node);
-	gl_color_node_free (&color_node);
-	g_free (id);
-
-	g_signal_handlers_unblock_by_func (G_OBJECT(object),
-					   update_editor_from_object_cb,
-					   editor);
-	g_signal_handlers_unblock_by_func (G_OBJECT(object),
-					   update_editor_from_move_cb,
-					   editor);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE. label object "changed" callback.                                 */
-/*---------------------------------------------------------------------------*/
-static void
-update_editor_from_object_cb (glLabelObject  *object,
-			      glObjectEditor *editor)
-{
-	gdouble            w, h;
-	glTextNode        *text_node;
-	gchar             *id;
-	gboolean           text_flag, cs_flag;
-	glColorNode       *color_node;
-	glMerge           *merge;
-	guint              format_digits;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	gl_label_object_get_size (object, &w, &h);
-	gl_object_editor_set_size (editor, w, h);
-	
-	merge = gl_label_get_merge (GL_LABEL(object->parent));
-
-	gl_label_barcode_get_props (GL_LABEL_BARCODE(object),
-				    &id, &text_flag, &cs_flag, &format_digits);
-	color_node = gl_label_object_get_line_color (object);
-	gl_object_editor_set_bc_style (editor, id, text_flag, cs_flag, format_digits);
-	gl_object_editor_set_bc_color (editor, (merge != NULL), color_node);
-	gl_color_node_free (&color_node);
-	g_free (id);
-
-	text_node = gl_label_barcode_get_data (GL_LABEL_BARCODE(object));
-	gl_object_editor_set_data (editor, (merge != NULL), text_node);
-	gl_text_node_free (&text_node);
-
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE. label object "moved" callback.                                   */
-/*---------------------------------------------------------------------------*/
-static void
-update_editor_from_move_cb (glLabelObject    *object,
-			    gdouble           dx,
-			    gdouble           dy,
-			    glObjectEditor   *editor)
-{
-	gdouble            x, y;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	gl_label_object_get_position (object, &x, &y);
-	gl_object_editor_set_position (editor, x, y);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Is object at (x,y)?                                                       */
-/*****************************************************************************/
-static gboolean
-object_at (glViewObject  *view_object,
-           cairo_t       *cr,
-           gdouble        x,
-           gdouble        y)
-{
-	glLabelObject    *object;
-        gdouble           w, h;
-
-        object = gl_view_object_get_object (view_object);
-
-        gl_label_object_get_size (object, &w, &h);
-
-        cairo_rectangle (cr, 0.0, 0.0, w, h);
-
-        if (cairo_in_fill (cr, x, y))
-        {
-                return TRUE;
-        }
-
-        return FALSE;
-}
-
 
 /*****************************************************************************/
 /* Return apropos cursor for create object mode.                             */
@@ -379,21 +91,13 @@ gl_view_barcode_create_button_press_event   (glView *view,
 {
 	GObject             *object;
         glTextNode          *text_node;
-	glColorNode         *line_color_node;
 
-        gl_view_unselect_all (view);
+        gl_label_unselect_all (view->label);
 
-        line_color_node = gl_color_node_new_default ();
-		
         object = gl_label_barcode_new (view->label);
         gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
         text_node = gl_text_node_new_from_text ("123456789");
         gl_label_barcode_set_data (GL_LABEL_BARCODE(object), text_node);
-        line_color_node->color = gl_color_set_opacity (gl_view_get_default_line_color(view), 0.5);
-        gl_label_object_set_line_color (GL_LABEL_OBJECT(object),
-                                        line_color_node);
-
-        gl_color_node_free (&line_color_node);
 
         view->create_object = GL_LABEL_OBJECT (object);
         view->create_x0 = x;
@@ -421,14 +125,7 @@ gl_view_barcode_create_button_release_event (glView *view,
                                              gdouble x,
                                              gdouble y)
 {
-	glColorNode         *line_color_node;
-
-        line_color_node = gl_color_node_new_default ();
-		
         gl_label_object_set_position (GL_LABEL_OBJECT(view->create_object), x, y);
-        line_color_node->color = gl_view_get_default_line_color(view);
-        gl_label_object_set_line_color (GL_LABEL_OBJECT(view->create_object), line_color_node);
-        gl_color_node_free (&line_color_node);
 }
 
 
diff --git a/src/view-barcode.h b/src/view-barcode.h
index a2b52d0..ba99775 100644
--- a/src/view-barcode.h
+++ b/src/view-barcode.h
@@ -21,42 +21,14 @@
 #ifndef __VIEW_BARCODE_H__
 #define __VIEW_BARCODE_H__
 
-#include "view-object.h"
-#include "label-barcode.h"
+#include "view.h"
+#include <gdk/gdk.h>
 
 G_BEGIN_DECLS
 
 
-#define GL_TYPE_VIEW_BARCODE            (gl_view_barcode_get_type ())
-#define GL_VIEW_BARCODE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GL_TYPE_VIEW_BARCODE, glViewBarcode))
-#define GL_VIEW_BARCODE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GL_TYPE_VIEW_BARCODE, glViewBarcodeClass))
-#define GL_IS_VIEW_BARCODE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GL_TYPE_VIEW_BARCODE))
-#define GL_IS_VIEW_BARCODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GL_TYPE_VIEW_BARCODE))
-
-typedef struct _glViewBarcode          glViewBarcode;
-typedef struct _glViewBarcodeClass     glViewBarcodeClass;
-
-typedef struct _glViewBarcodePrivate   glViewBarcodePrivate;
-
-struct _glViewBarcode {
-	glViewObject              parent_object;
-
-	glViewBarcodePrivate     *priv;
-};
-
-struct _glViewBarcodeClass {
-	glViewObjectClass         parent_class;
-};
-
-
-GType          gl_view_barcode_get_type (void) G_GNUC_CONST;
-
-glViewObject  *gl_view_barcode_new      (glLabelBarcode *object,
-                                         glView         *view);
-
-
 /* cursor for creating barcode objects */
-GdkCursor *gl_view_barcode_get_create_cursor (void);
+GdkCursor *gl_view_barcode_get_create_cursor           (void);
 
 /* Object creation handlers. */
 void       gl_view_barcode_create_button_press_event   (glView *view,
diff --git a/src/view-box.c b/src/view-box.c
index bcb7693..2dd259d 100644
--- a/src/view-box.c
+++ b/src/view-box.c
@@ -22,12 +22,7 @@
 
 #include "view-box.h"
 
-#include <glib/gi18n.h>
-#include <glib.h>
-
-#include "color.h"
-#include "object-editor.h"
-#include "stock.h"
+#include "label-box.h"
 
 #include "pixmaps/cursor_box.xbm"
 #include "pixmaps/cursor_box_mask.xbm"
@@ -44,9 +39,6 @@
 /* Private types.                                         */
 /*========================================================*/
 
-struct _glViewBoxPrivate {
-};
-
 
 /*========================================================*/
 /* Private globals.                                       */
@@ -57,321 +49,6 @@ struct _glViewBoxPrivate {
 /* Private function prototypes.                           */
 /*========================================================*/
 
-static void       gl_view_box_finalize              (GObject          *object);
-
-static GtkWidget *construct_properties_editor       (glViewObject     *view_object);
-
-static void       update_object_from_editor_cb      (glObjectEditor   *editor,
-						     glLabelObject    *object);
-
-static void       update_editor_from_object_cb      (glLabelObject    *object,
-						     glObjectEditor   *editor);
-
-static void       update_editor_from_move_cb        (glLabelObject    *object,
-						     gdouble           dx,
-						     gdouble           dy,
-						     glObjectEditor   *editor);
-
-static gboolean   object_at                         (glViewObject     *view_object,
-                                                     cairo_t          *cr,
-                                                     gdouble           x,
-                                                     gdouble           y);
-
-
-/*****************************************************************************/
-/* Boilerplate object stuff.                                                 */
-/*****************************************************************************/
-G_DEFINE_TYPE (glViewBox, gl_view_box, GL_TYPE_VIEW_OBJECT);
-
-
-static void
-gl_view_box_class_init (glViewBoxClass *class)
-{
-	GObjectClass      *object_class      = G_OBJECT_CLASS (class);
-	glViewObjectClass *view_object_class = GL_VIEW_OBJECT_CLASS (class);
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	gl_view_box_parent_class = g_type_class_peek_parent (class);
-
-	object_class->finalize = gl_view_box_finalize;
-
-	view_object_class->construct_editor = construct_properties_editor;
-	view_object_class->object_at        = object_at;
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-static void
-gl_view_box_init (glViewBox *view_box)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	view_box->priv = g_new0 (glViewBoxPrivate, 1);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-static void
-gl_view_box_finalize (GObject *object)
-{
-        glViewBox *view_box = GL_VIEW_BOX (object);
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (object && GL_IS_VIEW_BOX (object));
-
-        g_free (view_box->priv);
-
-	G_OBJECT_CLASS (gl_view_box_parent_class)->finalize (object);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* NEW box object view.                                                      */
-/*****************************************************************************/
-glViewObject *
-gl_view_box_new (glLabelBox *object,
-		 glView     *view)
-{
-	glViewBox         *view_box;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_val_if_fail (object && GL_IS_LABEL_BOX (object), NULL);
-	g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
-	
-	view_box = g_object_new (gl_view_box_get_type(), NULL);
-
-	gl_view_object_set_object (GL_VIEW_OBJECT(view_box),
-				   GL_LABEL_OBJECT(object),
-				   GL_VIEW_OBJECT_HANDLES_BOX);
-	gl_view_object_set_view (GL_VIEW_OBJECT(view_box), view);
-
-	gl_debug (DEBUG_VIEW, "END");
-
-	return GL_VIEW_OBJECT (view_box);
-}
-
-
-/*****************************************************************************/
-/* Create a properties dialog for a box object.                              */
-/*****************************************************************************/
-static GtkWidget *
-construct_properties_editor (glViewObject *view_object)
-{
-	GtkWidget          *editor;
-	glViewBox          *view_box = (glViewBox *)view_object;
-	glLabelObject      *object;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	object = gl_view_object_get_object (GL_VIEW_OBJECT(view_box));
-
-	/* Build editor. */
-	editor = gl_object_editor_new (GL_STOCK_BOX, _("Box object properties"),
-                                       object->parent,
-				       GL_OBJECT_EDITOR_SHADOW_PAGE,
-				       GL_OBJECT_EDITOR_POSITION_PAGE,
-				       GL_OBJECT_EDITOR_SIZE_PAGE,
-				       GL_OBJECT_EDITOR_FILL_PAGE,
-				       GL_OBJECT_EDITOR_LINE_PAGE,
-				       0);
-	
-	/* Update */
-	update_editor_from_object_cb (object, GL_OBJECT_EDITOR(editor));
-	update_editor_from_move_cb (object, 0, 0, GL_OBJECT_EDITOR(editor));
-
-	/* Connect signals. */
-	g_signal_connect (G_OBJECT (editor), "changed",
-			  G_CALLBACK(update_object_from_editor_cb), object);
-	g_signal_connect (G_OBJECT (object), "changed",
-			  G_CALLBACK (update_editor_from_object_cb), editor);
-	g_signal_connect (G_OBJECT (object), "moved",
-			  G_CALLBACK (update_editor_from_move_cb), editor);
-
-	gl_debug (DEBUG_VIEW, "END");
-
-	return editor;
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE.  editor "changed" callback.                                      */
-/*---------------------------------------------------------------------------*/
-static void
-update_object_from_editor_cb (glObjectEditor *editor,
-			      glLabelObject  *object)
-{
-	gdouble            x, y, w, h;
-	glColorNode       *line_color_node;
-	gdouble            line_width;
-	glColorNode	  *fill_color_node;
-	gboolean           shadow_state;
-	gdouble            shadow_x, shadow_y;
-	glColorNode	  *shadow_color_node;
-	gdouble            shadow_opacity;
-	
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_signal_handlers_block_by_func (G_OBJECT(object),
-					 update_editor_from_object_cb,
-					 editor);
-	g_signal_handlers_block_by_func (G_OBJECT(object),
-					 update_editor_from_move_cb,
-					 editor);
-
-	gl_object_editor_get_position (editor, &x, &y);
-	gl_label_object_set_position (object, x, y);
-
-	gl_object_editor_get_size (editor, &w, &h);
-	gl_label_object_set_size (object, w, h);
-
-	fill_color_node = gl_object_editor_get_fill_color (editor);
-	gl_label_object_set_fill_color (object, fill_color_node);
-	gl_color_node_free (&fill_color_node);
-
-	line_color_node = gl_object_editor_get_line_color (editor);
-	gl_label_object_set_line_color (object, line_color_node);
-	gl_color_node_free (&line_color_node);
-
-	line_width = gl_object_editor_get_line_width (editor);
-	gl_label_object_set_line_width (object, line_width);
-
-	shadow_state = gl_object_editor_get_shadow_state (editor);
-	gl_label_object_set_shadow_state (object, shadow_state);
-
-	gl_object_editor_get_shadow_offset (editor, &shadow_x, &shadow_y);
-	gl_label_object_set_shadow_offset (object, shadow_x, shadow_y);
-
-	shadow_color_node = gl_object_editor_get_shadow_color (editor);
-	gl_label_object_set_shadow_color (object, shadow_color_node);
-	gl_color_node_free (&shadow_color_node);
-
-	shadow_opacity = gl_object_editor_get_shadow_opacity (editor);
-	gl_label_object_set_shadow_opacity (object, shadow_opacity);
-
-	g_signal_handlers_unblock_by_func (G_OBJECT(object),
-					   update_editor_from_object_cb,
-					   editor);
-	g_signal_handlers_unblock_by_func (G_OBJECT(object),
-					   update_editor_from_move_cb,
-					   editor);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE. label object "changed" callback.                                 */
-/*---------------------------------------------------------------------------*/
-static void
-update_editor_from_object_cb (glLabelObject  *object,
-			      glObjectEditor *editor)
-{
-	gdouble            w, h;
-	glColorNode       *line_color_node;
-	gdouble            line_width;
-	glColorNode       *fill_color_node;
-	gboolean           shadow_state;
-	gdouble            shadow_x, shadow_y;
-	glColorNode	  *shadow_color_node;
-	gdouble            shadow_opacity;
-	glMerge	          *merge;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	gl_label_object_get_size (object, &w, &h);
-	gl_object_editor_set_size (editor, w, h);
-	merge = gl_label_get_merge (GL_LABEL(object->parent));
-	
-	fill_color_node = gl_label_object_get_fill_color (GL_LABEL_OBJECT(object));
-	gl_object_editor_set_fill_color (editor, (merge != NULL), fill_color_node);
-	gl_color_node_free (&fill_color_node);
-
-	line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
-	gl_object_editor_set_line_color (editor, (merge != NULL), line_color_node);
-	gl_color_node_free (&line_color_node);
-
-	line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
-	gl_object_editor_set_line_width (editor, line_width);
-
-	shadow_state = gl_label_object_get_shadow_state (object);
-	gl_object_editor_set_shadow_state (editor, shadow_state);
-
-	gl_label_object_get_shadow_offset (object, &shadow_x, &shadow_y);
-	gl_object_editor_set_shadow_offset (editor, shadow_x, shadow_y);
-
-	shadow_color_node = gl_label_object_get_shadow_color (object);
-	gl_object_editor_set_shadow_color (editor, (merge != NULL), shadow_color_node);
-	gl_color_node_free (&shadow_color_node);
-
-	shadow_opacity = gl_label_object_get_shadow_opacity (object);
-	gl_object_editor_set_shadow_opacity (editor, shadow_opacity);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE. label object "moved" callback.                                   */
-/*---------------------------------------------------------------------------*/
-static void
-update_editor_from_move_cb (glLabelObject    *object,
-			    gdouble           dx,
-			    gdouble           dy,
-			    glObjectEditor   *editor)
-{
-	gdouble            x, y;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	gl_label_object_get_position (object, &x, &y);
-	gl_object_editor_set_position (editor, x, y);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Is object at (x,y)?                                                       */
-/*****************************************************************************/
-static gboolean
-object_at (glViewObject  *view_object,
-           cairo_t       *cr,
-           gdouble        x,
-           gdouble        y)
-{
-	glLabelObject    *object;
-        gdouble           w, h;
-        gdouble           line_width;
-
-        object = gl_view_object_get_object (view_object);
-
-        gl_label_object_get_size (object, &w, &h);
-
-        cairo_rectangle (cr, 0.0, 0.0, w, h);
-
-        if (cairo_in_fill (cr, x, y))
-        {
-                return TRUE;
-        }
-
-        line_width = gl_label_object_get_line_width (object);
-        cairo_set_line_width (cr, line_width);
-        if (cairo_in_stroke (cr, x, y))
-        {
-                return TRUE;
-        }
-
-        return FALSE;
-}
-
 
 /*****************************************************************************/
 /* Return apropos cursor for create object mode.                             */
@@ -413,28 +90,12 @@ gl_view_box_create_button_press_event   (glView *view,
                                          gdouble y)
 {
 	GObject             *object;
-	glColorNode         *fill_color_node;
-	glColorNode         *line_color_node;
 
-        gl_view_unselect_all (view);
+        gl_label_unselect_all (view->label);
 
-        fill_color_node = gl_color_node_new_default ();
-        line_color_node = gl_color_node_new_default ();
-		
         object = gl_label_box_new (view->label);
         gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
         gl_label_object_set_size (GL_LABEL_OBJECT(object), 0.0, 0.0);
-        line_color_node->color = gl_color_set_opacity (gl_view_get_default_line_color(view), 0.5);
-        fill_color_node->color = gl_color_set_opacity (gl_view_get_default_fill_color(view), 0.5);
-        gl_label_object_set_line_width (GL_LABEL_OBJECT(object),
-                                        gl_view_get_default_line_width(view));
-        gl_label_object_set_line_color (GL_LABEL_OBJECT(object),
-                                        line_color_node);
-        gl_label_object_set_fill_color (GL_LABEL_OBJECT(object),
-                                        fill_color_node);
-
-        gl_color_node_free (&fill_color_node);
-        gl_color_node_free (&line_color_node);
 			
         view->create_object = GL_LABEL_OBJECT (object);
         view->create_x0 = x;
@@ -468,13 +129,8 @@ gl_view_box_create_button_release_event (glView *view,
                                          gdouble x,
                                          gdouble y)
 {
-	glColorNode         *fill_color_node;
-	glColorNode         *line_color_node;
         gdouble              w, h;
 
-        fill_color_node = gl_color_node_new_default ();
-        line_color_node = gl_color_node_new_default ();
-		
         if ((view->create_x0 == x) && (view->create_y0 == y)) {
                 x = view->create_x0 + 36.0;
                 y = view->create_y0 + 36.0;
@@ -484,12 +140,6 @@ gl_view_box_create_button_release_event (glView *view,
         w = MAX (x, view->create_x0) - MIN (x, view->create_x0);
         h = MAX (y, view->create_y0) - MIN (y, view->create_y0);
         gl_label_object_set_size (GL_LABEL_OBJECT(view->create_object), w, h);
-        line_color_node->color = gl_view_get_default_line_color(view);
-        gl_label_object_set_line_color (GL_LABEL_OBJECT(view->create_object), line_color_node);
-        fill_color_node->color = gl_view_get_default_fill_color(view);
-        gl_label_object_set_fill_color (GL_LABEL_OBJECT(view->create_object), fill_color_node);
-        gl_color_node_free (&fill_color_node);
-        gl_color_node_free (&line_color_node);
 }
 
 
diff --git a/src/view-box.h b/src/view-box.h
index 930ae1e..35c7e6b 100644
--- a/src/view-box.h
+++ b/src/view-box.h
@@ -21,42 +21,15 @@
 #ifndef __VIEW_BOX_H__
 #define __VIEW_BOX_H__
 
-#include "view-object.h"
-#include "label-box.h"
 
-G_BEGIN_DECLS
-
-
-#define GL_TYPE_VIEW_BOX            (gl_view_box_get_type ())
-#define GL_VIEW_BOX(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GL_TYPE_VIEW_BOX, glViewBox))
-#define GL_VIEW_BOX_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GL_TYPE_VIEW_BOX, glViewBoxClass))
-#define GL_IS_VIEW_BOX(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GL_TYPE_VIEW_BOX))
-#define GL_IS_VIEW_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GL_TYPE_VIEW_BOX))
-
-typedef struct _glViewBox          glViewBox;
-typedef struct _glViewBoxClass     glViewBoxClass;
-
-typedef struct _glViewBoxPrivate   glViewBoxPrivate;
-
-struct _glViewBox {
-	glViewObject          parent_object;
+#include "view.h"
+#include <gdk/gdk.h>
 
-	glViewBoxPrivate     *priv;
-};
-
-struct _glViewBoxClass {
-	glViewObjectClass     parent_class;
-};
-
-
-GType          gl_view_box_get_type (void) G_GNUC_CONST;
-
-glViewObject  *gl_view_box_new      (glLabelBox *object,
-				     glView     *view);
+G_BEGIN_DECLS
 
 
 /* cursor for creating box objects */
-GdkCursor *gl_view_box_get_create_cursor (void);
+GdkCursor *gl_view_box_get_create_cursor           (void);
 
 /* Object creation handlers. */
 void       gl_view_box_create_button_press_event   (glView *view,
diff --git a/src/view-ellipse.c b/src/view-ellipse.c
index a5069b2..7d286c2 100644
--- a/src/view-ellipse.c
+++ b/src/view-ellipse.c
@@ -22,14 +22,7 @@
 
 #include "view-ellipse.h"
 
-#include <glib/gi18n.h>
-#include <glib.h>
-#include <math.h>
-
-#include "cairo-ellipse-path.h"
-#include "color.h"
-#include "object-editor.h"
-#include "stock.h"
+#include "label-ellipse.h"
 
 #include "pixmaps/cursor_ellipse.xbm"
 #include "pixmaps/cursor_ellipse_mask.xbm"
@@ -46,9 +39,6 @@
 /* Private types.                                         */
 /*========================================================*/
 
-struct _glViewEllipsePrivate {
-};
-
 
 /*========================================================*/
 /* Private globals.                                       */
@@ -59,321 +49,6 @@ struct _glViewEllipsePrivate {
 /* Private function prototypes.                           */
 /*========================================================*/
 
-static void       gl_view_ellipse_finalize          (GObject          *object);
-
-static GtkWidget *construct_properties_editor       (glViewObject     *view_object);
-
-static void       update_object_from_editor_cb      (glObjectEditor   *editor,
-						     glLabelObject    *object);
-
-static void       update_editor_from_object_cb      (glLabelObject    *object,
-						     glObjectEditor   *editor);
-
-static void       update_editor_from_move_cb        (glLabelObject    *object,
-						     gdouble           dx,
-						     gdouble           dy,
-						     glObjectEditor   *editor);
-
-static gboolean   object_at                         (glViewObject     *view_object,
-                                                     cairo_t          *cr,
-                                                     gdouble           x,
-                                                     gdouble           y);
-
-
-/*****************************************************************************/
-/* Boilerplate object stuff.                                                 */
-/*****************************************************************************/
-G_DEFINE_TYPE (glViewEllipse, gl_view_ellipse, GL_TYPE_VIEW_OBJECT);
-
-
-static void
-gl_view_ellipse_class_init (glViewEllipseClass *class)
-{
-	GObjectClass      *object_class      = G_OBJECT_CLASS (class);
-	glViewObjectClass *view_object_class = GL_VIEW_OBJECT_CLASS (class);
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	gl_view_ellipse_parent_class = g_type_class_peek_parent (class);
-
-	object_class->finalize = gl_view_ellipse_finalize;
-
-	view_object_class->construct_editor = construct_properties_editor;
-	view_object_class->object_at        = object_at;
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-static void
-gl_view_ellipse_init (glViewEllipse *view_ellipse)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	view_ellipse->priv = g_new0 (glViewEllipsePrivate, 1);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-static void
-gl_view_ellipse_finalize (GObject *object)
-{
-        glViewEllipse *view_ellipse = GL_VIEW_ELLIPSE (object);
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (object && GL_IS_VIEW_ELLIPSE (object));
-
-        g_free (view_ellipse->priv);
-
-	G_OBJECT_CLASS (gl_view_ellipse_parent_class)->finalize (object);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* NEW ellipse object view.                                                  */
-/*****************************************************************************/
-glViewObject *
-gl_view_ellipse_new (glLabelEllipse *object,
-                     glView         *view)
-{
-	glViewEllipse         *view_ellipse;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_val_if_fail (object && GL_IS_LABEL_ELLIPSE (object), NULL);
-	g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
-	
-	view_ellipse = g_object_new (gl_view_ellipse_get_type(), NULL);
-
-	gl_view_object_set_object (GL_VIEW_OBJECT(view_ellipse),
-				   GL_LABEL_OBJECT(object),
-				   GL_VIEW_OBJECT_HANDLES_BOX);
-	gl_view_object_set_view (GL_VIEW_OBJECT(view_ellipse), view);
-
-	gl_debug (DEBUG_VIEW, "END");
-
-	return GL_VIEW_OBJECT (view_ellipse);
-}
-
-
-/*****************************************************************************/
-/* Create a properties dialog for a ellipse object.                          */
-/*****************************************************************************/
-static GtkWidget *
-construct_properties_editor (glViewObject *view_object)
-{
-	GtkWidget          *editor;
-	glViewEllipse      *view_ellipse = (glViewEllipse *)view_object;
-	glLabelObject      *object;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	object = gl_view_object_get_object (GL_VIEW_OBJECT(view_ellipse));
-
-	/* Build editor. */
-	editor = gl_object_editor_new (GL_STOCK_ELLIPSE, _("Ellipse object properties"),
-                                       object->parent,
-				       GL_OBJECT_EDITOR_SHADOW_PAGE,
-				       GL_OBJECT_EDITOR_POSITION_PAGE,
-				       GL_OBJECT_EDITOR_SIZE_PAGE,
-				       GL_OBJECT_EDITOR_FILL_PAGE,
-				       GL_OBJECT_EDITOR_LINE_PAGE,
-				       0);
-	
-	/* Update */
-	update_editor_from_object_cb (object, GL_OBJECT_EDITOR(editor));
-	update_editor_from_move_cb (object, 0, 0, GL_OBJECT_EDITOR(editor));
-
-	/* Connect signals. */
-	g_signal_connect (G_OBJECT (editor), "changed",
-			  G_CALLBACK(update_object_from_editor_cb), object);
-	g_signal_connect (G_OBJECT (object), "changed",
-			  G_CALLBACK (update_editor_from_object_cb), editor);
-	g_signal_connect (G_OBJECT (object), "moved",
-			  G_CALLBACK (update_editor_from_move_cb), editor);
-
-	gl_debug (DEBUG_VIEW, "END");
-
-	return editor;
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE.  editor "changed" callback.                                      */
-/*---------------------------------------------------------------------------*/
-static void
-update_object_from_editor_cb (glObjectEditor *editor,
-			      glLabelObject  *object)
-{
-	gdouble            x, y, w, h;
-	glColorNode       *line_color_node;
-	gdouble            line_width;
-	glColorNode	  *fill_color_node;
-	gboolean           shadow_state;
-	gdouble            shadow_x, shadow_y;
-	glColorNode	  *shadow_color_node;
-	gdouble            shadow_opacity;
-	
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_signal_handlers_block_by_func (G_OBJECT(object),
-					 update_editor_from_object_cb,
-					 editor);
-	g_signal_handlers_block_by_func (G_OBJECT(object),
-					 update_editor_from_move_cb,
-					 editor);
-
-	gl_object_editor_get_position (editor, &x, &y);
-	gl_label_object_set_position (object, x, y);
-
-	gl_object_editor_get_size (editor, &w, &h);
-	gl_label_object_set_size (object, w, h);
-
-	fill_color_node = gl_object_editor_get_fill_color (editor);
-	gl_label_object_set_fill_color (object, fill_color_node);
-	gl_color_node_free (&fill_color_node);
-
-	line_color_node = gl_object_editor_get_line_color (editor);
-	gl_label_object_set_line_color (object, line_color_node);
-	gl_color_node_free (&line_color_node);
-
-	line_width = gl_object_editor_get_line_width (editor);
-	gl_label_object_set_line_width (object, line_width);
-
-	shadow_state = gl_object_editor_get_shadow_state (editor);
-	gl_label_object_set_shadow_state (object, shadow_state);
-
-	gl_object_editor_get_shadow_offset (editor, &shadow_x, &shadow_y);
-	gl_label_object_set_shadow_offset (object, shadow_x, shadow_y);
-
-	shadow_color_node = gl_object_editor_get_shadow_color (editor);
-	gl_label_object_set_shadow_color (object, shadow_color_node);
-	gl_color_node_free (&shadow_color_node);
-
-	shadow_opacity = gl_object_editor_get_shadow_opacity (editor);
-	gl_label_object_set_shadow_opacity (object, shadow_opacity);
-
-	g_signal_handlers_unblock_by_func (G_OBJECT(object),
-					   update_editor_from_object_cb,
-					   editor);
-	g_signal_handlers_unblock_by_func (G_OBJECT(object),
-					   update_editor_from_move_cb,
-					   editor);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE. label object "changed" callback.                                 */
-/*---------------------------------------------------------------------------*/
-static void
-update_editor_from_object_cb (glLabelObject  *object,
-			      glObjectEditor *editor)
-{
-	gdouble            w, h;
-	glColorNode       *line_color_node;
-	gdouble            line_width;
-	glColorNode       *fill_color_node;
-	gboolean           shadow_state;
-	gdouble            shadow_x, shadow_y;
-	glColorNode	  *shadow_color_node;
-	gdouble            shadow_opacity;
-	glMerge	          *merge;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	gl_label_object_get_size (object, &w, &h);
-	gl_object_editor_set_size (editor, w, h);
-	merge = gl_label_get_merge (GL_LABEL(object->parent));
-	
-	fill_color_node = gl_label_object_get_fill_color (GL_LABEL_OBJECT(object));
-	gl_object_editor_set_fill_color (editor, (merge != NULL), fill_color_node);
-	gl_color_node_free (&fill_color_node);
-
-	line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
-	gl_object_editor_set_line_color (editor, (merge != NULL), line_color_node);
-	gl_color_node_free (&line_color_node);
-
-	line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
-	gl_object_editor_set_line_width (editor, line_width);
-
-	shadow_state = gl_label_object_get_shadow_state (object);
-	gl_object_editor_set_shadow_state (editor, shadow_state);
-
-	gl_label_object_get_shadow_offset (object, &shadow_x, &shadow_y);
-	gl_object_editor_set_shadow_offset (editor, shadow_x, shadow_y);
-
-	shadow_color_node = gl_label_object_get_shadow_color (object);
-	gl_object_editor_set_shadow_color (editor, (merge != NULL), shadow_color_node);
-	gl_color_node_free (&shadow_color_node);
-
-	shadow_opacity = gl_label_object_get_shadow_opacity (object);
-	gl_object_editor_set_shadow_opacity (editor, shadow_opacity);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE. label object "moved" callback.                                   */
-/*---------------------------------------------------------------------------*/
-static void
-update_editor_from_move_cb (glLabelObject    *object,
-			    gdouble           dx,
-			    gdouble           dy,
-			    glObjectEditor   *editor)
-{
-	gdouble            x, y;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	gl_label_object_get_position (object, &x, &y);
-	gl_object_editor_set_position (editor, x, y);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Is object at (x,y)?                                                       */
-/*****************************************************************************/
-static gboolean
-object_at (glViewObject  *view_object,
-           cairo_t       *cr,
-           gdouble        x,
-           gdouble        y)
-{
-	glLabelObject    *object;
-        gdouble           w, h;
-        gdouble           line_width;
-
-        object = gl_view_object_get_object (view_object);
-
-        gl_label_object_get_size (object, &w, &h);
-
-        gl_cairo_ellipse_path (cr, w/2, h/2);
-
-        if (cairo_in_fill (cr, x, y))
-        {
-                return TRUE;
-        }
-
-        line_width = gl_label_object_get_line_width (object);
-        cairo_set_line_width (cr, line_width);
-        if (cairo_in_stroke (cr, x, y))
-        {
-                return TRUE;
-        }
-
-        return FALSE;
-}
-
 
 /*****************************************************************************/
 /* Return apropos cursor for create object mode.                             */
@@ -415,28 +90,12 @@ gl_view_ellipse_create_button_press_event   (glView *view,
                                              gdouble y)
 {
 	GObject             *object;
-	glColorNode         *fill_color_node;
-	glColorNode         *line_color_node;
 
-        gl_view_unselect_all (view);
+        gl_label_unselect_all (view->label);
 
-        fill_color_node = gl_color_node_new_default ();
-        line_color_node = gl_color_node_new_default ();
-		
         object = gl_label_ellipse_new (view->label);
         gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
         gl_label_object_set_size (GL_LABEL_OBJECT(object), 0.0, 0.0);
-        line_color_node->color = gl_color_set_opacity (gl_view_get_default_line_color(view), 0.5);
-        fill_color_node->color = gl_color_set_opacity (gl_view_get_default_fill_color(view), 0.5);
-        gl_label_object_set_line_width (GL_LABEL_OBJECT(object),
-                                        gl_view_get_default_line_width(view));
-        gl_label_object_set_line_color (GL_LABEL_OBJECT(object),
-                                        line_color_node);
-        gl_label_object_set_fill_color (GL_LABEL_OBJECT(object),
-                                        fill_color_node);
-
-        gl_color_node_free (&fill_color_node);
-        gl_color_node_free (&line_color_node);
 
         view->create_object = GL_LABEL_OBJECT (object);
         view->create_x0 = x;
@@ -470,13 +129,8 @@ gl_view_ellipse_create_button_release_event (glView *view,
                                              gdouble x,
                                              gdouble y)
 {
-	glColorNode         *fill_color_node;
-	glColorNode         *line_color_node;
         gdouble              w, h;
 
-        fill_color_node = gl_color_node_new_default ();
-        line_color_node = gl_color_node_new_default ();
-		
         if ((view->create_x0 == x) && (view->create_y0 == y)) {
                 x = view->create_x0 + 36.0;
                 y = view->create_y0 + 36.0;
@@ -486,12 +140,6 @@ gl_view_ellipse_create_button_release_event (glView *view,
         w = MAX (x, view->create_x0) - MIN (x, view->create_x0);
         h = MAX (y, view->create_y0) - MIN (y, view->create_y0);
         gl_label_object_set_size (GL_LABEL_OBJECT(view->create_object), w, h);
-        line_color_node->color = gl_view_get_default_line_color(view);
-        gl_label_object_set_line_color (GL_LABEL_OBJECT(view->create_object), line_color_node);
-        fill_color_node->color = gl_view_get_default_fill_color(view);
-        gl_label_object_set_fill_color (GL_LABEL_OBJECT(view->create_object), fill_color_node);
-        gl_color_node_free (&fill_color_node);
-        gl_color_node_free (&line_color_node);
 }
 
 
diff --git a/src/view-ellipse.h b/src/view-ellipse.h
index a73c899..5ad66b0 100644
--- a/src/view-ellipse.h
+++ b/src/view-ellipse.h
@@ -21,42 +21,14 @@
 #ifndef __VIEW_ELLIPSE_H__
 #define __VIEW_ELLIPSE_H__
 
-#include "view-object.h"
-#include "label-ellipse.h"
+#include "view.h"
+#include <gdk/gdk.h>
 
 G_BEGIN_DECLS
 
 
-#define GL_TYPE_VIEW_ELLIPSE            (gl_view_ellipse_get_type ())
-#define GL_VIEW_ELLIPSE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GL_TYPE_VIEW_ELLIPSE, glViewEllipse))
-#define GL_VIEW_ELLIPSE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GL_TYPE_VIEW_ELLIPSE, glViewEllipseClass))
-#define GL_IS_VIEW_ELLIPSE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GL_TYPE_VIEW_ELLIPSE))
-#define GL_IS_VIEW_ELLIPSE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GL_TYPE_VIEW_ELLIPSE))
-
-typedef struct _glViewEllipse          glViewEllipse;
-typedef struct _glViewEllipseClass     glViewEllipseClass;
-
-typedef struct _glViewEllipsePrivate   glViewEllipsePrivate;
-
-struct _glViewEllipse {
-	glViewObject          parent_object;
-
-	glViewEllipsePrivate *priv;
-};
-
-struct _glViewEllipseClass {
-	glViewObjectClass     parent_class;
-};
-
-
-GType          gl_view_ellipse_get_type (void) G_GNUC_CONST;
-
-glViewObject  *gl_view_ellipse_new      (glLabelEllipse *object,
-                                         glView     *view);
-
-
 /* cursor for creating ellipse objects */
-GdkCursor *gl_view_ellipse_get_create_cursor (void);
+GdkCursor *gl_view_ellipse_get_create_cursor           (void);
 
 /* Object creation handlers. */
 void       gl_view_ellipse_create_button_press_event   (glView *view,
diff --git a/src/view-image.c b/src/view-image.c
index 5b76460..c0c5684 100644
--- a/src/view-image.c
+++ b/src/view-image.c
@@ -22,12 +22,7 @@
 
 #include "view-image.h"
 
-#include <glib/gi18n.h>
-#include <glib.h>
-
-#include "color.h"
-#include "object-editor.h"
-#include "stock.h"
+#include "label-image.h"
 
 #include "pixmaps/cursor_image.xbm"
 #include "pixmaps/cursor_image_mask.xbm"
@@ -44,9 +39,6 @@
 /* Private types.                                         */
 /*========================================================*/
 
-struct _glViewImagePrivate {
-};
-
 
 /*========================================================*/
 /* Private globals.                                       */
@@ -57,284 +49,6 @@ struct _glViewImagePrivate {
 /* Private function prototypes.                           */
 /*========================================================*/
 
-static void       gl_view_image_finalize            (GObject          *object);
-
-static GtkWidget *construct_properties_editor       (glViewObject     *view_object);
-
-static void       update_object_from_editor_cb      (glObjectEditor   *editor,
-						     glLabelObject    *object);
-
-static void       update_editor_from_object_cb      (glLabelObject    *object,
-						     glObjectEditor   *editor);
-
-static void       update_editor_from_move_cb        (glLabelObject    *object,
-						     gdouble           dx,
-						     gdouble           dy,
-						     glObjectEditor   *editor);
-
-static gboolean   object_at                         (glViewObject     *view_object,
-                                                     cairo_t          *cr,
-                                                     gdouble           x,
-                                                     gdouble           y);
-
-
-/*****************************************************************************/
-/* Boilerplate object stuff.                                                 */
-/*****************************************************************************/
-G_DEFINE_TYPE (glViewImage, gl_view_image, GL_TYPE_VIEW_OBJECT);
-
-
-static void
-gl_view_image_class_init (glViewImageClass *class)
-{
-	GObjectClass      *object_class      = G_OBJECT_CLASS (class);
-	glViewObjectClass *view_object_class = GL_VIEW_OBJECT_CLASS (class);
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	gl_view_image_parent_class = g_type_class_peek_parent (class);
-
-	object_class->finalize = gl_view_image_finalize;
-
-	view_object_class->construct_editor = construct_properties_editor;
-	view_object_class->object_at        = object_at;
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-static void
-gl_view_image_init (glViewImage *view_image)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	view_image->priv = g_new0 (glViewImagePrivate, 1);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-static void
-gl_view_image_finalize (GObject *object)
-{
-        glViewImage *view_image = GL_VIEW_IMAGE (object);
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (object && GL_IS_VIEW_IMAGE (object));
-
-        g_free (view_image->priv);
-
-	G_OBJECT_CLASS (gl_view_image_parent_class)->finalize (object);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* NEW image object view.                                                    */
-/*****************************************************************************/
-glViewObject *
-gl_view_image_new (glLabelImage *object,
-                   glView       *view)
-{
-	glViewImage         *view_image;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_val_if_fail (object && GL_IS_LABEL_IMAGE (object), NULL);
-	g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
-	
-	view_image = g_object_new (gl_view_image_get_type(), NULL);
-
-	gl_view_object_set_object (GL_VIEW_OBJECT(view_image),
-				   GL_LABEL_OBJECT(object),
-				   GL_VIEW_OBJECT_HANDLES_BOX);
-	gl_view_object_set_view (GL_VIEW_OBJECT(view_image), view);
-
-	gl_debug (DEBUG_VIEW, "END");
-
-	return GL_VIEW_OBJECT (view_image);
-}
-
-
-/*****************************************************************************/
-/* Create a properties dialog for a image object.                            */
-/*****************************************************************************/
-static GtkWidget *
-construct_properties_editor (glViewObject *view_object)
-{
-	GtkWidget          *editor;
-	glViewImage        *view_image = (glViewImage *)view_object;
-	glLabelObject      *object;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	object = gl_view_object_get_object (GL_VIEW_OBJECT(view_image));
-
-	/* Build editor. */
-	editor = gl_object_editor_new (GL_STOCK_IMAGE, _("Image object properties"),
-                                       object->parent,
-				       GL_OBJECT_EDITOR_POSITION_PAGE,
-				       GL_OBJECT_EDITOR_SIZE_IMAGE_PAGE,
-				       GL_OBJECT_EDITOR_IMAGE_PAGE,
-				       0);
-	
-	/* Update */
-	update_editor_from_object_cb (object, GL_OBJECT_EDITOR(editor));
-	update_editor_from_move_cb (object, 0, 0, GL_OBJECT_EDITOR(editor));
-
-	/* Connect signals. */
-	g_signal_connect (G_OBJECT (editor), "changed",
-			  G_CALLBACK(update_object_from_editor_cb), object);
-	g_signal_connect (G_OBJECT (object), "changed",
-			  G_CALLBACK (update_editor_from_object_cb), editor);
-	g_signal_connect (G_OBJECT (object), "moved",
-			  G_CALLBACK (update_editor_from_move_cb), editor);
-
-	gl_debug (DEBUG_VIEW, "END");
-
-	return editor;
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE.  editor "changed" callback.                                      */
-/*---------------------------------------------------------------------------*/
-static void
-update_object_from_editor_cb (glObjectEditor *editor,
-			      glLabelObject  *object)
-{
-	gdouble            x, y, w, h;
-	glTextNode        *filename;
-	const GdkPixbuf   *pixbuf;
-	gdouble            image_w, image_h;
-	gdouble            new_w, new_h;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_signal_handlers_block_by_func (G_OBJECT(object),
-					 update_editor_from_object_cb,
-					 editor);
-	g_signal_handlers_block_by_func (G_OBJECT(object),
-					 update_editor_from_move_cb,
-					 editor);
-
-
-	gl_object_editor_get_position (editor, &x, &y);
-	gl_label_object_set_position (object, x, y);
-
-	gl_object_editor_get_size (editor, &w, &h);
-	gl_label_object_set_size (object, w, h);
-
-	filename = gl_object_editor_get_image (editor);
-	gl_label_image_set_filename (GL_LABEL_IMAGE(object), filename);
-	gl_text_node_free (&filename);
-
-	/* Setting filename may have modified the size. */
-	gl_label_object_get_size (object, &new_w, &new_h);
-        if ( (new_w != w) || (new_h != h) )
-        {
-                gl_object_editor_set_size (editor, new_w, new_h);
-        }
-
-	/* It may also have a new base size. */
-        pixbuf = gl_label_image_get_pixbuf (GL_LABEL_IMAGE(object), NULL);
-        image_w = gdk_pixbuf_get_width (pixbuf);
-        image_h = gdk_pixbuf_get_height (pixbuf);
-	gl_object_editor_set_base_size (editor, image_w, image_h);
-
-	g_signal_handlers_unblock_by_func (G_OBJECT(object),
-					   update_editor_from_object_cb,
-					   editor);
-	g_signal_handlers_unblock_by_func (G_OBJECT(object),
-					   update_editor_from_move_cb,
-					   editor);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE. label object "changed" callback.                                 */
-/*---------------------------------------------------------------------------*/
-static void
-update_editor_from_object_cb (glLabelObject  *object,
-			      glObjectEditor *editor)
-{
-	gdouble            w, h;
-	const GdkPixbuf   *pixbuf;
-	gdouble            image_w, image_h;
-	glTextNode        *filename;
-	glMerge           *merge;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	gl_label_object_get_size (object, &w, &h);
-	gl_object_editor_set_size (editor, w, h);
-
-        pixbuf = gl_label_image_get_pixbuf (GL_LABEL_IMAGE(object), NULL);
-        image_w = gdk_pixbuf_get_width (pixbuf);
-        image_h = gdk_pixbuf_get_height (pixbuf);
-	gl_object_editor_set_base_size (editor, image_w, image_h);
-
-	filename = gl_label_image_get_filename (GL_LABEL_IMAGE(object));
-	merge = gl_label_get_merge (GL_LABEL(object->parent));
-	if ( filename != NULL ) {
-		gl_object_editor_set_image (editor, (merge != NULL), filename);
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE. label object "moved" callback.                                   */
-/*---------------------------------------------------------------------------*/
-static void
-update_editor_from_move_cb (glLabelObject    *object,
-			    gdouble           dx,
-			    gdouble           dy,
-			    glObjectEditor   *editor)
-{
-	gdouble            x, y;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	gl_label_object_get_position (object, &x, &y);
-	gl_object_editor_set_position (editor, x, y);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Is object at (x,y)?                                                       */
-/*****************************************************************************/
-static gboolean
-object_at (glViewObject  *view_object,
-           cairo_t       *cr,
-           gdouble        x,
-           gdouble        y)
-{
-	glLabelObject    *object;
-        gdouble           w, h;
-
-        object = gl_view_object_get_object (view_object);
-
-        gl_label_object_get_size (object, &w, &h);
-
-        cairo_rectangle (cr, 0.0, 0.0, w, h);
-
-        if (cairo_in_fill (cr, x, y))
-        {
-                return TRUE;
-        }
-
-        return FALSE;
-}
-
-
 /*****************************************************************************/
 /* Return apropos cursor for create object mode.                             */
 /*****************************************************************************/
@@ -376,7 +90,7 @@ gl_view_image_create_button_press_event   (glView *view,
 {
 	GObject             *object;
 
-        gl_view_unselect_all (view);
+        gl_label_unselect_all (view->label);
 
         object = gl_label_image_new (view->label);
         gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
diff --git a/src/view-image.h b/src/view-image.h
index 49b8773..66bad8b 100644
--- a/src/view-image.h
+++ b/src/view-image.h
@@ -21,42 +21,14 @@
 #ifndef __VIEW_IMAGE_H__
 #define __VIEW_IMAGE_H__
 
-#include "view-object.h"
-#include "label-image.h"
+#include "view.h"
+#include <gdk/gdk.h>
 
 G_BEGIN_DECLS
 
 
-#define GL_TYPE_VIEW_IMAGE            (gl_view_image_get_type ())
-#define GL_VIEW_IMAGE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GL_TYPE_VIEW_IMAGE, glViewImage))
-#define GL_VIEW_IMAGE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GL_TYPE_VIEW_IMAGE, glViewImageClass))
-#define GL_IS_VIEW_IMAGE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GL_TYPE_VIEW_IMAGE))
-#define GL_IS_VIEW_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GL_TYPE_VIEW_IMAGE))
-
-typedef struct _glViewImage          glViewImage;
-typedef struct _glViewImageClass     glViewImageClass;
-
-typedef struct _glViewImagePrivate   glViewImagePrivate;
-
-struct _glViewImage {
-	glViewObject        parent_object;
-
-	glViewImagePrivate *priv;
-};
-
-struct _glViewImageClass {
-	glViewObjectClass   parent_class;
-};
-
-
-GType          gl_view_image_get_type (void) G_GNUC_CONST;
-
-glViewObject  *gl_view_image_new      (glLabelImage *object,
-                                       glView     *view);
-
-
 /* cursor for creating image objects */
-GdkCursor *gl_view_image_get_create_cursor (void);
+GdkCursor *gl_view_image_get_create_cursor           (void);
 
 /* Object creation handlers. */
 void       gl_view_image_create_button_press_event   (glView *view,
diff --git a/src/view-line.c b/src/view-line.c
index 3cb62f1..2c7a0f2 100644
--- a/src/view-line.c
+++ b/src/view-line.c
@@ -22,12 +22,7 @@
 
 #include "view-line.h"
 
-#include <glib/gi18n.h>
-#include <glib.h>
-
-#include "color.h"
-#include "object-editor.h"
-#include "stock.h"
+#include "label-line.h"
 
 #include "pixmaps/cursor_line.xbm"
 #include "pixmaps/cursor_line_mask.xbm"
@@ -44,9 +39,6 @@
 /* Private types.                                         */
 /*========================================================*/
 
-struct _glViewLinePrivate {
-};
-
 
 /*========================================================*/
 /* Private globals.                                       */
@@ -57,306 +49,6 @@ struct _glViewLinePrivate {
 /* Private function prototypes.                           */
 /*========================================================*/
 
-static void       gl_view_line_finalize             (GObject          *object);
-
-static GtkWidget *construct_properties_editor       (glViewObject     *view_object);
-
-static void       update_object_from_editor_cb      (glObjectEditor   *editor,
-						     glLabelObject    *object);
-
-static void       update_editor_from_object_cb      (glLabelObject    *object,
-						     glObjectEditor   *editor);
-
-static void       update_editor_from_move_cb        (glLabelObject    *object,
-						     gdouble           dx,
-						     gdouble           dy,
-						     glObjectEditor   *editor);
-
-static gboolean   object_at                         (glViewObject     *view_object,
-                                                     cairo_t          *cr,
-                                                     gdouble           x,
-                                                     gdouble           y);
-
-
-/*****************************************************************************/
-/* Boilerplate object stuff.                                                 */
-/*****************************************************************************/
-G_DEFINE_TYPE (glViewLine, gl_view_line, GL_TYPE_VIEW_OBJECT);
-
-
-static void
-gl_view_line_class_init (glViewLineClass *class)
-{
-	GObjectClass      *object_class      = G_OBJECT_CLASS (class);
-	glViewObjectClass *view_object_class = GL_VIEW_OBJECT_CLASS (class);
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	gl_view_line_parent_class = g_type_class_peek_parent (class);
-
-	object_class->finalize = gl_view_line_finalize;
-
-	view_object_class->construct_editor = construct_properties_editor;
-	view_object_class->object_at        = object_at;
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-static void
-gl_view_line_init (glViewLine *view_line)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	view_line->priv = g_new0 (glViewLinePrivate, 1);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-static void
-gl_view_line_finalize (GObject *object)
-{
-        glViewLine *view_line = GL_VIEW_LINE (object);
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (object && GL_IS_VIEW_LINE (object));
-
-        g_free (view_line->priv);
-
-	G_OBJECT_CLASS (gl_view_line_parent_class)->finalize (object);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* NEW line object view.                                                  */
-/*****************************************************************************/
-glViewObject *
-gl_view_line_new (glLabelLine *object,
-                  glView     *view)
-{
-	glViewLine         *view_line;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_val_if_fail (object && GL_IS_LABEL_LINE (object), NULL);
-	g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
-	
-	view_line = g_object_new (gl_view_line_get_type(), NULL);
-
-	gl_view_object_set_object (GL_VIEW_OBJECT(view_line),
-				   GL_LABEL_OBJECT(object),
-				   GL_VIEW_OBJECT_HANDLES_LINE);
-	gl_view_object_set_view (GL_VIEW_OBJECT(view_line), view);
-
-	gl_debug (DEBUG_VIEW, "END");
-
-	return GL_VIEW_OBJECT (view_line);
-}
-
-
-/*****************************************************************************/
-/* Create a properties dialog for a line object.                             */
-/*****************************************************************************/
-static GtkWidget *
-construct_properties_editor (glViewObject *view_object)
-{
-	GtkWidget          *editor;
-	glViewLine         *view_line = (glViewLine *)view_object;
-	glLabelObject      *object;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	object = gl_view_object_get_object (GL_VIEW_OBJECT(view_line));
-
-	/* Build editor. */
-	editor = gl_object_editor_new (GL_STOCK_LINE, _("Line object properties"),
-                                       object->parent,
-				       GL_OBJECT_EDITOR_SHADOW_PAGE,
-				       GL_OBJECT_EDITOR_POSITION_PAGE,
-				       GL_OBJECT_EDITOR_SIZE_LINE_PAGE,
-				       GL_OBJECT_EDITOR_LINE_PAGE,
-				       0);
-	
-	/* Update */
-	update_editor_from_object_cb (object, GL_OBJECT_EDITOR(editor));
-	update_editor_from_move_cb (object, 0, 0, GL_OBJECT_EDITOR(editor));
-
-	/* Connect signals. */
-	g_signal_connect (G_OBJECT (editor), "changed",
-			  G_CALLBACK(update_object_from_editor_cb), object);
-	g_signal_connect (G_OBJECT (object), "changed",
-			  G_CALLBACK (update_editor_from_object_cb), editor);
-	g_signal_connect (G_OBJECT (object), "moved",
-			  G_CALLBACK (update_editor_from_move_cb), editor);
-
-	gl_debug (DEBUG_VIEW, "END");
-
-	return editor;
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE.  editor "changed" callback.                                      */
-/*---------------------------------------------------------------------------*/
-static void
-update_object_from_editor_cb (glObjectEditor *editor,
-			      glLabelObject  *object)
-{
-	gdouble            x, y, w, h;
-	glColorNode       *line_color_node;
-	gdouble            line_width;
-	gboolean           shadow_state;
-	gdouble            shadow_x, shadow_y;
-	glColorNode	  *shadow_color_node;
-	gdouble            shadow_opacity;
-	
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_signal_handlers_block_by_func (G_OBJECT(object),
-					 update_editor_from_object_cb,
-					 editor);
-	g_signal_handlers_block_by_func (G_OBJECT(object),
-					 update_editor_from_move_cb,
-					 editor);
-
-	gl_object_editor_get_position (editor, &x, &y);
-	gl_label_object_set_position (object, x, y);
-
-	gl_object_editor_get_lsize (editor, &w, &h);
-	gl_label_object_set_size (object, w, h);
-
-	line_color_node = gl_object_editor_get_line_color (editor);
-	gl_label_object_set_line_color (object, line_color_node);
-	gl_color_node_free (&line_color_node);
-
-	line_width = gl_object_editor_get_line_width (editor);
-	gl_label_object_set_line_width (object, line_width);
-
-	shadow_state = gl_object_editor_get_shadow_state (editor);
-	gl_label_object_set_shadow_state (object, shadow_state);
-
-	gl_object_editor_get_shadow_offset (editor, &shadow_x, &shadow_y);
-	gl_label_object_set_shadow_offset (object, shadow_x, shadow_y);
-
-	shadow_color_node = gl_object_editor_get_shadow_color (editor);
-	gl_label_object_set_shadow_color (object, shadow_color_node);
-	gl_color_node_free (&shadow_color_node);
-
-	shadow_opacity = gl_object_editor_get_shadow_opacity (editor);
-	gl_label_object_set_shadow_opacity (object, shadow_opacity);
-
-	g_signal_handlers_unblock_by_func (G_OBJECT(object),
-					   update_editor_from_object_cb,
-					   editor);
-	g_signal_handlers_unblock_by_func (G_OBJECT(object),
-					   update_editor_from_move_cb,
-					   editor);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE. label object "changed" callback.                                 */
-/*---------------------------------------------------------------------------*/
-static void
-update_editor_from_object_cb (glLabelObject  *object,
-			      glObjectEditor *editor)
-{
-	gdouble            w, h;
-	glColorNode       *line_color_node;
-	gdouble            line_width;
-	gboolean           shadow_state;
-	gdouble            shadow_x, shadow_y;
-	glColorNode	  *shadow_color_node;
-	gdouble            shadow_opacity;
-	glMerge	          *merge;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	gl_label_object_get_size (object, &w, &h);
-	gl_object_editor_set_lsize (editor, w, h);
-	merge = gl_label_get_merge (GL_LABEL(object->parent));
-	
-	line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
-	gl_object_editor_set_line_color (editor, (merge != NULL), line_color_node);
-	gl_color_node_free (&line_color_node);
-
-	line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
-	gl_object_editor_set_line_width (editor, line_width);
-
-	shadow_state = gl_label_object_get_shadow_state (object);
-	gl_object_editor_set_shadow_state (editor, shadow_state);
-
-	gl_label_object_get_shadow_offset (object, &shadow_x, &shadow_y);
-	gl_object_editor_set_shadow_offset (editor, shadow_x, shadow_y);
-
-	shadow_color_node = gl_label_object_get_shadow_color (object);
-	gl_object_editor_set_shadow_color (editor, (merge != NULL), shadow_color_node);
-	gl_color_node_free (&shadow_color_node);
-
-	shadow_opacity = gl_label_object_get_shadow_opacity (object);
-	gl_object_editor_set_shadow_opacity (editor, shadow_opacity);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE. label object "moved" callback.                                   */
-/*---------------------------------------------------------------------------*/
-static void
-update_editor_from_move_cb (glLabelObject    *object,
-			    gdouble           dx,
-			    gdouble           dy,
-			    glObjectEditor   *editor)
-{
-	gdouble            x, y;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	gl_label_object_get_position (object, &x, &y);
-	gl_object_editor_set_position (editor, x, y);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Is object at (x,y)?                                                       */
-/*****************************************************************************/
-static gboolean
-object_at (glViewObject  *view_object,
-           cairo_t       *cr,
-           gdouble        x,
-           gdouble        y)
-{
-	glLabelObject    *object;
-        gdouble           w, h;
-        gdouble           line_width;
-
-        object = gl_view_object_get_object (view_object);
-
-        gl_label_object_get_size (object, &w, &h);
-
-        cairo_move_to (cr, 0.0, 0.0);
-        cairo_line_to (cr, w, h);
-
-        line_width = gl_label_object_get_line_width (object);
-        cairo_set_line_width (cr, line_width);
-        if (cairo_in_stroke (cr, x, y))
-        {
-                return TRUE;
-        }
-
-        return FALSE;
-}
-
 
 /*****************************************************************************/
 /* Return apropos cursor for create object mode.                             */
@@ -398,22 +90,12 @@ gl_view_line_create_button_press_event   (glView *view,
                                           gdouble y)
 {
 	GObject             *object;
-	glColorNode         *line_color_node;
 
-        gl_view_unselect_all (view);
+        gl_label_unselect_all (view->label);
 
-        line_color_node = gl_color_node_new_default ();
-		
         object = gl_label_line_new (view->label);
         gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
         gl_label_object_set_size (GL_LABEL_OBJECT(object), 0.0, 0.0);
-        line_color_node->color = gl_color_set_opacity (gl_view_get_default_line_color(view), 0.5);
-        gl_label_object_set_line_width (GL_LABEL_OBJECT(object),
-                                        gl_view_get_default_line_width(view));
-        gl_label_object_set_line_color (GL_LABEL_OBJECT(object),
-                                        line_color_node);
-
-        gl_color_node_free (&line_color_node);
 
         view->create_object = GL_LABEL_OBJECT (object);
         view->create_x0 = x;
@@ -445,11 +127,8 @@ gl_view_line_create_button_release_event (glView *view,
                                           gdouble x,
                                           gdouble y)
 {
-	glColorNode         *line_color_node;
         gdouble              w, h;
 
-        line_color_node = gl_color_node_new_default ();
-		
         if ((view->create_x0 == x) && (view->create_y0 == y)) {
                 x = view->create_x0 + 36.0;
                 y = view->create_y0 + 36.0;
@@ -457,9 +136,6 @@ gl_view_line_create_button_release_event (glView *view,
         w = x - view->create_x0;
         h = y - view->create_y0;
         gl_label_object_set_size (GL_LABEL_OBJECT(view->create_object), w, h);
-        line_color_node->color = gl_view_get_default_line_color(view);
-        gl_label_object_set_line_color (GL_LABEL_OBJECT(view->create_object), line_color_node);
-        gl_color_node_free (&line_color_node);
 }
 
 
diff --git a/src/view-line.h b/src/view-line.h
index 9fc54ab..406ae7f 100644
--- a/src/view-line.h
+++ b/src/view-line.h
@@ -21,42 +21,14 @@
 #ifndef __VIEW_LINE_H__
 #define __VIEW_LINE_H__
 
-#include "view-object.h"
-#include "label-line.h"
+#include "view.h"
+#include <gdk/gdk.h>
 
 G_BEGIN_DECLS
 
 
-#define GL_TYPE_VIEW_LINE            (gl_view_line_get_type ())
-#define GL_VIEW_LINE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GL_TYPE_VIEW_LINE, glViewLine))
-#define GL_VIEW_LINE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GL_TYPE_VIEW_LINE, glViewLineClass))
-#define GL_IS_VIEW_LINE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GL_TYPE_VIEW_LINE))
-#define GL_IS_VIEW_LINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GL_TYPE_VIEW_LINE))
-
-typedef struct _glViewLine          glViewLine;
-typedef struct _glViewLineClass     glViewLineClass;
-
-typedef struct _glViewLinePrivate   glViewLinePrivate;
-
-struct _glViewLine {
-	glViewObject       parent_object;
-
-	glViewLinePrivate *priv;
-};
-
-struct _glViewLineClass {
-	glViewObjectClass  parent_class;
-};
-
-
-GType          gl_view_line_get_type (void) G_GNUC_CONST;
-
-glViewObject  *gl_view_line_new      (glLabelLine *object,
-                                      glView     *view);
-
-
 /* cursor for creating line objects */
-GdkCursor *gl_view_line_get_create_cursor (void);
+GdkCursor *gl_view_line_get_create_cursor           (void);
 
 /* Object creation handlers. */
 void       gl_view_line_create_button_press_event   (glView *view,
diff --git a/src/view-text.c b/src/view-text.c
index e45c7dc..569a8c3 100644
--- a/src/view-text.c
+++ b/src/view-text.c
@@ -23,11 +23,8 @@
 #include "view-text.h"
 
 #include <glib/gi18n.h>
-#include <glib.h>
 
-#include "color.h"
-#include "object-editor.h"
-#include "stock.h"
+#include "label-text.h"
 
 #include "pixmaps/cursor_text.xbm"
 #include "pixmaps/cursor_text_mask.xbm"
@@ -44,9 +41,6 @@
 /* Private types.                                         */
 /*========================================================*/
 
-struct _glViewTextPrivate {
-};
-
 
 /*========================================================*/
 /* Private globals.                                       */
@@ -57,380 +51,6 @@ struct _glViewTextPrivate {
 /* Private function prototypes.                           */
 /*========================================================*/
 
-static void       gl_view_text_finalize             (GObject          *object);
-
-static GtkWidget *construct_properties_editor       (glViewObject     *view_object);
-
-static void       update_object_from_editor_cb      (glObjectEditor   *editor,
-						     glLabelObject    *object);
-
-static void       update_object_from_editor_size_cb (glObjectEditor   *editor,
-                                                     glLabelObject    *object);
-
-static void       update_editor_from_object_cb      (glLabelObject    *object,
-						     glObjectEditor   *editor);
-
-static void       update_editor_from_move_cb        (glLabelObject    *object,
-						     gdouble           dx,
-						     gdouble           dy,
-						     glObjectEditor   *editor);
-
-static gboolean   object_at                         (glViewObject     *view_object,
-                                                     cairo_t          *cr,
-                                                     gdouble           x,
-                                                     gdouble           y);
-
-
-/*****************************************************************************/
-/* Boilerplate object stuff.                                                 */
-/*****************************************************************************/
-G_DEFINE_TYPE (glViewText, gl_view_text, GL_TYPE_VIEW_OBJECT);
-
-
-static void
-gl_view_text_class_init (glViewTextClass *class)
-{
-	GObjectClass      *object_class      = G_OBJECT_CLASS (class);
-	glViewObjectClass *view_object_class = GL_VIEW_OBJECT_CLASS (class);
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	gl_view_text_parent_class = g_type_class_peek_parent (class);
-
-	object_class->finalize = gl_view_text_finalize;
-
-	view_object_class->construct_editor = construct_properties_editor;
-	view_object_class->object_at        = object_at;
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-static void
-gl_view_text_init (glViewText *view_text)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	view_text->priv = g_new0 (glViewTextPrivate, 1);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-static void
-gl_view_text_finalize (GObject *object)
-{
-        glViewText *view_text = GL_VIEW_TEXT (object);
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (object && GL_IS_VIEW_TEXT (object));
-
-        g_free (view_text->priv);
-
-	G_OBJECT_CLASS (gl_view_text_parent_class)->finalize (object);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* NEW text object view.                                                     */
-/*****************************************************************************/
-glViewObject *
-gl_view_text_new (glLabelText *object,
-                  glView      *view)
-{
-	glViewText         *view_text;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_val_if_fail (object && GL_IS_LABEL_TEXT (object), NULL);
-	g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
-	
-	view_text = g_object_new (gl_view_text_get_type(), NULL);
-
-	gl_view_object_set_object (GL_VIEW_OBJECT(view_text),
-				   GL_LABEL_OBJECT(object),
-				   GL_VIEW_OBJECT_HANDLES_BOX);
-	gl_view_object_set_view (GL_VIEW_OBJECT(view_text), view);
-
-	gl_debug (DEBUG_VIEW, "END");
-
-	return GL_VIEW_OBJECT (view_text);
-}
-
-
-/*****************************************************************************/
-/* Create a properties dialog for a text object.                             */
-/*****************************************************************************/
-static GtkWidget *
-construct_properties_editor (glViewObject *view_object)
-{
-	GtkWidget          *editor;
-	glViewText          *view_text = (glViewText *)view_object;
-	glLabelObject      *object;
-	GtkTextBuffer      *buffer;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	object = gl_view_object_get_object (GL_VIEW_OBJECT(view_text));
-
-	/* Build editor. */
-	editor = gl_object_editor_new (GL_STOCK_TEXT, _("Text object properties"),
-                                       object->parent,
-				       GL_OBJECT_EDITOR_SHADOW_PAGE,
-				       GL_OBJECT_EDITOR_POSITION_PAGE,
-				       GL_OBJECT_EDITOR_SIZE_PAGE,
-				       GL_OBJECT_EDITOR_TEXT_PAGE,
-				       GL_OBJECT_EDITOR_EDIT_PAGE,
-				       0);
-
-	buffer = gl_label_text_get_buffer (GL_LABEL_TEXT(object));
-	gl_object_editor_set_text_buffer (GL_OBJECT_EDITOR(editor), buffer);
-	
-	/* Update */
-	update_editor_from_object_cb (object, GL_OBJECT_EDITOR(editor));
-	update_editor_from_move_cb (object, 0, 0, GL_OBJECT_EDITOR(editor));
-
-	/* Connect signals. */
-	g_signal_connect (G_OBJECT (editor), "changed",
-			  G_CALLBACK(update_object_from_editor_cb), object);
-	g_signal_connect (G_OBJECT (editor), "size_changed",
-			  G_CALLBACK(update_object_from_editor_size_cb), object);
-	g_signal_connect (G_OBJECT (object), "changed",
-			  G_CALLBACK (update_editor_from_object_cb), editor);
-	g_signal_connect (G_OBJECT (object), "moved",
-			  G_CALLBACK (update_editor_from_move_cb), editor);
-
-	gl_debug (DEBUG_VIEW, "END");
-
-	return editor;
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE.  editor "changed" callback.                                      */
-/*---------------------------------------------------------------------------*/
-static void
-update_object_from_editor_cb (glObjectEditor *editor,
-			      glLabelObject  *object)
-{
-	gdouble            x, y;
-	gchar             *font_family;
-	gdouble            font_size;
-	PangoWeight        font_weight;
-	gboolean           font_italic_flag;
-	glColorNode       *color_node;
-	PangoAlignment     align;
-	gdouble            text_line_spacing;
-	gboolean           auto_shrink;
-	gboolean           shadow_state;
-	gdouble            shadow_x, shadow_y;
-	glColorNode	  *shadow_color_node;
-	gdouble            shadow_opacity;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_signal_handlers_block_by_func (G_OBJECT(object),
-					 update_editor_from_object_cb,
-					 editor);
-	g_signal_handlers_block_by_func (G_OBJECT(object),
-					 update_editor_from_move_cb,
-					 editor);
-
-	gl_object_editor_get_position (editor, &x, &y);
-	font_family = gl_object_editor_get_font_family (editor);
-	font_size = gl_object_editor_get_font_size (editor);
-	font_weight = gl_object_editor_get_font_weight (editor);
-	font_italic_flag = gl_object_editor_get_font_italic_flag (editor);
-	color_node = gl_object_editor_get_text_color (editor);
-	align = gl_object_editor_get_text_alignment (editor);
-	text_line_spacing = gl_object_editor_get_text_line_spacing (editor);
-	auto_shrink = gl_object_editor_get_text_auto_shrink (editor);
-
-	gl_label_object_set_position (object, x, y);
-	gl_label_object_set_font_family (object, font_family);
-	gl_label_object_set_font_size (object, font_size);
-	gl_label_object_set_font_weight (object, font_weight);
-	gl_label_object_set_font_italic_flag (object, font_italic_flag);
-	gl_label_object_set_text_color (object, color_node);
-	gl_label_object_set_text_alignment (object, align);
-	gl_label_object_set_text_line_spacing (object, text_line_spacing);
-	gl_label_text_set_auto_shrink (GL_LABEL_TEXT (object), auto_shrink);
-
-	gl_color_node_free (&color_node);
-	g_free (font_family);
-
-	shadow_state = gl_object_editor_get_shadow_state (editor);
-	gl_label_object_set_shadow_state (object, shadow_state);
-
-	gl_object_editor_get_shadow_offset (editor, &shadow_x, &shadow_y);
-	gl_label_object_set_shadow_offset (object, shadow_x, shadow_y);
-
-	shadow_color_node = gl_object_editor_get_shadow_color (editor);
-	gl_label_object_set_shadow_color (object, shadow_color_node);
-	gl_color_node_free (&shadow_color_node);
-
-	shadow_opacity = gl_object_editor_get_shadow_opacity (editor);
-	gl_label_object_set_shadow_opacity (object, shadow_opacity);
-
-	g_signal_handlers_unblock_by_func (G_OBJECT(object),
-					   update_editor_from_object_cb,
-					   editor);
-	g_signal_handlers_unblock_by_func (G_OBJECT(object),
-					   update_editor_from_move_cb,
-					   editor);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE.  editor "changed" callback.                                      */
-/*---------------------------------------------------------------------------*/
-static void
-update_object_from_editor_size_cb (glObjectEditor *editor,
-				   glLabelObject  *object)
-{
-	gdouble            w, h;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_signal_handlers_block_by_func (G_OBJECT(object),
-					 update_editor_from_object_cb,
-					 editor);
-	g_signal_handlers_block_by_func (G_OBJECT(object),
-					 update_editor_from_move_cb,
-					 editor);
-
-	gl_object_editor_get_size (editor, &w, &h);
-
-	gl_label_object_set_size (object, w, h);
-
-	g_signal_handlers_unblock_by_func (G_OBJECT(object),
-					   update_editor_from_object_cb,
-					   editor);
-	g_signal_handlers_unblock_by_func (G_OBJECT(object),
-					   update_editor_from_move_cb,
-					   editor);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE. label object "changed" callback.                                 */
-/*---------------------------------------------------------------------------*/
-static void
-update_editor_from_object_cb (glLabelObject  *object,
-			      glObjectEditor *editor)
-{
-	gdouble            w, h;
-	gchar             *font_family;
-	gdouble            font_size;
-	PangoWeight        font_weight;
-	gboolean           font_italic_flag;
-	glColorNode       *color_node;
-	PangoAlignment     align;
-	gdouble            text_line_spacing;
-	gboolean           auto_shrink;
-	gboolean           shadow_state;
-	gdouble            shadow_x, shadow_y;
-	glColorNode	  *shadow_color_node;
-	gdouble            shadow_opacity;
-	glMerge		  *merge;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	gl_label_object_get_size (object, &w, &h);
-	gl_object_editor_set_size (editor, w, h);
-	merge = gl_label_get_merge (GL_LABEL(object->parent));
-
-	font_family      = gl_label_object_get_font_family (object);
-	font_size        = gl_label_object_get_font_size (object);
-	font_weight      = gl_label_object_get_font_weight (object);
-	font_italic_flag = gl_label_object_get_font_italic_flag (object);
-	color_node       = gl_label_object_get_text_color (object);
-	align             = gl_label_object_get_text_alignment (object);
-	text_line_spacing = gl_label_object_get_text_line_spacing (object);
-	auto_shrink      = gl_label_text_get_auto_shrink (GL_LABEL_TEXT (object));
-
-	gl_object_editor_set_font_family (editor, font_family);
-	gl_object_editor_set_font_size (editor, font_size);
-	gl_object_editor_set_font_weight (editor, font_weight);
-	gl_object_editor_set_font_italic_flag (editor, font_italic_flag);
-	gl_object_editor_set_text_color (editor, (merge != NULL), color_node);
-	gl_object_editor_set_text_alignment (editor, align);
-	gl_object_editor_set_text_line_spacing (editor, text_line_spacing);
-	gl_object_editor_set_text_auto_shrink (editor, auto_shrink);
-
-	gl_color_node_free (&color_node);
-	g_free (font_family);
-
-	shadow_state = gl_label_object_get_shadow_state (object);
-	gl_object_editor_set_shadow_state (editor, shadow_state);
-
-	gl_label_object_get_shadow_offset (object, &shadow_x, &shadow_y);
-	gl_object_editor_set_shadow_offset (editor, shadow_x, shadow_y);
-
-	shadow_color_node = gl_label_object_get_shadow_color (object);
-	gl_object_editor_set_shadow_color (editor, (merge != NULL), shadow_color_node);
-	gl_color_node_free (&shadow_color_node);
-
-	shadow_opacity = gl_label_object_get_shadow_opacity (object);
-	gl_object_editor_set_shadow_opacity (editor, shadow_opacity);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE. label object "moved" callback.                                   */
-/*---------------------------------------------------------------------------*/
-static void
-update_editor_from_move_cb (glLabelObject    *object,
-			    gdouble           dx,
-			    gdouble           dy,
-			    glObjectEditor   *editor)
-{
-	gdouble            x, y;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	gl_label_object_get_position (object, &x, &y);
-	gl_object_editor_set_position (editor, x, y);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Is object at (x,y)?                                                       */
-/*****************************************************************************/
-static gboolean
-object_at (glViewObject  *view_object,
-           cairo_t       *cr,
-           gdouble        x,
-           gdouble        y)
-{
-	glLabelObject    *object;
-        gdouble           w, h;
-
-        object = gl_view_object_get_object (view_object);
-
-        gl_label_object_get_size (object, &w, &h);
-
-        cairo_rectangle (cr, 0.0, 0.0, w, h);
-
-        if (cairo_in_fill (cr, x, y))
-        {
-                return TRUE;
-        }
-
-        return FALSE;
-}
-
 
 /*****************************************************************************/
 /* Return apropos cursor for create object mode.                             */
@@ -473,34 +93,14 @@ gl_view_text_create_button_press_event   (glView *view,
 {
 	GObject             *object;
 	GList               *lines;
-	gchar               *family;
-	glColorNode         *color_node;
 
-        gl_view_unselect_all (view);
+        gl_label_unselect_all (view->label);
 
         object = gl_label_text_new (view->label);
-        color_node = gl_color_node_new_default ();
         gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
-        family = gl_view_get_default_font_family (view);
-        gl_label_object_set_font_family (GL_LABEL_OBJECT(object), family);
-        gl_label_object_set_font_size (GL_LABEL_OBJECT(object),
-                                       gl_view_get_default_font_size (view));
-        gl_label_object_set_font_weight (GL_LABEL_OBJECT(object),
-                                         gl_view_get_default_font_weight (view));
-        gl_label_object_set_font_italic_flag (GL_LABEL_OBJECT(object),
-                                              gl_view_get_default_font_italic_flag (view));
-								  
-        color_node->color = gl_color_set_opacity (gl_view_get_default_text_color (view), 0.5);
-        gl_label_object_set_text_color (GL_LABEL_OBJECT(object),
-							color_node);
-        gl_label_object_set_text_alignment (GL_LABEL_OBJECT(object),
-                                            gl_view_get_default_text_alignment (view));
-        gl_label_object_set_text_line_spacing (GL_LABEL_OBJECT(object), gl_view_get_default_text_line_spacing (view));
-						       
-        g_free (family);
+
         lines = gl_text_node_lines_new_from_text (_("Text"));
         gl_label_text_set_lines (GL_LABEL_TEXT(object), lines);
-        gl_color_node_free (&color_node);
 
         view->create_object = GL_LABEL_OBJECT (object);
         view->create_x0 = x;
@@ -528,13 +128,7 @@ gl_view_text_create_button_release_event (glView *view,
                                           gdouble x,
                                           gdouble y)
 {
-	glColorNode         *color_node;
-
-        color_node = gl_color_node_new_default ();
         gl_label_object_set_position (GL_LABEL_OBJECT(view->create_object), x, y);
-        color_node->color = gl_view_get_default_text_color(view);
-        gl_label_object_set_text_color (GL_LABEL_OBJECT(view->create_object), color_node);
-        gl_color_node_free (&color_node);
 }
 
 
diff --git a/src/view-text.h b/src/view-text.h
index 150ffb8..d1be8c0 100644
--- a/src/view-text.h
+++ b/src/view-text.h
@@ -21,42 +21,17 @@
 #ifndef __VIEW_TEXT_H__
 #define __VIEW_TEXT_H__
 
-#include "view-object.h"
-#include "label-text.h"
+#include "view.h"
+#include <gdk/gdk.h>
 
-G_BEGIN_DECLS
-
-
-#define GL_TYPE_VIEW_TEXT            (gl_view_text_get_type ())
-#define GL_VIEW_TEXT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GL_TYPE_VIEW_TEXT, glViewText))
-#define GL_VIEW_TEXT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GL_TYPE_VIEW_TEXT, glViewTextClass))
-#define GL_IS_VIEW_TEXT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GL_TYPE_VIEW_TEXT))
-#define GL_IS_VIEW_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GL_TYPE_VIEW_TEXT))
-
-typedef struct _glViewText          glViewText;
-typedef struct _glViewTextClass     glViewTextClass;
-
-typedef struct _glViewTextPrivate   glViewTextPrivate;
-
-struct _glViewText {
-	glViewObject       parent_object;
+#include "view.h"
+#include <gdk/gdk.h>
 
-	glViewTextPrivate *priv;
-};
-
-struct _glViewTextClass {
-	glViewObjectClass  parent_class;
-};
-
-
-GType          gl_view_text_get_type (void) G_GNUC_CONST;
-
-glViewObject  *gl_view_text_new      (glLabelText *object,
-                                      glView      *view);
+G_BEGIN_DECLS
 
 
 /* cursor for creating text objects */
-GdkCursor *gl_view_text_get_create_cursor (void);
+GdkCursor *gl_view_text_get_create_cursor           (void);
 
 /* Object creation handlers. */
 void       gl_view_text_create_button_press_event   (glView *view,
diff --git a/src/view.c b/src/view.c
index c814cd1..f808e8f 100644
--- a/src/view.c
+++ b/src/view.c
@@ -22,6 +22,13 @@
 
 #include "view.h"
 
+#include "view-box.h"
+#include "view-ellipse.h"
+#include "view-line.h"
+#include "view-image.h"
+#include "view-text.h"
+#include "view-barcode.h"
+
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <gdk/gdkkeysyms.h>
@@ -31,14 +38,6 @@
 #include "label.h"
 #include "cairo-label-path.h"
 #include "cairo-markup-path.h"
-#include "view-object.h"
-#include "view-box.h"
-#include "view-ellipse.h"
-#include "view-line.h"
-#include "view-image.h"
-#include "view-text.h"
-#include "view-barcode.h"
-#include "xml-label.h"
 #include "color.h"
 #include "prefs.h"
 #include "marshal.h"
@@ -74,7 +73,6 @@
 /*==========================================================================*/
 
 enum {
-	SELECTION_CHANGED,
 	CONTEXT_MENU_ACTIVATE,
 	ZOOM_CHANGED,
 	POINTER_MOVED,
@@ -90,9 +88,6 @@ enum {
 
 static guint signals[LAST_SIGNAL] = {0};
 
-/* "CLIPBOARD" selection */
-static GdkAtom clipboard_atom = GDK_NONE;
-
 static gdouble zooms[] = {
 	8.00,
 	6.00,
@@ -138,9 +133,6 @@ static void       label_changed_cb                (glView         *view);
 
 static void       label_resized_cb                (glView         *view);
 
-static void       label_object_added_cb           (glView         *view,
-                                                   glLabelObject  *object);
-
 static void       draw_layers                     (glView         *view,
                                                    cairo_t        *cr);
 
@@ -159,35 +151,10 @@ static void       draw_highlight_layer            (glView         *view,
 static void       draw_select_region_layer        (glView         *view,
                                                    cairo_t        *cr);
 
-static void       select_object_real              (glView         *view,
-						   glViewObject   *view_object);
-static void       unselect_object_real            (glView         *view,
-						   glViewObject   *view_object);
-
-static glViewObject *view_view_object_at          (glView         *view,
-                                                   cairo_t        *cr,
-						   gdouble         x,
-                                                   gdouble         y);
-
 static void       set_zoom_real                   (glView         *view,
 						   gdouble         zoom,
 						   gboolean        scale_to_fit_flag);
 
-static void       selection_clear_cb              (GtkWidget         *widget,
-                                                   GdkEventSelection *event,
-                                                   glView            *view);
-
-static void       selection_get_cb                (GtkWidget         *widget,
-                                                   GtkSelectionData  *selection_data,
-                                                   guint              info,
-                                                   guint              time,
-                                                   glView            *view);
-
-static void       selection_received_cb           (GtkWidget         *widget,
-                                                   GtkSelectionData  *selection_data,
-                                                   guint              time,
-                                                   glView            *view);
-
 static gboolean   focus_in_event_cb               (glView            *view,
                                                    GdkEventFocus     *event);
 
@@ -212,6 +179,10 @@ static gboolean   button_release_event_cb         (glView            *view,
 static gboolean   key_press_event_cb              (glView            *view,
                                                    GdkEventKey       *event);
 
+static void       resize_event                    (glView            *view,
+                                                   cairo_t           *cr,
+                                                   gdouble            x,
+                                                   gdouble            y);
 
 /****************************************************************************/
 /* Boilerplate Object stuff.                                                */
@@ -230,16 +201,6 @@ gl_view_class_init (glViewClass *class)
 
 	object_class->finalize = gl_view_finalize;
 
-	signals[SELECTION_CHANGED] =
-		g_signal_new ("selection_changed",
-			      G_OBJECT_CLASS_TYPE (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (glViewClass, selection_changed),
-			      NULL, NULL,
-			      gl_marshal_VOID__VOID,
-			      G_TYPE_NONE,
-			      0);
-
 	signals[CONTEXT_MENU_ACTIVATE] =
 		g_signal_new ("context_menu_activate",
 			      G_OBJECT_CLASS_TYPE (object_class),
@@ -306,10 +267,7 @@ gl_view_init (glView *view)
 	view->grid_visible         = TRUE;
 	view->grid_spacing         = 9;
 	view->markup_visible       = TRUE;
-	view->default_font_family  = NULL;
 	view->mode                 = GL_VIEW_MODE_ARROW;
-	view->object_list          = NULL;
-	view->selected_object_list = NULL;
 	view->zoom                 = 1.0;
 	view->home_scale           = get_home_scale (view);
 
@@ -364,40 +322,6 @@ gl_view_init (glView *view)
 	g_signal_connect_swapped (G_OBJECT (view->canvas), "key-press-event",
 				  G_CALLBACK (key_press_event_cb), view);
 
-        /*
-         * Clipboard
-         */
-	view->have_selection       = FALSE;
-	view->selection_data       = NULL;
-	view->invisible            = gtk_invisible_new ();
-	if (!clipboard_atom) {
-		clipboard_atom = gdk_atom_intern ("GLABELS_CLIPBOARD", FALSE);
-	}
-	gtk_selection_add_target (view->invisible,
-				  clipboard_atom, GDK_SELECTION_TYPE_STRING, 1);
-	g_signal_connect (G_OBJECT (view->invisible),
-			  "selection_clear_event",
-			  G_CALLBACK (selection_clear_cb), view);
-	g_signal_connect (G_OBJECT (view->invisible), "selection_get",
-			  G_CALLBACK (selection_get_cb), view);
-	g_signal_connect (G_OBJECT (view->invisible),
-			  "selection_received",
-			  G_CALLBACK (selection_received_cb), view);
-
-        /*
-         * Defaults from preferences
-         */
-	gl_view_set_default_font_family       (view, gl_prefs_model_get_default_font_family (gl_prefs));
-	gl_view_set_default_font_size         (view, gl_prefs_model_get_default_font_size (gl_prefs));
-	gl_view_set_default_font_weight       (view, gl_prefs_model_get_default_font_weight (gl_prefs));
-	gl_view_set_default_font_italic_flag  (view, gl_prefs_model_get_default_font_italic_flag (gl_prefs));
-	gl_view_set_default_text_color        (view, gl_prefs_model_get_default_text_color (gl_prefs));
-	gl_view_set_default_text_alignment    (view, gl_prefs_model_get_default_text_alignment (gl_prefs));
-	gl_view_set_default_text_line_spacing (view, gl_prefs_model_get_default_text_line_spacing (gl_prefs));
-	gl_view_set_default_line_width        (view, gl_prefs_model_get_default_line_width (gl_prefs));
-	gl_view_set_default_line_color        (view, gl_prefs_model_get_default_line_color (gl_prefs));
-	gl_view_set_default_fill_color        (view, gl_prefs_model_get_default_fill_color (gl_prefs));
-
 	gl_debug (DEBUG_VIEW, "END");
 }
 
@@ -410,11 +334,7 @@ gl_view_finalize (GObject *object)
 	gl_debug (DEBUG_VIEW, "START");
 
 	g_return_if_fail (object != NULL);
-	g_return_if_fail (GL_IS_VIEW (object));
-
-	if (view->default_font_family) {
-		g_free (view->default_font_family);
-	}
+	g_return_if_fail (GL_IS_VIEW (view));
 
 	G_OBJECT_CLASS (gl_view_parent_class)->finalize (object);
 
@@ -451,43 +371,18 @@ static void
 gl_view_construct (glView  *view,
                    glLabel *label)
 {
-        GList            *p_obj;
-        glLabelObject    *object;
-
 	gl_debug (DEBUG_VIEW, "START");
 
 	g_return_if_fail (GL_IS_VIEW (view));
 
 	view->label = label;
 
-        for (p_obj = label->objects; p_obj != NULL; p_obj = p_obj->next)
-        {
-                object = GL_LABEL_OBJECT (p_obj->data);
-
-                if (GL_IS_LABEL_BOX (object)) {
-                        gl_view_box_new (GL_LABEL_BOX(object), view);
-                } else if (GL_IS_LABEL_ELLIPSE (object)) {
-                        gl_view_ellipse_new (GL_LABEL_ELLIPSE(object), view);
-                } else if (GL_IS_LABEL_LINE (object)) {
-                        gl_view_line_new (GL_LABEL_LINE(object), view);
-                } else if (GL_IS_LABEL_IMAGE (object)) {
-                        gl_view_image_new (GL_LABEL_IMAGE(object), view);
-                } else if (GL_IS_LABEL_TEXT (object)) {
-                        gl_view_text_new (GL_LABEL_TEXT(object), view);
-                } else if (GL_IS_LABEL_BARCODE (object)) {
-                        gl_view_barcode_new (GL_LABEL_BARCODE(object), view);
-                } else {
-                        /* Should not happen! */
-                        g_message ("Invalid label object type.");
-                }
-        }
-
+	g_signal_connect_swapped (G_OBJECT (view->label), "selection_changed",
+                                  G_CALLBACK (label_changed_cb), view);
 	g_signal_connect_swapped (G_OBJECT (view->label), "changed",
                                   G_CALLBACK (label_changed_cb), view);
 	g_signal_connect_swapped (G_OBJECT (view->label), "size_changed",
                                   G_CALLBACK (label_resized_cb), view);
-	g_signal_connect_swapped (G_OBJECT (view->label), "object_added",
-                                  G_CALLBACK (label_object_added_cb), view);
 
 	gl_debug (DEBUG_VIEW, "END");
 }
@@ -754,40 +649,6 @@ label_resized_cb (glView  *view)
 
 
 /*---------------------------------------------------------------------------*/
-/* PRIVATE.  Handle new label object.                                        */
-/*---------------------------------------------------------------------------*/
-static void
-label_object_added_cb (glView         *view,
-                       glLabelObject  *object)
-{
-        glViewObject *view_object;
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
-
-        if (GL_IS_LABEL_BOX (object)) {
-                view_object = gl_view_box_new (GL_LABEL_BOX(object), view);
-        } else if (GL_IS_LABEL_ELLIPSE (object)) {
-                view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(object), view);
-        } else if (GL_IS_LABEL_LINE (object)) {
-                view_object = gl_view_line_new (GL_LABEL_LINE(object), view);
-        } else if (GL_IS_LABEL_IMAGE (object)) {
-                view_object = gl_view_image_new (GL_LABEL_IMAGE(object), view);
-        } else if (GL_IS_LABEL_TEXT (object)) {
-                view_object = gl_view_text_new (GL_LABEL_TEXT(object), view);
-        } else if (GL_IS_LABEL_BARCODE (object)) {
-                view_object = gl_view_barcode_new (GL_LABEL_BARCODE(object), view);
-        } else {
-                /* Should not happen! */
-                view_object = NULL;
-                g_message ("Invalid label object type.");
-        }
-
-        gl_view_select_object (view, view_object);
-}
-
-
-/*---------------------------------------------------------------------------*/
 /* PRIVATE.  Create, draw and order layers.                                  */
 /*---------------------------------------------------------------------------*/
 static void
@@ -847,10 +708,15 @@ static void
 draw_bg_layer (glView  *view,
                cairo_t *cr)
 {
+        const lglTemplate *template;
+        gboolean           rotate_flag;
+
 	g_return_if_fail (view && GL_IS_VIEW (view));
 	g_return_if_fail (view->label && GL_IS_LABEL (view->label));
 
-        gl_cairo_label_path (cr, view->label->template, view->label->rotate_flag, FALSE);
+        template    = gl_label_get_template (view->label);
+        rotate_flag = gl_label_get_rotate_flag (view->label);
+        gl_cairo_label_path (cr, template, rotate_flag, FALSE);
 
         cairo_set_source_rgb (cr, PAPER_RGB_ARGS);
         cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
@@ -865,10 +731,11 @@ static void
 draw_grid_layer (glView  *view,
                  cairo_t *cr)
 {
+        const lglTemplate         *template;
+	const lglTemplateFrame    *frame;
 	gdouble                    w, h;
 	gdouble                    x, y;
 	gdouble                    x0, y0;
-	const lglTemplateFrame    *frame;
 
 	gl_debug (DEBUG_VIEW, "START");
 
@@ -878,7 +745,8 @@ draw_grid_layer (glView  *view,
         if (view->grid_visible)
         {
 
-                frame = (lglTemplateFrame *)view->label->template->frames->data;
+                template = gl_label_get_template (view->label);
+                frame = (lglTemplateFrame *)template->frames->data;
 
                 gl_label_get_size (view->label, &w, &h);
 	
@@ -927,8 +795,9 @@ static void
 draw_markup_layer (glView  *view,
                    cairo_t *cr)
 {
-	glLabel                   *label;
+	const lglTemplate         *template;
 	const lglTemplateFrame    *frame;
+        gboolean                   rotate_flag;
 	GList                     *p;
 	lglTemplateMarkup         *markup;
         gdouble                    width, height;
@@ -939,12 +808,13 @@ draw_markup_layer (glView  *view,
         if (view->markup_visible)
         {
 
-                label      = view->label;
-                frame = (lglTemplateFrame *)view->label->template->frames->data;
+                template    = gl_label_get_template (view->label);
+                frame       = (lglTemplateFrame *)template->frames->data;
+                rotate_flag = gl_label_get_rotate_flag (view->label);
 
                 cairo_save (cr);
 
-                if (label->rotate_flag)
+                if (rotate_flag)
                 {
                         lgl_template_frame_get_size (frame, &width, &height);
                         cairo_rotate (cr, -M_PI/2.0);
@@ -958,7 +828,7 @@ draw_markup_layer (glView  *view,
                 {
                         markup = (lglTemplateMarkup *)p->data;
 
-                        gl_cairo_markup_path (cr, markup, label);
+                        gl_cairo_markup_path (cr, markup, view->label);
 
                         cairo_stroke (cr);
                 }
@@ -987,10 +857,16 @@ static void
 draw_fg_layer (glView  *view,
                cairo_t *cr)
 {
+        const lglTemplate *template;
+        gboolean           rotate_flag;
+
 	g_return_if_fail (view && GL_IS_VIEW (view));
 	g_return_if_fail (view->label && GL_IS_LABEL (view->label));
 
-        gl_cairo_label_path (cr, view->label->template, view->label->rotate_flag, FALSE);
+        template    = gl_label_get_template (view->label);
+        rotate_flag = gl_label_get_rotate_flag (view->label);
+
+        gl_cairo_label_path (cr, template, rotate_flag, FALSE);
 
         cairo_set_line_width (cr, OUTLINE_WIDTH_PIXELS/(view->home_scale * view->zoom));
         cairo_set_source_rgb (cr, OUTLINE_RGB_ARGS);
@@ -1005,8 +881,9 @@ static void
 draw_highlight_layer (glView  *view,
                       cairo_t *cr)
 {
+	GList            *selection_list;
 	GList            *p_obj;
-	glViewObject     *view_object;
+	glLabelObject    *object;
 
 	g_return_if_fail (view && GL_IS_VIEW (view));
 
@@ -1014,13 +891,17 @@ draw_highlight_layer (glView  *view,
 
         cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
 
-	for (p_obj = view->selected_object_list; p_obj != NULL; p_obj = p_obj->next)
+        selection_list = gl_label_get_selection_list (view->label);
+
+	for (p_obj = selection_list; p_obj != NULL; p_obj = p_obj->next)
         {
-		view_object = GL_VIEW_OBJECT (p_obj->data);
+		object = GL_LABEL_OBJECT (p_obj->data);
 
-                gl_view_object_draw_handles (view_object, cr);
+                gl_label_object_draw_handles (object, cr);
 	}
 
+        g_list_free (selection_list);
+
         cairo_restore (cr);
 }
 
@@ -1173,22 +1054,22 @@ gl_view_object_create_mode (glView            *view,
 	switch (type)
         {
 	case GL_LABEL_OBJECT_BOX:
-		cursor = gl_view_box_get_create_cursor ();
+                cursor = gl_view_box_get_create_cursor ();
 		break;
 	case GL_LABEL_OBJECT_ELLIPSE:
-		cursor = gl_view_ellipse_get_create_cursor ();
+                cursor = gl_view_ellipse_get_create_cursor ();
 		break;
 	case GL_LABEL_OBJECT_LINE:
-		cursor = gl_view_line_get_create_cursor ();
+                cursor = gl_view_line_get_create_cursor ();
 		break;
 	case GL_LABEL_OBJECT_IMAGE:
-		cursor = gl_view_image_get_create_cursor ();
+                cursor = gl_view_image_get_create_cursor ();
 		break;
 	case GL_LABEL_OBJECT_TEXT:
-		cursor = gl_view_text_get_create_cursor ();
+                cursor = gl_view_text_get_create_cursor ();
 		break;
 	case GL_LABEL_OBJECT_BARCODE:
-		cursor = gl_view_barcode_get_create_cursor ();
+                cursor = gl_view_barcode_get_create_cursor ();
 		break;
 	default:
 		g_message ("Invalid label object type.");/*Should not happen!*/
@@ -1207,1400 +1088,6 @@ gl_view_object_create_mode (glView            *view,
 
 
 /*****************************************************************************/
-/* Select given object (adding to current selection).                        */
-/*****************************************************************************/
-void
-gl_view_select_object (glView       *view,
-		       glViewObject *view_object)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	select_object_real (view, view_object);
-
-	g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Unselect given object (removing from current selection).                  */
-/*****************************************************************************/
-void
-gl_view_unselect_object (glView       *view,
-			 glViewObject *view_object)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	unselect_object_real (view, view_object);
-
-	g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Select all items.                                                         */
-/*****************************************************************************/
-void
-gl_view_select_all (glView *view)
-{
-	GList *p, *p_next;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	/* 1st unselect anything already selected. */
-	for (p = view->selected_object_list; p != NULL; p = p_next) {
-		p_next = p->next;
-		unselect_object_real (view, GL_VIEW_OBJECT (p->data));
-	}
-
-	/* Finally select all objects. */
-	for (p = view->object_list; p != NULL; p = p->next) {
-		select_object_real (view, GL_VIEW_OBJECT (p->data));
-	}
-
-	g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Remove all selections                                                     */
-/*****************************************************************************/
-void
-gl_view_unselect_all (glView *view)
-{
-	GList *p;
-	GList *p_next;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	for (p = view->selected_object_list; p != NULL; p = p_next) {
-		p_next = p->next;
-		unselect_object_real (view, GL_VIEW_OBJECT (p->data));
-	}
-
-	g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Select all objects within given rectangular region (adding to selection). */
-/*****************************************************************************/
-void
-gl_view_select_region (glView        *view,
-                       glLabelRegion *region)
-{
-	GList         *p;
-	glViewObject  *view_object;
-	glLabelObject *object;
-        gdouble        r_x1, r_y1;
-        gdouble        r_x2, r_y2;
-        glLabelRegion  obj_extent;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-        r_x1 = MIN (region->x1, region->x2);
-        r_y1 = MIN (region->y1, region->y2);
-        r_x2 = MAX (region->x1, region->x2);
-        r_y2 = MAX (region->y1, region->y2);
-
-	for (p = view->object_list; p != NULL; p = p->next)
-        {
-		view_object = GL_VIEW_OBJECT(p->data);
-		if (!gl_view_is_object_selected (view, view_object))
-                {
-
-			object = gl_view_object_get_object (view_object);
-
-			gl_label_object_get_extent (object, &obj_extent);
-			if ((obj_extent.x1 >= r_x1) &&
-                            (obj_extent.x2 <= r_x2) &&
-                            (obj_extent.y1 >= r_y1) &&
-                            (obj_extent.y2 <= r_y2))
-                        {
-				select_object_real (view, view_object);
-			}
-
-		}
-	}
-
-	g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE. Select an object.                                                */
-/*---------------------------------------------------------------------------*/
-static void
-select_object_real (glView       *view,
-		    glViewObject *view_object)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-	g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
-
-	if (!gl_view_is_object_selected (view, view_object)) {
-		view->selected_object_list =
-		    g_list_append (view->selected_object_list, view_object);
-	}
-	gtk_widget_grab_focus (GTK_WIDGET (view->canvas));
-
-        gl_view_update (view);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE.  Un-select object.                                               */
-/*---------------------------------------------------------------------------*/
-static void
-unselect_object_real (glView       *view,
-		      glViewObject *view_object)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-	g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
-
-	view->selected_object_list =
-	    g_list_remove (view->selected_object_list, view_object);
-
-        gl_view_update (view);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE. Return object at (x,y).                                          */
-/*---------------------------------------------------------------------------*/
-static glViewObject *
-view_view_object_at (glView  *view,
-                     cairo_t *cr,
-                     gdouble  x,
-                     gdouble  y)
-{
-	GList            *p_obj;
-	glViewObject     *view_object;
-
-	g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
-
-	for (p_obj = g_list_last (view->object_list); p_obj != NULL; p_obj = p_obj->prev)
-        {
-
-		view_object = GL_VIEW_OBJECT (p_obj->data);
-
-                if (gl_view_object_at (view_object, cr, x, y))
-                {
-                        return view_object;
-                }
-
-	}
-
-        return NULL;
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE. Return object handle at (x,y).                                   */
-/*---------------------------------------------------------------------------*/
-static glViewObject *
-view_handle_at (glView             *view,
-                cairo_t            *cr,
-                gdouble             x,
-                gdouble             y,
-                glViewObjectHandle *handle)
-{
-	GList            *p_obj;
-	glViewObject     *view_object;
-
-	g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
-
-	for (p_obj = g_list_last (view->selected_object_list); p_obj != NULL; p_obj = p_obj->prev)
-        {
-
-		view_object = GL_VIEW_OBJECT (p_obj->data);
-
-                if ((*handle = gl_view_object_handle_at (view_object, cr, x, y)))
-                {
-                        return view_object;
-                }
-
-	}
-
-        return NULL;
-}
-
-
-/*****************************************************************************/
-/* Is the object in our current selection?                                   */
-/*****************************************************************************/
-gboolean
-gl_view_is_object_selected (glView       *view,
-			    glViewObject *view_object)
-{
-	gl_debug (DEBUG_VIEW, "");
-
-	g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
-	g_return_val_if_fail (GL_IS_VIEW_OBJECT (view_object), FALSE);
-
-	if (g_list_find (view->selected_object_list, view_object) == NULL) {
-		return FALSE;
-	}
-	return TRUE;
-}
-
-
-/*****************************************************************************/
-/* Is our current selection empty?                                           */
-/*****************************************************************************/
-gboolean
-gl_view_is_selection_empty (glView *view)
-{
-	gl_debug (DEBUG_VIEW, "");
-
-	g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
-
-	if (view->selected_object_list == NULL) {
-		return TRUE;
-	} else {
-		return FALSE;
-	}
-}
-
-
-/*****************************************************************************/
-/* Is our current selection atomic?  I.e. only one item selected.            */
-/*****************************************************************************/
-gboolean
-gl_view_is_selection_atomic (glView *view)
-{
-	gl_debug (DEBUG_VIEW, "");
-
-	g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
-
-	if (view->selected_object_list == NULL)
-		return FALSE;
-	if (view->selected_object_list->next == NULL)
-		return TRUE;
-	return FALSE;
-}
-
-
-/*****************************************************************************/
-/* Delete selected objects. (Bypass clipboard)                               */
-/*****************************************************************************/
-void
-gl_view_delete_selection (glView *view)
-{
-	GList         *object_list;
-	GList         *p;
-	GList         *p_next;
-	glViewObject  *view_object;
-	glLabelObject *object;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	object_list = view->selected_object_list;
-	view->selected_object_list = NULL;
-	g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
-
-	for (p = object_list; p != NULL; p = p_next) {
-		p_next = p->next;
-		view_object = GL_VIEW_OBJECT (p->data);
-		object = gl_view_object_get_object (view_object);
-                gl_label_object_remove (object);
-	}
-
-        g_list_free (object_list);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Get object property editor of first selected object.                      */
-/*****************************************************************************/
-GtkWidget *
-gl_view_get_editor (glView *view)
-{
-	glViewObject *view_object;
-	GtkWidget    *editor = NULL;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
-
-	if (!gl_view_is_selection_empty (view)) {
-
-		view_object = GL_VIEW_OBJECT(view->selected_object_list->data);
-		editor = gl_view_object_get_editor (view_object);
-
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-
-	return editor;
-}
-
-
-/*****************************************************************************/
-/* Raise selected items to top.                                              */
-/*****************************************************************************/
-void
-gl_view_raise_selection (glView *view)
-{
-	GList         *p;
-	glViewObject  *view_object;
-	glLabelObject *object;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	for (p = view->selected_object_list; p != NULL; p = p->next) {
-		view_object = GL_VIEW_OBJECT (p->data);
-		object = gl_view_object_get_object (view_object);
-		gl_label_object_raise_to_top (object);
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Lower selected items to bottom.                                           */
-/*****************************************************************************/
-void
-gl_view_lower_selection (glView *view)
-{
-	GList         *p;
-	glViewObject  *view_object;
-	glLabelObject *object;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	for (p = view->selected_object_list; p != NULL; p = p->next) {
-		view_object = GL_VIEW_OBJECT (p->data);
-		object = gl_view_object_get_object (view_object);
-		gl_label_object_lower_to_bottom (object);
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Rotate selected objects by given angle.                                   */
-/*****************************************************************************/
-void
-gl_view_rotate_selection (glView *view,
-			  gdouble theta_degs)
-{
-	GList         *p;
-	glViewObject  *view_object;
-	glLabelObject *object;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	for (p = view->selected_object_list; p != NULL; p = p->next) {
-		view_object = GL_VIEW_OBJECT (p->data);
-		object = gl_view_object_get_object (view_object);
-		gl_label_object_rotate (object, theta_degs);
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Rotate selected objects 90 degrees left.                                  */
-/*****************************************************************************/
-void
-gl_view_rotate_selection_left (glView *view)
-{
-	GList         *p;
-	glViewObject  *view_object;
-	glLabelObject *object;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	for (p = view->selected_object_list; p != NULL; p = p->next) {
-		view_object = GL_VIEW_OBJECT (p->data);
-		object = gl_view_object_get_object (view_object);
-		gl_label_object_rotate (object, -90.0);
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Rotate selected objects 90 degrees right.                                 */
-/*****************************************************************************/
-void
-gl_view_rotate_selection_right (glView *view)
-{
-	GList         *p;
-	glViewObject  *view_object;
-	glLabelObject *object;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	for (p = view->selected_object_list; p != NULL; p = p->next) {
-		view_object = GL_VIEW_OBJECT (p->data);
-		object = gl_view_object_get_object (view_object);
-		gl_label_object_rotate (object, 90.0);
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Flip selected objects horizontally.                                       */
-/*****************************************************************************/
-void
-gl_view_flip_selection_horiz (glView *view)
-{
-	GList         *p;
-	glViewObject  *view_object;
-	glLabelObject *object;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	for (p = view->selected_object_list; p != NULL; p = p->next) {
-		view_object = GL_VIEW_OBJECT (p->data);
-		object = gl_view_object_get_object (view_object);
-		gl_label_object_flip_horiz (object);
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Flip selected objects vertically.                                         */
-/*****************************************************************************/
-void
-gl_view_flip_selection_vert (glView *view)
-{
-	GList         *p;
-	glViewObject  *view_object;
-	glLabelObject *object;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	for (p = view->selected_object_list; p != NULL; p = p->next) {
-		view_object = GL_VIEW_OBJECT (p->data);
-		object = gl_view_object_get_object (view_object);
-		gl_label_object_flip_vert (object);
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Align selected objects to left most edge.                                 */
-/*****************************************************************************/
-void
-gl_view_align_selection_left (glView *view)
-{
-	GList         *p;
-	glViewObject  *view_object;
-	glLabelObject *object;
-	gdouble        dx, x1_min;
-        glLabelRegion  obj_extent;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	g_return_if_fail (!gl_view_is_selection_empty (view) &&
-			  !gl_view_is_selection_atomic (view));
-
-	/* find left most edge */
-	p = view->selected_object_list;
-	view_object = GL_VIEW_OBJECT (p->data);
-	object = gl_view_object_get_object (view_object);
-	gl_label_object_get_extent (object, &obj_extent);
-        x1_min = obj_extent.x1;
-	for (p = p->next; p != NULL; p = p->next)
-        {
-		view_object = GL_VIEW_OBJECT (p->data);
-		object = gl_view_object_get_object (view_object);
-		gl_label_object_get_extent (object, &obj_extent);
-		if ( obj_extent.x1 < x1_min ) x1_min = obj_extent.x1;
-	}
-
-	/* now adjust the object positions to line up the left edges */
-	for (p = view->selected_object_list; p != NULL; p = p->next)
-        {
-		view_object = GL_VIEW_OBJECT (p->data);
-		object = gl_view_object_get_object (view_object);
-		gl_label_object_get_extent (object, &obj_extent);
-		dx = x1_min - obj_extent.x1;
-		gl_label_object_set_position_relative (object, dx, 0.0);
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Align selected objects to right most edge.                                */
-/*****************************************************************************/
-void
-gl_view_align_selection_right (glView *view)
-{
-	GList         *p;
-	glViewObject  *view_object;
-	glLabelObject *object;
-	gdouble        dx, x2_max;
-        glLabelRegion  obj_extent;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	g_return_if_fail (!gl_view_is_selection_empty (view) &&
-			  !gl_view_is_selection_atomic (view));
-
-	/* find right most edge */
-	p = view->selected_object_list;
-	view_object = GL_VIEW_OBJECT (p->data);
-	object = gl_view_object_get_object (view_object);
-	gl_label_object_get_extent (object, &obj_extent);
-        x2_max = obj_extent.x2;
-	for (p = p->next; p != NULL; p = p->next)
-        {
-		view_object = GL_VIEW_OBJECT (p->data);
-		object = gl_view_object_get_object (view_object);
-		gl_label_object_get_extent (object, &obj_extent);
-		if ( obj_extent.x2 > x2_max ) x2_max = obj_extent.x2;
-	}
-
-	/* now adjust the object positions to line up the right edges */
-	for (p = view->selected_object_list; p != NULL; p = p->next)
-        {
-		view_object = GL_VIEW_OBJECT (p->data);
-		object = gl_view_object_get_object (view_object);
-		gl_label_object_get_extent (object, &obj_extent);
-		dx = x2_max - obj_extent.x2;
-		gl_label_object_set_position_relative (object, dx, 0.0);
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Align selected objects to horizontal center of objects.                   */
-/*****************************************************************************/
-void
-gl_view_align_selection_hcenter (glView *view)
-{
-	GList         *p;
-	glViewObject  *view_object;
-	glLabelObject *object;
-	gdouble        dx;
-	gdouble        dxmin;
-	gdouble        xsum, xavg;
-        glLabelRegion  obj_extent;
-	gdouble        xcenter;
-	gint           n;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	g_return_if_fail (!gl_view_is_selection_empty (view) &&
-			  !gl_view_is_selection_atomic (view));
-
-	/* find average center of objects */
-	xsum = 0.0;
-	n = 0;
-	for (p = view->selected_object_list; p != NULL; p = p->next)
-        {
-		view_object = GL_VIEW_OBJECT (p->data);
-		object = gl_view_object_get_object (view_object);
-		gl_label_object_get_extent (object, &obj_extent);
-		xsum += (obj_extent.x1 + obj_extent.x2) / 2.0;
-		n++;
-	}
-	xavg = xsum / n;
-
-	/* find center of object closest to average center */
-	p = view->selected_object_list;
-	view_object = GL_VIEW_OBJECT (p->data);
-	object = gl_view_object_get_object (view_object);
-	gl_label_object_get_extent (object, &obj_extent);
-	dxmin = fabs (xavg - (obj_extent.x1 + obj_extent.x2)/2.0);
-	xcenter = (obj_extent.x1 + obj_extent.x2)/2.0;
-	for (p = p->next; p != NULL; p = p->next)
-        {
-		view_object = GL_VIEW_OBJECT (p->data);
-		object = gl_view_object_get_object (view_object);
-		gl_label_object_get_extent (object, &obj_extent);
-		dx = fabs (xavg - (obj_extent.x1 + obj_extent.x2)/2.0);
-		if ( dx < dxmin )
-                {
-			dxmin = dx;
-			xcenter = (obj_extent.x1 + obj_extent.x2)/2.0;
-		}
-	}
-
-	/* now adjust the object positions to line up this center */
-	for (p = view->selected_object_list; p != NULL; p = p->next) {
-		view_object = GL_VIEW_OBJECT (p->data);
-		object = gl_view_object_get_object (view_object);
-		gl_label_object_get_extent (object, &obj_extent);
-		dx = xcenter - (obj_extent.x1 + obj_extent.x2)/2.0;
-		gl_label_object_set_position_relative (object, dx, 0.0);
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Align selected objects to top most edge.                                  */
-/*****************************************************************************/
-void
-gl_view_align_selection_top (glView *view)
-{
-	GList         *p;
-	glViewObject  *view_object;
-	glLabelObject *object;
-	gdouble        dy, y1_min;
-        glLabelRegion  obj_extent;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	g_return_if_fail (!gl_view_is_selection_empty (view) &&
-			  !gl_view_is_selection_atomic (view));
-
-	/* find top most edge */
-	p = view->selected_object_list;
-	view_object = GL_VIEW_OBJECT (p->data);
-	object = gl_view_object_get_object (view_object);
-	gl_label_object_get_extent (object, &obj_extent);
-        y1_min = obj_extent.y1;
-	for (p = p->next; p != NULL; p = p->next)
-        {
-		view_object = GL_VIEW_OBJECT (p->data);
-		object = gl_view_object_get_object (view_object);
-		gl_label_object_get_extent (object, &obj_extent);
-		if ( obj_extent.y1 < y1_min ) y1_min = obj_extent.y1;
-	}
-
-	/* now adjust the object positions to line up the top edges */
-	for (p = view->selected_object_list; p != NULL; p = p->next)
-        {
-		view_object = GL_VIEW_OBJECT (p->data);
-		object = gl_view_object_get_object (view_object);
-		gl_label_object_get_extent (object, &obj_extent);
-		dy = y1_min - obj_extent.y1;
-		gl_label_object_set_position_relative (object, 0.0, dy);
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Align selected objects to bottom most edge.                               */
-/*****************************************************************************/
-void
-gl_view_align_selection_bottom (glView *view)
-{
-	GList         *p;
-	glViewObject  *view_object;
-	glLabelObject *object;
-	gdouble        dy, y2_max;
-        glLabelRegion  obj_extent;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	g_return_if_fail (!gl_view_is_selection_empty (view) &&
-			  !gl_view_is_selection_atomic (view));
-
-	/* find bottom most edge */
-	p = view->selected_object_list;
-	view_object = GL_VIEW_OBJECT (p->data);
-	object = gl_view_object_get_object (view_object);
-	gl_label_object_get_extent (object, &obj_extent);
-        y2_max = obj_extent.y2;
-	for (p = p->next; p != NULL; p = p->next)
-        {
-		view_object = GL_VIEW_OBJECT (p->data);
-		object = gl_view_object_get_object (view_object);
-		gl_label_object_get_extent (object, &obj_extent);
-		if ( obj_extent.y2 > y2_max ) y2_max = obj_extent.y2;
-	}
-
-	/* now adjust the object positions to line up the bottom edges */
-	for (p = view->selected_object_list; p != NULL; p = p->next)
-        {
-		view_object = GL_VIEW_OBJECT (p->data);
-		object = gl_view_object_get_object (view_object);
-		gl_label_object_get_extent (object, &obj_extent);
-		dy = y2_max - obj_extent.y2;
-		gl_label_object_set_position_relative (object, 0.0, dy);
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Align selected objects to viertical center of objects.                    */
-/*****************************************************************************/
-void
-gl_view_align_selection_vcenter (glView *view)
-{
-	GList         *p;
-	glViewObject  *view_object;
-	glLabelObject *object;
-	gdouble        dy;
-	gdouble        dymin;
-	gdouble        ysum, yavg;
-        glLabelRegion  obj_extent;
-	gdouble        ycenter;
-	gint           n;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	g_return_if_fail (!gl_view_is_selection_empty (view) &&
-			  !gl_view_is_selection_atomic (view));
-
-	/* find average center of objects */
-	ysum = 0.0;
-	n = 0;
-	for (p = view->selected_object_list; p != NULL; p = p->next)
-        {
-		view_object = GL_VIEW_OBJECT (p->data);
-		object = gl_view_object_get_object (view_object);
-		gl_label_object_get_extent (object, &obj_extent);
-		ysum += (obj_extent.y1 + obj_extent.y2) / 2.0;
-		n++;
-	}
-	yavg = ysum / n;
-
-	/* find center of object closest to average center */
-	p = view->selected_object_list;
-	view_object = GL_VIEW_OBJECT (p->data);
-	object = gl_view_object_get_object (view_object);
-	gl_label_object_get_extent (object, &obj_extent);
-	dymin = fabs (yavg - (obj_extent.y1 + obj_extent.y2)/2.0);
-	ycenter = (obj_extent.y1 + obj_extent.y2)/2.0;
-	for (p = p->next; p != NULL; p = p->next)
-        {
-		view_object = GL_VIEW_OBJECT (p->data);
-		object = gl_view_object_get_object (view_object);
-		gl_label_object_get_extent (object, &obj_extent);
-		dy = fabs (yavg - (obj_extent.y1 + obj_extent.y2)/2.0);
-		if ( dy < dymin )
-                {
-			dymin = dy;
-			ycenter = (obj_extent.y1 + obj_extent.y2)/2.0;
-		}
-	}
-
-	/* now adjust the object positions to line up this center */
-	for (p = view->selected_object_list; p != NULL; p = p->next)
-        {
-		view_object = GL_VIEW_OBJECT (p->data);
-		object = gl_view_object_get_object (view_object);
-		gl_label_object_get_extent (object, &obj_extent);
-		dy = ycenter - (obj_extent.y1 + obj_extent.y2)/2.0;
-		gl_label_object_set_position_relative (object, 0.0, dy);
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Center selected objects to in center of label.                            */
-/*****************************************************************************/
-void
-gl_view_center_selection_horiz (glView *view)
-{
-	GList         *p;
-	glViewObject  *view_object;
-	glLabelObject *object;
-	gdouble        dx;
-	gdouble        x_label_center;
-	gdouble        x_obj_center;
-	glLabelRegion  obj_extent;
-	gdouble        w, h;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	g_return_if_fail (!gl_view_is_selection_empty (view));
-
-	gl_label_get_size (view->label, &w, &h);
-	x_label_center = w / 2.0;
-
-	/* adjust the object positions */
-	for (p = view->selected_object_list; p != NULL; p = p->next)
-        {
-		view_object = GL_VIEW_OBJECT (p->data);
-		object = gl_view_object_get_object (view_object);
-		gl_label_object_get_extent (object, &obj_extent);
-		x_obj_center = (obj_extent.x1 + obj_extent.x2) / 2.0;
-		dx = x_label_center - x_obj_center;
-		gl_label_object_set_position_relative (object, dx, 0.0);
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Center selected objects to in center of label.                            */
-/*****************************************************************************/
-void
-gl_view_center_selection_vert (glView *view)
-{
-	GList         *p;
-	glViewObject  *view_object;
-	glLabelObject *object;
-	gdouble        dy;
-	gdouble        y_label_center;
-	gdouble        y_obj_center;
-	glLabelRegion  obj_extent;
-	gdouble        w, h;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	g_return_if_fail (!gl_view_is_selection_empty (view));
-
-	gl_label_get_size (view->label, &w, &h);
-	y_label_center = h / 2.0;
-
-	/* adjust the object positions */
-	for (p = view->selected_object_list; p != NULL; p = p->next)
-        {
-		view_object = GL_VIEW_OBJECT (p->data);
-		object = gl_view_object_get_object (view_object);
-		gl_label_object_get_extent (object, &obj_extent);
-		y_obj_center = (obj_extent.y1 + obj_extent.y2) / 2.0;
-		dy = y_label_center - y_obj_center;
-		gl_label_object_set_position_relative (object, 0.0, dy);
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Move selected objects                                                     */
-/*****************************************************************************/
-void
-gl_view_move_selection (glView  *view,
-			gdouble  dx,
-			gdouble  dy)
-{
-	GList         *p;
-	glLabelObject *object;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	for (p = view->selected_object_list; p != NULL; p = p->next)
-        {
-
-		object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
-		gl_label_object_set_position_relative (object, dx, dy);
-
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Can text properties be set for selection?                                 */
-/*****************************************************************************/
-gboolean
-gl_view_can_selection_text (glView *view)
-{
-	GList         *p;
-	glLabelObject *object;
-
-	gl_debug (DEBUG_VIEW, "");
-
-	g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
-
-	for (p = view->selected_object_list; p != NULL; p = p->next)
-        {
-
-		object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
-		if (gl_label_object_can_text (object))
-                {
-			return TRUE;
-		}
-
-	}
-
-	return FALSE;
-}
-
-
-/*****************************************************************************/
-/* Set font family for all text contained in selected objects.               */
-/*****************************************************************************/
-void
-gl_view_set_selection_font_family (glView      *view,
-				   const gchar *font_family)
-{
-	GList         *p;
-	glLabelObject *object;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	for (p = view->selected_object_list; p != NULL; p = p->next) {
-
-		object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
-		gl_label_object_set_font_family (object, font_family);
-
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Set font size for all text contained in selected objects.                 */
-/*****************************************************************************/
-void
-gl_view_set_selection_font_size (glView  *view,
-				 gdouble  font_size)
-{
-	GList         *p;
-	glLabelObject *object;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	for (p = view->selected_object_list; p != NULL; p = p->next) {
-
-		object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
-		gl_label_object_set_font_size (object, font_size);
-
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Set font weight for all text contained in selected objects.               */
-/*****************************************************************************/
-void
-gl_view_set_selection_font_weight (glView      *view,
-				   PangoWeight  font_weight)
-{
-	GList         *p;
-	glLabelObject *object;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	for (p = view->selected_object_list; p != NULL; p = p->next) {
-
-		object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
-		gl_label_object_set_font_weight (object, font_weight);
-
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Set font italic flag for all text contained in selected objects.          */
-/*****************************************************************************/
-void
-gl_view_set_selection_font_italic_flag (glView   *view,
-					gboolean  font_italic_flag)
-{
-	GList         *p;
-	glLabelObject *object;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	for (p = view->selected_object_list; p != NULL; p = p->next) {
-
-		object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
-		gl_label_object_set_font_italic_flag (object, font_italic_flag);
-
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Set text alignment for all text contained in selected objects.            */
-/*****************************************************************************/
-void
-gl_view_set_selection_text_alignment (glView            *view,
-				      PangoAlignment     text_alignment)
-{
-	GList         *p;
-	glLabelObject *object;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	for (p = view->selected_object_list; p != NULL; p = p->next) {
-
-		object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
-		gl_label_object_set_text_alignment (object, text_alignment);
-
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Set text line spacing for all text contained in selected objects.         */
-/*****************************************************************************/
-void
-gl_view_set_selection_text_line_spacing (glView  *view,
-				         gdouble  text_line_spacing)
-{
-	GList         *p;
-	glLabelObject *object;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	for (p = view->selected_object_list; p != NULL; p = p->next) {
-
-		object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
-		gl_label_object_set_text_line_spacing (object, text_line_spacing);
-
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Set text color for all text contained in selected objects.                */
-/*****************************************************************************/
-void
-gl_view_set_selection_text_color (glView      *view,
-				  glColorNode *text_color_node)
-{
-	GList         *p;
-	glLabelObject *object;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	for (p = view->selected_object_list; p != NULL; p = p->next) {
-
-		object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
-		gl_label_object_set_text_color (object, text_color_node);
-
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Can fill properties be set for selection?                                 */
-/*****************************************************************************/
-gboolean
-gl_view_can_selection_fill (glView *view)
-{
-	GList         *p;
-	glLabelObject *object;
-
-	gl_debug (DEBUG_VIEW, "");
-
-	g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
-
-	for (p = view->selected_object_list; p != NULL; p = p->next) {
-
-		object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
-		if (gl_label_object_can_fill (object)) {
-			return TRUE;
-		}
-
-	}
-
-	return FALSE;
-}
-
-
-/*****************************************************************************/
-/* Set fill color for all selected objects.                                  */
-/*****************************************************************************/
-void
-gl_view_set_selection_fill_color (glView      *view,
-				  glColorNode *fill_color_node)
-{
-	GList         *p;
-	glLabelObject *object;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	for (p = view->selected_object_list; p != NULL; p = p->next) {
-
-		object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
-		gl_label_object_set_fill_color (object, fill_color_node);
-
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Can line color properties be set for selection?                           */
-/*****************************************************************************/
-gboolean
-gl_view_can_selection_line_color (glView *view)
-{
-	GList         *p;
-	glLabelObject *object;
-
-	gl_debug (DEBUG_VIEW, "");
-
-	g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
-
-	for (p = view->selected_object_list; p != NULL; p = p->next) {
-
-		object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
-		if (gl_label_object_can_line_color (object)) {
-			return TRUE;
-		}
-
-	}
-
-	return FALSE;
-}
-
-
-/*****************************************************************************/
-/* Set line color for all selected objects.                                  */
-/*****************************************************************************/
-void
-gl_view_set_selection_line_color (glView      *view,
-				  glColorNode *line_color_node)
-{
-	GList         *p;
-	glLabelObject *object;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	for (p = view->selected_object_list; p != NULL; p = p->next) {
-
-		object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
-		gl_label_object_set_line_color (object, line_color_node);
-
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* Can line width properties be set for selection?                           */
-/*****************************************************************************/
-gboolean
-gl_view_can_selection_line_width (glView *view)
-{
-	GList         *p;
-	glLabelObject *object;
-
-	gl_debug (DEBUG_VIEW, "");
-
-	g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
-
-	for (p = view->selected_object_list; p != NULL; p = p->next) {
-
-		object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
-		if (gl_label_object_can_line_width (object)) {
-			return TRUE;
-		}
-
-	}
-
-	return FALSE;
-}
-
-
-/*****************************************************************************/
-/* Set line width for all selected objects.                                  */
-/*****************************************************************************/
-void
-gl_view_set_selection_line_width (glView  *view,
-				  gdouble  line_width)
-{
-	GList         *p;
-	glLabelObject *object;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	for (p = view->selected_object_list; p != NULL; p = p->next) {
-
-		object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
-		gl_label_object_set_line_width (object, line_width);
-
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* "Cut" selected items and place in clipboard selections.                   */
-/*****************************************************************************/
-void
-gl_view_cut (glView *view)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	gl_view_copy (view);
-	gl_view_delete_selection (view);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* "Copy" selected items to clipboard selections.                            */
-/*****************************************************************************/
-void
-gl_view_copy (glView *view)
-{
-	GList         *p;
-	glViewObject  *view_object;
-	glLabelObject *object;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	if (view->selected_object_list) {
-
-		if ( view->selection_data ) {
-			g_object_unref (view->selection_data);
-		}
-		view->selection_data = GL_LABEL(gl_label_new ());
-		gl_label_set_template (view->selection_data, view->label->template);
-		gl_label_set_rotate_flag (view->selection_data, view->label->rotate_flag);
-
-		for (p = view->selected_object_list; p != NULL; p = p->next) {
-
-			view_object = GL_VIEW_OBJECT (p->data);
-			object = gl_view_object_get_object (view_object);
-
-			gl_label_object_dup (object, view->selection_data);
-
-		}
-
-		gtk_selection_owner_set (view->invisible,
-					 clipboard_atom, GDK_CURRENT_TIME);
-		view->have_selection = TRUE;
-
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
-/* "Paste" from private clipboard selection.                                 */
-/*****************************************************************************/
-void
-gl_view_paste (glView *view)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	gtk_selection_convert (GTK_WIDGET (view->invisible),
-			       clipboard_atom, GDK_SELECTION_TYPE_STRING,
-			       GDK_CURRENT_TIME);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*****************************************************************************/
 /* Zoom in one "notch"                                                       */
 /*****************************************************************************/
 void
@@ -2805,434 +1292,6 @@ gl_view_is_zoom_min (glView *view)
 
 
 /*---------------------------------------------------------------------------*/
-/* PRIVATE.  Handle "selection-clear" signal.                                */
-/*---------------------------------------------------------------------------*/
-static void
-selection_clear_cb (GtkWidget         *widget,
-		    GdkEventSelection *event,
-		    glView            *view)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	view->have_selection = FALSE;
-	g_object_unref (view->selection_data);
-	view->selection_data = NULL;
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE.  Handle "selection-get" signal.                                  */
-/*---------------------------------------------------------------------------*/
-static void
-selection_get_cb (GtkWidget        *widget,
-		  GtkSelectionData *sd,
-		  guint             info,
-		  guint             time,
-		  glView           *view)
-{
-	gchar            *buffer;
-	glXMLLabelStatus  status;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	if (view->have_selection) {
-
-		buffer = gl_xml_label_save_buffer (view->selection_data,
-						   &status);
-		gtk_selection_data_set (sd,
-					GDK_SELECTION_TYPE_STRING, 8,
-					(guchar *)buffer, strlen (buffer));
-		g_free (buffer);
-	}
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* PRIVATE.  Handle "selection-received" signal.  (Result of Paste)          */
-/*---------------------------------------------------------------------------*/
-static void
-selection_received_cb (GtkWidget        *widget,
-		       GtkSelectionData *sd,
-		       guint             time,
-		       glView           *view)
-{
-	glLabel          *label = NULL;
-	glXMLLabelStatus  status;
-	GList            *p, *p_next;
-	glLabelObject    *object, *newobject;
-
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	if (gtk_selection_data_get_length (sd) < 0)
-        {
-		return;
-	}
-	if (gtk_selection_data_get_data_type (sd) != GDK_SELECTION_TYPE_STRING)
-        {
-		return;
-	}
-
-	gl_view_unselect_all (view);
-
-	label = gl_xml_label_open_buffer ((gchar *)gtk_selection_data_get_data (sd), &status);
-	for (p = label->objects; p != NULL; p = p_next)
-        {
-		p_next = p->next;
-
-		object = (glLabelObject *) p->data;
-		newobject = gl_label_object_dup (object, view->label);
-
-		gl_debug (DEBUG_VIEW, "object pasted");
-	}
-	g_object_unref (label);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/****************************************************************************/
-/* Set default font family.                                                 */
-/****************************************************************************/
-void
-gl_view_set_default_font_family (glView      *view,
-				 const gchar *font_family)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	if (view->default_font_family) {
-		g_free (view->default_font_family);
-	}
-	view->default_font_family = g_strdup (font_family);
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/****************************************************************************/
-/* Set default font size.                                                   */
-/****************************************************************************/
-void
-gl_view_set_default_font_size (glView  *view,
-			       gdouble  font_size)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	view->default_font_size = font_size;
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/****************************************************************************/
-/* Set default font weight.                                                 */
-/****************************************************************************/
-void
-gl_view_set_default_font_weight (glView      *view,
-				 PangoWeight  font_weight)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	view->default_font_weight = font_weight;
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/****************************************************************************/
-/* Set default font italic flag.                                            */
-/****************************************************************************/
-void
-gl_view_set_default_font_italic_flag (glView   *view,
-				      gboolean  font_italic_flag)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	view->default_font_italic_flag = font_italic_flag;
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/****************************************************************************/
-/* Set default text color.                                                  */
-/****************************************************************************/
-void
-gl_view_set_default_text_color (glView *view,
-				guint   text_color)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	view->default_text_color = text_color;
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/****************************************************************************/
-/* Set default text alignment.                                              */
-/****************************************************************************/
-void
-gl_view_set_default_text_alignment (glView           *view,
-				    PangoAlignment    text_alignment)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	view->default_text_alignment = text_alignment;
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/****************************************************************************/
-/* Set default text line spacing.                                           */
-/****************************************************************************/
-void
-gl_view_set_default_text_line_spacing (glView  *view,
-			               gdouble  text_line_spacing)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	view->default_text_line_spacing = text_line_spacing;
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/****************************************************************************/
-/* Set default line width.                                                  */
-/****************************************************************************/
-void
-gl_view_set_default_line_width (glView  *view,
-				gdouble  line_width)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	view->default_line_width = line_width;
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/****************************************************************************/
-/* Set default line color.                                                  */
-/****************************************************************************/
-void
-gl_view_set_default_line_color (glView *view,
-				guint   line_color)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	view->default_line_color = line_color;
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/****************************************************************************/
-/* Set default fill color.                                                  */
-/****************************************************************************/
-void
-gl_view_set_default_fill_color (glView *view,
-				guint   fill_color)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_if_fail (view && GL_IS_VIEW (view));
-
-	view->default_fill_color = fill_color;
-
-	gl_debug (DEBUG_VIEW, "END");
-}
-
-
-/****************************************************************************/
-/* Get default font family.                                                 */
-/****************************************************************************/
-gchar *
-gl_view_get_default_font_family (glView *view)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
-
-	gl_debug (DEBUG_VIEW, "END");
-
-	return g_strdup (view->default_font_family);
-}
-
-
-/****************************************************************************/
-/* Get default font size.                                                   */
-/****************************************************************************/
-gdouble
-gl_view_get_default_font_size (glView *view)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_val_if_fail (view && GL_IS_VIEW (view), 12.0);
-
-	gl_debug (DEBUG_VIEW, "END");
-
-	return view->default_font_size;
-}
-
-
-/****************************************************************************/
-/* Get default font weight.                                                 */
-/****************************************************************************/
-PangoWeight
-gl_view_get_default_font_weight (glView *view)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_val_if_fail (view && GL_IS_VIEW (view), PANGO_WEIGHT_NORMAL);
-
-	gl_debug (DEBUG_VIEW, "END");
-
-	return view->default_font_weight;
-}
-
-
-/****************************************************************************/
-/* Get default font italic flag.                                            */
-/****************************************************************************/
-gboolean
-gl_view_get_default_font_italic_flag (glView *view)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
-
-	gl_debug (DEBUG_VIEW, "END");
-
-	return view->default_font_italic_flag;
-}
-
-
-/****************************************************************************/
-/* Get default text color.                                                  */
-/****************************************************************************/
-guint
-gl_view_get_default_text_color (glView *view)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
-
-	gl_debug (DEBUG_VIEW, "END");
-
-	return view->default_text_color;
-}
-
-
-/****************************************************************************/
-/* Get default text alignment.                                              */
-/****************************************************************************/
-PangoAlignment
-gl_view_get_default_text_alignment (glView *view)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_val_if_fail (view && GL_IS_VIEW (view), PANGO_ALIGN_LEFT);
-
-	gl_debug (DEBUG_VIEW, "END");
-
-	return view->default_text_alignment;
-}
-
-
-/****************************************************************************/
-/* Get default text line spacing.                                           */
-/****************************************************************************/
-gdouble
-gl_view_get_default_text_line_spacing (glView *view)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_val_if_fail (view && GL_IS_VIEW (view), 1.0);
-
-	gl_debug (DEBUG_VIEW, "END");
-
-	return view->default_text_line_spacing;
-}
-
-
-/****************************************************************************/
-/* Get default line width.                                                  */
-/****************************************************************************/
-gdouble
-gl_view_get_default_line_width (glView *view)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_val_if_fail (view && GL_IS_VIEW (view), 1.0);
-
-	gl_debug (DEBUG_VIEW, "END");
-
-	return view->default_line_width;
-}
-
-
-/****************************************************************************/
-/* Get default line color.                                                  */
-/****************************************************************************/
-guint
-gl_view_get_default_line_color (glView *view)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
-
-	gl_debug (DEBUG_VIEW, "END");
-
-	return view->default_line_color;
-}
-
-
-/****************************************************************************/
-/* Get default fill color.                                                  */
-/****************************************************************************/
-guint
-gl_view_get_default_fill_color (glView *view)
-{
-	gl_debug (DEBUG_VIEW, "START");
-
-	g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
-
-	gl_debug (DEBUG_VIEW, "END");
-
-	return view->default_fill_color;
-}
-
-
-/*---------------------------------------------------------------------------*/
 /* PRIVATE.  Focus in event handler.                                         */
 /*---------------------------------------------------------------------------*/
 static gboolean
@@ -3293,7 +1352,7 @@ motion_notify_event_cb (glView            *view,
         gdouble             scale;
         gdouble             x, y;
         GdkCursor          *cursor;
-        glViewObjectHandle  handle;
+        glLabelObjectHandle handle;
 
         bin_window = gtk_layout_get_bin_window (GTK_LAYOUT (view->canvas));
         window = gtk_widget_get_window (view->canvas);
@@ -3327,12 +1386,12 @@ motion_notify_event_cb (glView            *view,
                 {
 
                 case GL_VIEW_IDLE:
-                        if ( gl_view_is_selection_atomic (view) &&
-                             view_handle_at (view, cr, event->x, event->y, &handle) )
+                        if ( gl_label_is_selection_atomic (view->label) &&
+                             gl_label_get_handle_at (view->label, cr, event->x, event->y, &handle) )
                         {
                                 cursor = gdk_cursor_new (GDK_CROSSHAIR);
                         }
-                        else if (view_view_object_at (view, cr, event->x, event->y))
+                        else if (gl_label_object_at (view->label, cr, event->x, event->y))
                         {
                                 cursor = gdk_cursor_new (GDK_FLEUR);
                         }
@@ -3358,7 +1417,7 @@ motion_notify_event_cb (glView            *view,
                         break;
 
                 case GL_VIEW_ARROW_MOVE:
-                        gl_view_move_selection (view,
+                        gl_label_move_selection (view->label,
                                                 (x - view->move_last_x),
                                                 (y - view->move_last_y));
                         view->move_last_x = x;
@@ -3366,12 +1425,7 @@ motion_notify_event_cb (glView            *view,
                         break;
 
                 case GL_VIEW_ARROW_RESIZE:
-                        gl_view_object_resize_event (view->resize_object,
-                                                     view->resize_handle,
-                                                     view->resize_honor_aspect,
-                                                     cr,
-                                                     event->x,
-                                                     event->y);
+                        resize_event (view, cr, event->x, event->y);
                         break;
 
                 default:
@@ -3449,8 +1503,8 @@ button_press_event_cb (glView            *view,
 	cairo_t            *cr;
         gdouble             scale;
         gdouble             x, y;
-        glViewObject       *view_object;
-        glViewObjectHandle  handle;
+        glLabelObject      *object;
+        glLabelObjectHandle handle;
 
         gtk_widget_grab_focus(GTK_WIDGET (view->canvas));
 
@@ -3479,36 +1533,36 @@ button_press_event_cb (glView            *view,
                 switch (view->mode)
                 {
                 case GL_VIEW_MODE_ARROW:
-                        if ( gl_view_is_selection_atomic (view) &&
-                             (view_object = view_handle_at (view, cr, event->x, event->y, &handle)) )
+                        if ( gl_label_is_selection_atomic (view->label) &&
+                             (object = gl_label_get_handle_at (view->label, cr, event->x, event->y, &handle)) )
                         {
-                                view->resize_object = view_object;
+                                view->resize_object = object;
                                 view->resize_handle = handle;
                                 view->resize_honor_aspect = event->state & GDK_CONTROL_MASK;
 
                                 view->state = GL_VIEW_ARROW_RESIZE;
                         }
-                        else if ((view_object = view_view_object_at (view, cr, event->x, event->y)))
+                        else if ((object = gl_label_object_at (view->label, cr, event->x, event->y)))
                         {
                                 if (event->state & GDK_CONTROL_MASK)
                                 {
-                                        if (gl_view_is_object_selected (view, view_object))
+                                        if (gl_label_object_is_selected (object))
                                         {
                                                 /* Un-selecting a selected item */
-                                                gl_view_unselect_object (view, view_object);
+                                                gl_label_unselect_object (view->label, object);
                                         } else {
                                                 /* Add to current selection */
-                                                gl_view_select_object (view, view_object);
+                                                gl_label_select_object (view->label, object);
                                         }
                                 }
                                 else
                                 {
-                                        if (!gl_view_is_object_selected (view, view_object))
+                                        if (!gl_label_object_is_selected (object))
                                         {
                                                 /* remove any selections before adding */
-                                                gl_view_unselect_all (view);
+                                                gl_label_unselect_all (view->label);
                                                 /* Add to current selection */
-                                                gl_view_select_object (view, view_object);
+                                                gl_label_select_object (view->label, object);
                                         }
                                 }
                                 view->move_last_x = x;
@@ -3520,7 +1574,7 @@ button_press_event_cb (glView            *view,
                         {
                                 if (!(event->state & GDK_CONTROL_MASK))
                                 {
-                                        gl_view_unselect_all (view);
+                                        gl_label_unselect_all (view->label);
                                 }
 
                                 view->select_region_visible = TRUE;
@@ -3654,7 +1708,7 @@ button_release_event_cb (glView            *view,
                                 view->select_region.x2 = x;
                                 view->select_region.y2 = y;
 
-                                gl_view_select_region (view, &view->select_region);
+                                gl_label_select_region (view->label, &view->select_region);
 
                                 view->state = GL_VIEW_IDLE;
                                 break;
@@ -3698,6 +1752,8 @@ button_release_event_cb (glView            *view,
                         cursor = gdk_cursor_new (GDK_LEFT_PTR);
                         gdk_window_set_cursor (window, cursor);
                         gdk_cursor_unref (cursor);
+
+                        gl_label_select_object (view->label, view->create_object);
                         break;
 
 
@@ -3734,23 +1790,23 @@ key_press_event_cb (glView            *view,
 
                 case GDK_Left:
                 case GDK_KP_Left:
-                        gl_view_move_selection (view, -1.0 / (view->zoom), 0.0);
+                        gl_label_move_selection (view->label, -1.0 / (view->zoom), 0.0);
                         break;
                 case GDK_Up:
                 case GDK_KP_Up:
-                        gl_view_move_selection (view, 0.0, -1.0 / (view->zoom));
+                        gl_label_move_selection (view->label, 0.0, -1.0 / (view->zoom));
                         break;
                 case GDK_Right:
                 case GDK_KP_Right:
-                        gl_view_move_selection (view, 1.0 / (view->zoom), 0.0);
+                        gl_label_move_selection (view->label, 1.0 / (view->zoom), 0.0);
                         break;
                 case GDK_Down:
                 case GDK_KP_Down:
-                        gl_view_move_selection (view, 0.0, 1.0 / (view->zoom));
+                        gl_label_move_selection (view->label, 0.0, 1.0 / (view->zoom));
                         break;
                 case GDK_Delete:
                 case GDK_KP_Delete:
-                        gl_view_delete_selection (view);
+                        gl_label_delete_selection (view->label);
                         cursor = gdk_cursor_new (GDK_LEFT_PTR);
                         gdk_window_set_cursor (window, cursor);
                         gdk_cursor_unref (cursor);
@@ -3764,6 +1820,184 @@ key_press_event_cb (glView            *view,
 }
 
 
+/*---------------------------------------------------------------------------*/
+/* PRIVATE.  Resize object.                                                  */
+/*---------------------------------------------------------------------------*/
+static void
+resize_event (glView             *view,
+              cairo_t            *cr,
+              gdouble             x,
+              gdouble             y)
+{
+        cairo_matrix_t matrix;
+        gdouble        x0, y0, x1, y1, x2, y2;
+        gdouble        w, h;
+        gdouble        dx=0, dy=0;
+
+	gl_debug (DEBUG_VIEW, "x,y world = %g, %g", x, y);
+
+        /*
+         * Change to item relative coordinates
+         */
+        cairo_save (cr);
+        gl_label_object_get_position (view->resize_object, &x0, &y0);
+        cairo_translate (cr, x0, y0);
+        gl_label_object_get_matrix (view->resize_object, &matrix);
+        cairo_transform (cr, &matrix);
+
+        /*
+         * Initialize origin and 2 corners in object relative coordinates.
+         */
+        x0 = 0.0;
+        y0 = 0.0;
+
+        x1 = 0.0;
+        y1 = 0.0;
+
+        gl_label_object_get_size (view->resize_object, &x2, &y2);
+
+	gl_debug (DEBUG_VIEW, "x0,y0 object = %g, %g", x0, y0);
+	gl_debug (DEBUG_VIEW, "x1,y1 object = %g, %g", x1, y1);
+	gl_debug (DEBUG_VIEW, "x2,y2 object = %g, %g", x2, y2);
+
+        /*
+         * Translate x,y into object relative coordinates.
+         */
+        cairo_device_to_user (cr, &x, &y);
+
+	gl_debug (DEBUG_VIEW, "x,y object = %g, %g", x, y);
+        
+        /*
+         * Get new size
+         */
+        switch (view->resize_handle)
+        {
+
+        case GL_LABEL_OBJECT_HANDLE_NW:
+                w = MAX (x2 - x, 0);
+                h = MAX (y2 - y, 0);
+                break;
+
+        case GL_LABEL_OBJECT_HANDLE_N:
+                w = x2 - x1;
+                h = MAX (y2 - y, 0);
+                break;
+
+        case GL_LABEL_OBJECT_HANDLE_NE:
+                w = MAX (x - x1, 0);
+                h = MAX (y2 - y, 0);
+                break;
+
+        case GL_LABEL_OBJECT_HANDLE_E:
+                w = MAX (x - x1, 0);
+                h = y2 - y1;
+                break;
+
+        case GL_LABEL_OBJECT_HANDLE_SE:
+                w = MAX (x - x1, 0);
+                h = MAX (y - y1, 0);
+                break;
+
+        case GL_LABEL_OBJECT_HANDLE_S:
+                w = x2 - x1;
+                h = MAX (y - y1, 0);
+                break;
+
+        case GL_LABEL_OBJECT_HANDLE_SW:
+                w = MAX (x2 - x, 0);
+                h = MAX (y - y1, 0);
+                break;
+
+        case GL_LABEL_OBJECT_HANDLE_W:
+                w = MAX (x2 - x, 0);
+                h = y2 - y1;
+                break;
+        case GL_LABEL_OBJECT_HANDLE_P1:
+                x1 = x;
+                y1 = y;
+                dx = (x2 - x);
+                dy = (y2 - y);
+                x0 = x0 + x1;
+                y0 = y0 + y1;
+                break;
+
+        case GL_LABEL_OBJECT_HANDLE_P2:
+                dx = x - x1;
+                dy = y - y1;
+                x0 = x0 + x1;
+                y0 = y0 + y1;
+                break;
+
+        default:
+                g_print ("Invalid handle.\n");  /* Should not happen! */
+
+        }
+        if ( (view->resize_handle != GL_LABEL_OBJECT_HANDLE_P1) &&
+             (view->resize_handle != GL_LABEL_OBJECT_HANDLE_P2) )
+        {
+                if ( view->resize_honor_aspect )
+                {
+                        gl_label_object_set_size_honor_aspect (view->resize_object, w, h);
+                }
+                else
+                {
+                        gl_label_object_set_size (view->resize_object, w, h);
+                }
+
+                /*
+                 * Query the new size in case it was constrained.
+                 */
+                gl_label_object_get_size (view->resize_object, &w, &h);
+
+                /*
+                 * Get new position
+                 */
+                switch (view->resize_handle)
+                {
+
+                case GL_LABEL_OBJECT_HANDLE_NW:
+                        x0 += x2 - w;
+                        y0 += y2 - h;
+                        break;
+
+                case GL_LABEL_OBJECT_HANDLE_N:
+                case GL_LABEL_OBJECT_HANDLE_NE:
+                        /* x unchanged */
+                        y0 += y2 - h;
+                        break;
+
+                case GL_LABEL_OBJECT_HANDLE_E:
+                case GL_LABEL_OBJECT_HANDLE_SE:
+                case GL_LABEL_OBJECT_HANDLE_S:
+                        /* unchanged */
+                        break;
+
+                case GL_LABEL_OBJECT_HANDLE_SW:
+                case GL_LABEL_OBJECT_HANDLE_W:
+                        x0 += x2 - w;
+                        /* y unchanged */
+                        break;
+
+                default:
+                        g_print ("Invalid handle.\n");  /* Should not happen! */
+                }
+        }
+        else
+        {
+                gl_label_object_set_size (view->resize_object, dx, dy);
+        }
+
+        /*
+         * Put new origin back into world coordinates and set.
+         */
+        cairo_user_to_device (cr, &x0, &y0);
+        cairo_restore (cr);
+        cairo_device_to_user (cr, &x0, &y0);
+        gl_label_object_set_position (view->resize_object, x0, y0);
+}
+
+
+
 
 /*
  * Local Variables:       -- emacs
diff --git a/src/view.h b/src/view.h
index 54d4b4f..249db66 100644
--- a/src/view.h
+++ b/src/view.h
@@ -51,8 +51,7 @@ typedef enum {
 typedef struct _glView      glView;
 typedef struct _glViewClass glViewClass;
 
-#include "view-object.h"
-#include "color.h"
+
 
 struct _glView {
 	GtkVBox            parent_widget;
@@ -86,48 +85,20 @@ struct _glView {
         glLabelRegion      select_region;
 
         /* GL_VIEW_ARROW_RESIZE state */
-        glViewObject      *resize_object;
-        glViewObjectHandle resize_handle;
-        gboolean           resize_honor_aspect;
+        glLabelObject      *resize_object;
+        glLabelObjectHandle resize_handle;
+        gboolean            resize_honor_aspect;
 
         /* GL_VIEW_CREATE_DRAG state */
         glLabelObject     *create_object;
         gdouble            create_x0;
         gdouble            create_y0;
 
-	GList             *object_list;           /* glViewObjects */
-	GList             *selected_object_list;  /* glViewObjects */
-
-	/* Clipboard selection stuff */
-	gint               have_selection;
-	glLabel           *selection_data;
-	GtkWidget         *invisible;
-
-	/* Default object text properties */
-	gchar             *default_font_family;
-	gdouble            default_font_size;
-	PangoWeight        default_font_weight;
-	gboolean           default_font_italic_flag;
-	guint              default_text_color;
-	PangoAlignment     default_text_alignment;
-	gdouble            default_text_line_spacing;
-
-	/* Default object line properties */
-	gdouble            default_line_width;
-	guint              default_line_color;
-	
-	/* Default object fill properties */
-	guint              default_fill_color;
-
 };
 
 struct _glViewClass {
 	GtkVBoxClass      parent_class;
 
-	/* Selection changed signal */
-	void (*selection_changed) (glView   *view,
-				   gpointer  user_data);
-
 	/* Signal to launch a context menu */
 	void (*context_menu_activate) (glView   *view,
 				       gint      button,
@@ -178,111 +149,6 @@ void       gl_view_object_create_mode      (glView            *view,
 					    glLabelObjectType  type);
 
 
-void       gl_view_select_object           (glView            *view,
-					    glViewObject      *view_object);
-
-void       gl_view_unselect_object         (glView            *view,
-					    glViewObject      *view_object);
-
-void       gl_view_select_all              (glView            *view);
-
-void       gl_view_unselect_all            (glView            *view);
-
-void       gl_view_select_region           (glView            *view,
-                                            glLabelRegion     *region);
-
-gboolean   gl_view_is_object_selected      (glView            *view,
-					    glViewObject      *view_object);
-
-gboolean   gl_view_is_selection_empty      (glView            *view);
-
-gboolean   gl_view_is_selection_atomic     (glView            *view);
-
-void       gl_view_delete_selection        (glView            *view);
-
-GtkWidget *gl_view_get_editor              (glView            *view);
-
-void       gl_view_raise_selection         (glView            *view);
-
-void       gl_view_lower_selection         (glView            *view);
-
-void       gl_view_rotate_selection        (glView            *view,
-					    gdouble            theta_degs);
-
-void       gl_view_rotate_selection_left   (glView            *view);
-
-void       gl_view_rotate_selection_right  (glView            *view);
-
-void       gl_view_flip_selection_horiz    (glView            *view);
-
-void       gl_view_flip_selection_vert     (glView            *view);
-
-void       gl_view_align_selection_left    (glView            *view);
-
-void       gl_view_align_selection_right   (glView            *view);
-
-void       gl_view_align_selection_hcenter (glView            *view);
-
-void       gl_view_align_selection_top     (glView            *view);
-
-void       gl_view_align_selection_bottom  (glView            *view);
-
-void       gl_view_align_selection_vcenter (glView            *view);
-
-void       gl_view_center_selection_horiz  (glView            *view);
-
-void       gl_view_center_selection_vert   (glView            *view);
-
-void       gl_view_move_selection          (glView            *view,
-					    gdouble            dx,
-					    gdouble            dy);
-
-gboolean   gl_view_can_selection_text             (glView           *view);
-
-void       gl_view_set_selection_font_family      (glView           *view,
-						   const gchar      *font_family);
-
-void       gl_view_set_selection_font_size        (glView           *view,
-						   gdouble           font_size);
-
-void       gl_view_set_selection_font_weight      (glView           *view,
-						   PangoWeight      font_weight);
-
-void       gl_view_set_selection_text_line_spacing (glView           *view,
-						   gdouble           text_line_spacing);
-
-void       gl_view_set_selection_font_italic_flag (glView           *view,
-						   gboolean          font_italic_flag);
-
-void       gl_view_set_selection_text_alignment   (glView           *view,
-						   PangoAlignment    text_alignment);
-
-void       gl_view_set_selection_text_color       (glView           *view,
-						   glColorNode      *text_color_node);
-
-gboolean   gl_view_can_selection_fill             (glView           *view);
-
-void       gl_view_set_selection_fill_color       (glView           *view,
-						   glColorNode      *fill_color);
-
-gboolean   gl_view_can_selection_line_color       (glView           *view);
-
-void       gl_view_set_selection_line_color       (glView           *view,
-						   glColorNode      *line_color_node);
-
-gboolean   gl_view_can_selection_line_width       (glView           *view);
-
-void       gl_view_set_selection_line_width       (glView           *view,
-						   gdouble           line_width);
-
-
-void       gl_view_cut                     (glView            *view);
-
-void       gl_view_copy                    (glView            *view);
-
-void       gl_view_paste                   (glView            *view);
-
-
 void       gl_view_zoom_in                 (glView            *view);
 
 void       gl_view_zoom_out                (glView            *view);
@@ -299,57 +165,6 @@ gboolean   gl_view_is_zoom_max             (glView            *view);
 gboolean   gl_view_is_zoom_min             (glView            *view);
 
 
-void       gl_view_set_default_font_family      (glView            *view,
-						 const gchar       *font_family);
-
-void       gl_view_set_default_font_size        (glView            *view,
-						 gdouble            font_size);
-
-void       gl_view_set_default_font_weight      (glView            *view,
-						 PangoWeight        font_weight);
-
-void       gl_view_set_default_font_italic_flag (glView            *view,
-					         gboolean           font_italic_flag);
-
-void       gl_view_set_default_text_color       (glView            *view,
-						 guint              text_color);
-
-void       gl_view_set_default_text_alignment   (glView            *view,
-						 PangoAlignment     text_alignment);
-
-void       gl_view_set_default_line_width       (glView            *view,
-						 gdouble            line_width);
-
-void       gl_view_set_default_line_color       (glView            *view,
-						 guint              line_color);
-
-void       gl_view_set_default_fill_color       (glView            *view,
-						 guint              fill_color);
-void       gl_view_set_default_text_line_spacing (glView            *view,
-						 gdouble            text_line_spacing);
-
-
-
-gchar           *gl_view_get_default_font_family      (glView            *view);
-
-gdouble          gl_view_get_default_font_size        (glView            *view);
-
-PangoWeight      gl_view_get_default_font_weight      (glView            *view);
-
-gboolean         gl_view_get_default_font_italic_flag (glView            *view);
-
-guint            gl_view_get_default_text_color       (glView            *view);
-
-PangoAlignment   gl_view_get_default_text_alignment   (glView            *view);
-
-gdouble          gl_view_get_default_text_line_spacing (glView            *view);
-
-gdouble          gl_view_get_default_line_width       (glView            *view);
-
-guint            gl_view_get_default_line_color       (glView            *view);
-
-guint            gl_view_get_default_fill_color       (glView            *view);
-
 
 
 G_END_DECLS
diff --git a/src/window.c b/src/window.c
index 6520c37..42d24a5 100644
--- a/src/window.c
+++ b/src/window.c
@@ -68,7 +68,7 @@ static gboolean window_delete_event_cb (glWindow      *window,
 					GdkEvent      *event,
 					gpointer       user_data);
 
-static void     selection_changed_cb   (glView        *view,
+static void     selection_changed_cb   (glLabel       *label,
 					glWindow      *window);
 
 static void   context_menu_activate_cb (glView       *view,
@@ -340,6 +340,8 @@ gl_window_set_label (glWindow    *window,
 	g_return_if_fail (GL_IS_WINDOW (window));
 	g_return_if_fail (GL_IS_LABEL (label));
 
+        window->label = label;
+
 	gl_label_clear_modified (label);
 
 	set_window_title (window, label);
@@ -350,7 +352,7 @@ gl_window_set_label (glWindow    *window,
 	}
 
 	window->view = gl_view_new (label);
-	gtk_box_pack_start (GTK_BOX (window->hbox), window->view,TRUE, TRUE, 0);
+	gtk_box_pack_start (GTK_BOX (window->hbox), window->view, TRUE, TRUE, 0);
 
 	gtk_widget_show_all (window->view);
 
@@ -370,15 +372,15 @@ gl_window_set_label (glWindow    *window,
 
 	gl_ui_update_all (window->ui, GL_VIEW(window->view));
 
-	gl_ui_property_bar_set_view (window->property_bar, GL_VIEW(window->view));
-	gl_ui_sidebar_set_view (window->sidebar, GL_VIEW(window->view));
+	gl_ui_property_bar_set_label (window->property_bar, window->label);
+	gl_ui_sidebar_set_label (window->sidebar, window->label);
 
 	string = g_strdup_printf ("%3.0f%%",
 				  100.0*gl_view_get_zoom (GL_VIEW(window->view)));
 	gtk_label_set_text (GTK_LABEL(window->zoom_info), string);
 	g_free (string);
 
-	g_signal_connect (G_OBJECT(window->view), "selection_changed",
+	g_signal_connect (G_OBJECT(window->label), "selection_changed",
 			  G_CALLBACK(selection_changed_cb), window);
 
 	g_signal_connect (G_OBJECT(window->view), "context_menu_activate",
@@ -471,15 +473,15 @@ window_delete_event_cb (glWindow      *window,
 /** PRIVATE.  View "selection state changed" callback.                       */
 /*---------------------------------------------------------------------------*/
 static void 
-selection_changed_cb (glView   *view,
+selection_changed_cb (glLabel  *label,
 		      glWindow *window)
 {
 	gl_debug (DEBUG_WINDOW, "START");
 
-	g_return_if_fail (view && GL_IS_VIEW (view));
+	g_return_if_fail (label && GL_IS_LABEL (label));
 	g_return_if_fail (window && GL_IS_WINDOW (window));
 
-	gl_ui_update_selection_verbs (window->ui, view);
+	gl_ui_update_selection_verbs (window->ui, GL_VIEW (window->view));
 
 	gl_debug (DEBUG_WINDOW, "END");
 }
@@ -499,7 +501,7 @@ context_menu_activate_cb (glView       *view,
         g_return_if_fail (view && GL_IS_VIEW (view));
 	g_return_if_fail (window && GL_IS_WINDOW (window));
 
-        if (gl_view_is_selection_empty (view)) {
+        if (gl_label_is_selection_empty (view->label)) {
 
 		gtk_menu_popup (GTK_MENU (window->empty_selection_context_menu),
 				NULL, NULL, NULL, NULL, button, activate_time);
diff --git a/src/window.h b/src/window.h
index 999bd4c..5c030f4 100644
--- a/src/window.h
+++ b/src/window.h
@@ -50,10 +50,11 @@ struct _glWindow {
 
 	GtkUIManager            *ui;
 
-	GtkWidget               *view;
-
 	GtkWidget               *hbox;
 
+	glLabel                 *label;
+
+	GtkWidget               *view;
 	glUIPropertyBar         *property_bar;
 	glUISidebar             *sidebar;
 
diff --git a/src/xml-label.c b/src/xml-label.c
index cf3c436..5d0fe9c 100644
--- a/src/xml-label.c
+++ b/src/xml-label.c
@@ -1151,10 +1151,11 @@ static xmlDocPtr
 xml_label_to_doc (glLabel          *label,
 		  glXMLLabelStatus *status)
 {
-        lglUnits    units;
-	xmlDocPtr   doc;
-	xmlNsPtr    ns;
-	glMerge    *merge;
+        lglUnits           units;
+	xmlDocPtr          doc;
+	xmlNsPtr           ns;
+        const lglTemplate *template;
+	glMerge           *merge;
 
 	gl_debug (DEBUG_XML, "START");
 
@@ -1169,7 +1170,8 @@ xml_label_to_doc (glLabel          *label,
 	ns = xmlNewNs (doc->xmlRootNode, (xmlChar *)LGL_XML_NAME_SPACE, NULL);
 	xmlSetNs (doc->xmlRootNode, ns);
 
-	lgl_xml_template_create_template_node (label->template, doc->xmlRootNode, ns);
+        template = gl_label_get_template (label);
+	lgl_xml_template_create_template_node (template, doc->xmlRootNode, ns);
 
 	xml_create_objects (doc->xmlRootNode, ns, label);
 
@@ -1198,16 +1200,21 @@ xml_create_objects (xmlNodePtr  root,
 		    glLabel    *label)
 {
 	xmlNodePtr     node;
+        gboolean       rotate_flag;
+        const GList   *object_list;
 	GList         *p;
 	glLabelObject *object;
 
 	gl_debug (DEBUG_XML, "START");
 
+        rotate_flag = gl_label_get_rotate_flag (label);
+        object_list = gl_label_get_object_list (label);
+
 	node = xmlNewChild (root, ns, (xmlChar *)"Objects", NULL);
 	lgl_xml_set_prop_string (node, "id", "0");
-	lgl_xml_set_prop_boolean (node, "rotate", label->rotate_flag);
+	lgl_xml_set_prop_boolean (node, "rotate", rotate_flag);
 
-	for (p = label->objects; p != NULL; p = p->next) {
+	for (p = (GList *)object_list; p != NULL; p = p->next) {
 
 		object = GL_LABEL_OBJECT(p->data);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]