summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Van Berkom <tristan.van.berkom@gmail.com>2011-01-27 16:30:15 +0900
committerTristan Van Berkom <tristan.van.berkom@gmail.com>2011-01-27 16:30:15 +0900
commit78c0b1da9fda1f17a8368027fbb2827cce654648 (patch)
tree3ecdf5c19eeae1f27f3a50207e44d9bef90410b4
parente2dfd6296d92b43483f050001314affc422987dd (diff)
downloadgtk+-builder-details.tar.gz
Added <mime-types> and <patterns> parsing support to GtkFileFilter.builder-details
-rw-r--r--gtk/gtkbuilder.c6
-rw-r--r--gtk/gtkfilefilter.c194
2 files changed, 198 insertions, 2 deletions
diff --git a/gtk/gtkbuilder.c b/gtk/gtkbuilder.c
index b658654abf..9f875b4339 100644
--- a/gtk/gtkbuilder.c
+++ b/gtk/gtkbuilder.c
@@ -232,7 +232,11 @@
* <link linkend="GtkActionGroup-BUILDER-UI">GtkActionGroup</link>.
* <link linkend="GtkMenuItem-BUILDER-UI">GtkMenuItem</link>,
* <link linkend="GtkAssistant-BUILDER-UI">GtkAssistant</link>,
- * <link linkend="GtkScale-BUILDER-UI">GtkScale</link>.
+ * <link linkend="GtkScale-BUILDER-UI">GtkScale</link>,
+ * <link linkend="GtkComboBoxText-BUILDER-UI">GtkComboBoxText</link>,
+ * <link linkend="GtkRecentFilter-BUILDER-UI">GtkRecentFilter</link>,
+ * <link linkend="GtkFileFilter-BUILDER-UI">GtkFileFilter</link>,
+ * <link linkend="GtkTextTagTable-BUILDER-UI">GtkTextTagTable</link>.
* </para>
* </refsect2>
*/
diff --git a/gtk/gtkfilefilter.c b/gtk/gtkfilefilter.c
index cdfb6cbedf..21b44c053a 100644
--- a/gtk/gtkfilefilter.c
+++ b/gtk/gtkfilefilter.c
@@ -39,6 +39,33 @@
* see gtk_file_chooser_add_filter(), but it is also possible
* to manually use a filter on a file with gtk_file_filter_filter().
*
+ * <refsect2 id="GtkFileFilter-BUILDER-UI">
+ * <title>GtkFileFilter as GtkBuildable</title>
+ * <para>
+ * The GtkFileFilter implementation of the GtkBuildable interface
+ * supports adding rules using the &lt;mime-types&gt, &lt;patterns&gt and
+ * &lt;applications&gt elements and listing the rules within. Specifying
+ * a &lt;mime-type&gt or &lt;pattern&gt is the same
+ * as calling gtk_recent_filter_add_mime_type() or gtk_recent_filter_add_pattern()
+ *
+ * <example>
+ * <title>A UI definition fragment specifying GtkFileFilter rules</title>
+ * <programlisting><![CDATA[
+ * <object class="GtkFileFilter">
+ * <mime-types>
+ * <mime-type>text/plain</mime-type>
+ * <mime-type>image/*</mime-type>
+ * </mime-types>
+ * <patterns>
+ * <pattern>*.txt</pattern>
+ * <pattern>*.png</pattern>
+ * </patterns>
+ * </object>
+ * ]]></programlisting>
+ * </example>
+ * </para>
+ * </refsect2>
+ *
* @see_also: #GtkFileChooser
*/
@@ -48,6 +75,7 @@
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "gtkfilefilter.h"
+#include "gtkbuildable.h"
#include "gtkintl.h"
#include "gtkprivate.h"
@@ -100,7 +128,22 @@ struct _FilterRule
static void gtk_file_filter_finalize (GObject *object);
-G_DEFINE_TYPE (GtkFileFilter, gtk_file_filter, G_TYPE_INITIALLY_UNOWNED)
+static void gtk_file_filter_buildable_init (GtkBuildableIface *iface);
+static gboolean gtk_file_filter_buildable_custom_tag_start (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ GMarkupParser *parser,
+ gpointer *data);
+static void gtk_file_filter_buildable_custom_tag_end (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ gpointer *data);
+
+G_DEFINE_TYPE_WITH_CODE (GtkFileFilter, gtk_file_filter, G_TYPE_INITIALLY_UNOWNED,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
+ gtk_file_filter_buildable_init))
static void
gtk_file_filter_init (GtkFileFilter *object)
@@ -153,6 +196,155 @@ gtk_file_filter_finalize (GObject *object)
G_OBJECT_CLASS (gtk_file_filter_parent_class)->finalize (object);
}
+/*
+ * GtkBuildable implementation
+ */
+static void
+gtk_file_filter_buildable_init (GtkBuildableIface *iface)
+{
+ iface->custom_tag_start = gtk_file_filter_buildable_custom_tag_start;
+ iface->custom_tag_end = gtk_file_filter_buildable_custom_tag_end;
+}
+
+typedef enum {
+ PARSE_MIME_TYPES,
+ PARSE_PATTERNS
+} ParserType;
+
+typedef struct {
+ GtkFileFilter *filter;
+ ParserType type;
+ GString *string;
+ gboolean parsing;
+} SubParserData;
+
+static void
+parser_start_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **names,
+ const gchar **values,
+ gpointer user_data,
+ GError **error)
+{
+ SubParserData *parser_data = (SubParserData*)user_data;
+
+ if (strcmp (element_name, "mime-types") == 0)
+ return;
+ else if (strcmp (element_name, "mime-type") == 0)
+ {
+ parser_data->parsing = TRUE;
+ return;
+ }
+ else if (strcmp (element_name, "patterns") == 0)
+ return;
+ else if (strcmp (element_name, "pattern") == 0)
+ {
+ parser_data->parsing = TRUE;
+ return;
+ }
+ else
+ g_warning ("Unsupported tag for GtkFileFilter: %s\n", element_name);
+}
+
+static void
+parser_text_element (GMarkupParseContext *context,
+ const gchar *text,
+ gsize text_len,
+ gpointer user_data,
+ GError **error)
+{
+ SubParserData *parser_data = (SubParserData*)user_data;
+
+ if (parser_data->parsing)
+ g_string_append_len (parser_data->string, text, text_len);
+}
+
+static void
+parser_end_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ gpointer user_data,
+ GError **error)
+{
+ SubParserData *parser_data = (SubParserData*)user_data;
+
+ if (parser_data->string)
+ {
+ switch (parser_data->type)
+ {
+ case PARSE_MIME_TYPES:
+ gtk_file_filter_add_mime_type (parser_data->filter, parser_data->string->str);
+ break;
+ case PARSE_PATTERNS:
+ gtk_file_filter_add_pattern (parser_data->filter, parser_data->string->str);
+ break;
+ default:
+ break;
+ }
+ }
+
+ g_string_set_size (parser_data->string, 0);
+ parser_data->parsing = FALSE;
+}
+
+static const GMarkupParser sub_parser =
+ {
+ parser_start_element,
+ parser_end_element,
+ parser_text_element,
+ };
+
+static gboolean
+gtk_file_filter_buildable_custom_tag_start (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ GMarkupParser *parser,
+ gpointer *data)
+{
+ SubParserData *parser_data = NULL;
+
+ if (strcmp (tagname, "mime-types") == 0)
+ {
+ parser_data = g_slice_new0 (SubParserData);
+ parser_data->string = g_string_new ("");
+ parser_data->type = PARSE_MIME_TYPES;
+ parser_data->filter = GTK_FILE_FILTER (buildable);
+
+ *parser = sub_parser;
+ *data = parser_data;
+ }
+ else if (strcmp (tagname, "patterns") == 0)
+ {
+ parser_data = g_slice_new0 (SubParserData);
+ parser_data->string = g_string_new ("");
+ parser_data->type = PARSE_PATTERNS;
+ parser_data->filter = GTK_FILE_FILTER (buildable);
+
+ *parser = sub_parser;
+ *data = parser_data;
+ }
+
+ return parser_data != NULL;
+}
+
+static void
+gtk_file_filter_buildable_custom_tag_end (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ gpointer *data)
+{
+ if (strcmp (tagname, "mime-types") == 0 ||
+ strcmp (tagname, "patterns") == 0)
+ {
+ SubParserData *parser_data = (SubParserData*)data;
+
+ g_string_free (parser_data->string, TRUE);
+ g_slice_free (SubParserData, parser_data);
+ }
+}
+
+
/**
* gtk_file_filter_new:
*