Index: gtk/gtkbuilderprivate.h
===================================================================
--- gtk/gtkbuilderprivate.h	(revisione 20824)
+++ gtk/gtkbuilderprivate.h	(copia locale)
@@ -96,6 +96,11 @@ typedef struct {
   const gchar *filename;
   GSList *finalizers;
   GSList *custom_finalizers;
+
+  GSList *requested_objects; /* NULL if all the objects are requested */
+  gboolean inside_requested_object;
+  gint requested_object_level;
+  gint cur_object_level;
 } ParserData;
 
 typedef GType (*GTypeGetFunc) (void);
@@ -105,6 +110,7 @@ void _gtk_builder_parser_parse_buffer (G
                                        const gchar *filename,
                                        const gchar *buffer,
                                        gsize length,
+                                       gchar **requested_objs,
                                        GError **error);
 GObject * _gtk_builder_construct (GtkBuilder *builder,
                                   ObjectInfo *info,
Index: gtk/gtkbuilder.c
===================================================================
--- gtk/gtkbuilder.c	(revisione 20824)
+++ gtk/gtkbuilder.c	(copia locale)
@@ -658,7 +658,70 @@ gtk_builder_add_from_file (GtkBuilder   
 
   g_return_val_if_fail (GTK_IS_BUILDER (builder), 0);
   g_return_val_if_fail (filename != NULL, 0);
-  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, 0);
+
+  tmp_error = NULL;
+
+  if (!g_file_get_contents (filename, &buffer, &length, &tmp_error))
+    {
+      g_propagate_error (error, tmp_error);
+      return 0;
+    }
+  
+  g_free (builder->priv->filename);
+  builder->priv->filename = g_strdup (filename);
+
+  _gtk_builder_parser_parse_buffer (builder, filename,
+                                    buffer, length,
+                                    NULL,
+                                    &tmp_error);
+
+  g_free (buffer);
+
+  if (tmp_error != NULL)
+    {
+      g_propagate_error (error, tmp_error);
+      return 0;
+    }
+
+  return 1;
+}
+
+/**
+ * gtk_builder_add_objects_from_file:
+ * @builder: a #GtkBuilder
+ * @filename: the name of the file to parse
+ * @object_ids: nul-terminated array of objects to build
+ * @error: return location for an error, or %NULL
+ *
+ * Parses a file containing a <link linkend="BUILDER-UI">GtkBuilder 
+ * UI definition</link> building only the requested objects and merges
+ * them with the current contents of @builder. 
+ *
+ * <note><para>
+ * If you are adding an object that depends on an object that is not 
+ * its child (for instance a #GtkTreeView that depends on its
+ * #GtkTreeModel), you have to explicitely list all of them in @object_ids. 
+ * </para></note>
+ *
+ * Returns: A positive value on success, 0 if an error occurred
+ *
+ * Since: 2.14
+ **/
+guint
+gtk_builder_add_objects_from_file (GtkBuilder   *builder,
+                                   const gchar  *filename,
+                                   gchar       **object_ids,
+                                   GError      **error)
+{
+  gchar *buffer;
+  gsize length;
+  GError *tmp_error;
+
+  g_return_val_if_fail (GTK_IS_BUILDER (builder), 0);
+  g_return_val_if_fail (filename != NULL, 0);
+  g_return_val_if_fail (object_ids != NULL && object_ids[0] != NULL, 0);
+  g_return_val_if_fail (error == NULL || *error == NULL, 0);
 
   tmp_error = NULL;
 
@@ -673,6 +736,7 @@ gtk_builder_add_from_file (GtkBuilder   
 
   _gtk_builder_parser_parse_buffer (builder, filename,
                                     buffer, length,
+                                    object_ids,
                                     &tmp_error);
 
   g_free (buffer);
@@ -695,7 +759,7 @@ gtk_builder_add_from_file (GtkBuilder   
  *
  * Parses a string containing a <link linkend="BUILDER-UI">GtkBuilder 
  * UI definition</link> and merges it with the current contents of @builder. 
- * 
+ *
  * Returns: A positive value on success, 0 if an error occurred
  *
  * Since: 2.12
@@ -710,7 +774,7 @@ gtk_builder_add_from_string (GtkBuilder 
 
   g_return_val_if_fail (GTK_IS_BUILDER (builder), 0);
   g_return_val_if_fail (buffer != NULL, 0);
-  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, 0);
 
   tmp_error = NULL;
 
@@ -719,6 +783,7 @@ gtk_builder_add_from_string (GtkBuilder 
 
   _gtk_builder_parser_parse_buffer (builder, "<input>",
                                     buffer, length,
+                                    NULL,
                                     &tmp_error);
   if (tmp_error != NULL)
     {
@@ -730,6 +795,61 @@ gtk_builder_add_from_string (GtkBuilder 
 }
 
 /**
+ * gtk_builder_add_objects_from_string:
+ * @builder: a #GtkBuilder
+ * @buffer: the string to parse
+ * @length: the length of @buffer (may be -1 if @buffer is nul-terminated)
+ * @object_ids: nul-terminated array of objects to build
+ * @error: return location for an error, or %NULL
+ *
+ * Parses a string containing a <link linkend="BUILDER-UI">GtkBuilder 
+ * UI definition</link> building only the requested objects and merges
+ * them with the current contents of @builder. 
+ * 
+ * <note><para>
+ * If you are adding an object that depends on an object that is not 
+ * its child (for instance a #GtkTreeView that depends on its
+ * #GtkTreeModel), you have to explicitely list all of them in @object_ids. 
+ * </para></note>
+ *
+ * Returns: A positive value on success, 0 if an error occurred
+ *
+ * Since: 2.14
+ **/
+guint
+gtk_builder_add_objects_from_string (GtkBuilder   *builder,
+                                     const gchar  *buffer,
+                                     gsize         length,
+                                     gchar       **object_ids,
+                                     GError      **error)
+{
+  GError *tmp_error;
+
+  g_return_val_if_fail (GTK_IS_BUILDER (builder), 0);
+  g_return_val_if_fail (buffer != NULL, 0);
+  g_return_val_if_fail (object_ids != NULL && object_ids[0] != NULL, 0);
+  g_return_val_if_fail (error == NULL || *error == NULL, 0);
+
+  tmp_error = NULL;
+
+  g_free (builder->priv->filename);
+  builder->priv->filename = g_strdup (".");
+
+  _gtk_builder_parser_parse_buffer (builder, "<input>",
+                                    buffer, length,
+                                    object_ids,
+                                    &tmp_error);
+
+  if (tmp_error != NULL)
+    {
+      g_propagate_error (error, tmp_error);
+      return 0;
+    }
+
+  return 1;
+}
+
+/**
  * gtk_builder_get_object:
  * @builder: a #GtkBuilder
  * @name: name of object to get
Index: gtk/gtkbuilder.h
===================================================================
--- gtk/gtkbuilder.h	(revisione 20824)
+++ gtk/gtkbuilder.h	(copia locale)
@@ -100,6 +100,15 @@ guint        gtk_builder_add_from_string
                                                   const gchar   *buffer,
                                                   gsize          length,
                                                   GError       **error);
+guint        gtk_builder_add_objects_from_file   (GtkBuilder    *builder,
+                                                  const gchar   *filename,
+                                                  gchar        **object_ids,
+                                                  GError       **error);
+guint        gtk_builder_add_objects_from_string (GtkBuilder    *builder,
+                                                  const gchar   *buffer,
+                                                  gsize          length,
+                                                  gchar        **object_ids,
+                                                  GError       **error);
 GObject*     gtk_builder_get_object              (GtkBuilder    *builder,
                                                   const gchar   *name);
 GSList*      gtk_builder_get_objects             (GtkBuilder    *builder);
Index: gtk/tests/builder.c
===================================================================
--- gtk/tests/builder.c	(revisione 20824)
+++ gtk/tests/builder.c	(copia locale)
@@ -622,7 +622,8 @@ test_list_store (void)
   g_free (lastname);
   g_assert (age == 50);
   g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter) == FALSE);
-  
+  g_object_unref (builder);
+
   builder = builder_new_from_string (buffer3, -1, NULL);
   store = gtk_builder_get_object (builder, "liststore1");
   g_assert (gtk_tree_model_get_n_columns (GTK_TREE_MODEL (store)) == 3);
@@ -2102,7 +2103,6 @@ test_pango_attributes (void)
 
 }
 
-
 static void
 test_requires (void)
 {
@@ -2124,6 +2124,51 @@ test_requires (void)
   g_error_free (error);
 }
 
+static void
+test_add_objects (void)
+{
+  GtkBuilder *builder;
+  GError *error;
+  gint ret;
+  GObject *obj;
+  gchar *objects[2] = {"mainbox", NULL}; 
+  const gchar buffer[] =
+    "<interface>"
+    "  <object class=\"GtkWindow\" id=\"window\">"
+    "    <child>"
+    "      <object class=\"GtkVBox\" id=\"mainbox\">"
+    "        <property name=\"visible\">True</property>"
+    "        <child>"
+    "          <object class=\"GtkLabel\" id=\"label1\">"
+    "            <property name=\"visible\">True</property>"
+    "            <property name=\"label\" translatable=\"no\">first label</property>"
+    "          </object>"
+    "        </child>"
+    "        <child>"
+    "          <object class=\"GtkLabel\" id=\"label2\">"
+    "            <property name=\"visible\">True</property>"
+    "            <property name=\"label\" translatable=\"no\">second label</property>"
+    "          </object>"
+    "          <packing>"
+    "            <property name=\"position\">1</property>"
+    "          </packing>"
+    "        </child>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+    "<interface/>";
+
+  error = NULL;
+  builder = gtk_builder_new ();
+  ret = gtk_builder_add_objects_from_string (builder, buffer, -1, objects, &error);
+  g_assert (ret);
+  g_assert (error == NULL);
+  obj = gtk_builder_get_object (builder, "window");  
+  g_assert (!obj);
+  obj = gtk_builder_get_object (builder, "mainbox");  
+  g_assert (GTK_IS_WIDGET (obj));
+  g_object_unref (builder);
+}
 
 static void 
 test_file (const gchar *filename)
@@ -2209,6 +2254,7 @@ main (int argc, char **argv)
   g_test_add_func ("/Builder/IconFactory", test_icon_factory);
   g_test_add_func ("/Builder/PangoAttributes", test_pango_attributes);
   g_test_add_func ("/Builder/Requires", test_requires);
+  g_test_add_func ("/Builder/AddObjects", test_add_objects);
 
   return g_test_run();
 }
Index: gtk/gtk.symbols
===================================================================
--- gtk/gtk.symbols	(revisione 20824)
+++ gtk/gtk.symbols	(copia locale)
@@ -445,6 +445,8 @@ gtk_buildable_set_buildable_property
 #if IN_FILE(__GTK_BUILDER_C__)
 gtk_builder_add_from_file
 gtk_builder_add_from_string
+gtk_builder_add_objects_from_file
+gtk_builder_add_objects_from_string
 gtk_builder_error_quark
 gtk_builder_get_object
 gtk_builder_get_objects
Index: gtk/gtkbuilderparser.c
===================================================================
--- gtk/gtkbuilderparser.c	(revisione 20824)
+++ gtk/gtkbuilderparser.c	(copia locale)
@@ -282,6 +282,21 @@ parse_requires (ParserData   *data,
   req_info->tag.name = element_name;
 }
 
+static gboolean
+is_requested_object (const gchar *object,
+                     ParserData  *data)
+{
+  GSList *l;
+
+  for (l = data->requested_objects; l; l = l->next)
+    {
+      if (strcmp (l->data, object) == 0)
+        return TRUE;
+    }
+
+  return FALSE;
+}
+
 static void
 parse_object (ParserData   *data,
               const gchar  *element_name,
@@ -346,6 +361,25 @@ parse_object (ParserData   *data,
       return;
     }
 
+  ++data->cur_object_level;
+
+  /* check if we reached a requested object (if it is specified) */
+  if (data->requested_objects && !data->inside_requested_object)
+    {
+      if (is_requested_object (object_id, data))
+        {
+          data->requested_object_level = data->cur_object_level;
+
+          GTK_NOTE (BUILDER, g_print ("requested object \"%s\" found at level %d\n",
+                                      object_id,
+                                      data->requested_object_level));
+
+          data->inside_requested_object = TRUE;
+        }
+      else
+        return;
+    }
+
   object_info = g_slice_new0 (ObjectInfo);
   object_info->class_name = object_class;
   object_info->id = object_id;
@@ -801,6 +835,11 @@ start_element (GMarkupParseContext *cont
     parse_requires (data, element_name, names, values, error);
   else if (strcmp (element_name, "object") == 0)
     parse_object (data, element_name, names, values, error);
+  else if (data->requested_objects && !data->inside_requested_object)
+    {
+      /* If outside a requested object, simply ignore this tag */
+      return;
+    }
   else if (strcmp (element_name, "child") == 0)
     parse_child (data, element_name, names, values, error);
   else if (strcmp (element_name, "property") == 0)
@@ -910,11 +949,32 @@ end_element (GMarkupParseContext *contex
 			 GTK_MAJOR_VERSION, GTK_MINOR_VERSION);
 	}
     }
+  else if (strcmp (element_name, "interface") == 0)
+    {
+    }
+  else if (data->requested_objects && !data->inside_requested_object)
+    {
+      /* If outside a requested object, simply ignore this tag */
+      return;
+    }
   else if (strcmp (element_name, "object") == 0)
     {
       ObjectInfo *object_info = state_pop_info (data, ObjectInfo);
       ChildInfo* child_info = state_peek_info (data, ChildInfo);
 
+      if (data->requested_objects && data->inside_requested_object &&
+          (data->cur_object_level == data->requested_object_level))
+        {
+          GTK_NOTE (BUILDER, g_print ("requested object end found at level %d\n",
+                                      data->requested_object_level));
+
+          data->inside_requested_object = FALSE;
+        }
+
+      --data->cur_object_level;
+
+      g_assert (data->cur_object_level >= 0);
+
       object_info->object = builder_construct (data, object_info, error);
       if (!object_info->object)
 	{
@@ -976,9 +1036,6 @@ end_element (GMarkupParseContext *contex
       object_info->signals =
         g_slist_prepend (object_info->signals, signal_info);
     }
-  else if (strcmp (element_name, "interface") == 0)
-    {
-    }
   else if (strcmp (element_name, "placeholder") == 0)
     {
     }
@@ -1056,6 +1113,7 @@ _gtk_builder_parser_parse_buffer (GtkBui
                                   const gchar  *filename,
                                   const gchar  *buffer,
                                   gsize         length,
+                                  gchar       **requested_objs,
                                   GError      **error)
 {
   ParserData *data;
@@ -1066,13 +1124,31 @@ _gtk_builder_parser_parse_buffer (GtkBui
   data->filename = filename;
   data->domain = g_strdup (gtk_builder_get_translation_domain (builder));
 
+  data->requested_objects = NULL;
+  if (requested_objs)
+    {
+      gint i;
+
+      data->inside_requested_object = FALSE;
+      for (i = 0; requested_objs[i]; ++i)
+        {
+          data->requested_objects = g_slist_prepend (data->requested_objects,
+                                                     g_strdup (requested_objs[i]));	
+        }
+    }
+  else
+    {
+      /* get all the objects */
+      data->inside_requested_object = TRUE;
+    }
+
   data->ctx = g_markup_parse_context_new (&parser, 
                                           G_MARKUP_TREAT_CDATA_AS_TEXT, 
                                           data, NULL);
 
   if (!g_markup_parse_context_parse (data->ctx, buffer, length, error))
     goto out;
-  
+
   _gtk_builder_finish (builder);
 
   /* Custom parser_finished */
@@ -1103,6 +1179,8 @@ _gtk_builder_parser_parse_buffer (GtkBui
   g_slist_foreach (data->custom_finalizers, (GFunc)free_subparser, NULL);
   g_slist_free (data->custom_finalizers);
   g_slist_free (data->finalizers);
+  g_slist_foreach (data->requested_objects, (GFunc) g_free, NULL);
+  g_slist_free (data->requested_objects);
   g_free (data->domain);
   g_markup_parse_context_free (data->ctx);
   g_free (data);
Index: docs/reference/gtk/gtk-sections.txt
===================================================================
--- docs/reference/gtk/gtk-sections.txt	(revisione 20824)
+++ docs/reference/gtk/gtk-sections.txt	(copia locale)
@@ -478,6 +478,8 @@ GtkBuilderError
 gtk_builder_new
 gtk_builder_add_from_file
 gtk_builder_add_from_string
+gtk_builder_add_objects_from_file
+gtk_builder_add_objects_from_string
 gtk_builder_get_object
 gtk_builder_get_objects
 gtk_builder_connect_signals
