Commit a6a7b7e9 authored by Tristan Van Berkom's avatar Tristan Van Berkom

Added GtkBuildable support for adding rules to GtkRecentFilter

Also added documentation section for this. Since the GtkRecentFilter
documentation was still living in sgml, as a side-effect I migrated these
docs to the gtkrecentfilter.[ch] sources.
parent d7b71be4
<!-- ##### SECTION Title ##### -->
GtkRecentFilter
<!-- ##### SECTION Short_Description ##### -->
A filter for selecting a subset of recently used files
<!-- ##### SECTION Long_Description ##### -->
<para>
A #GtkRecentFilter can be used to restrict the files being shown
in a #GtkRecentChooser. Files can be filtered based on their name
(with gtk_recent_filter_add_pattern()), on their mime type (with
gtk_file_filter_add_mime_type()), on the application that has
registered them (with gtk_recent_filter_add_application()), or by
a custom filter function (with gtk_recent_filter_add_custom()).
</para>
<para>
Filtering by mime type handles aliasing and subclassing of mime
types; e.g. a filter for text/plain also matches a file with mime
type application/rtf, since application/rtf is a subclass of text/plain.
Note that #GtkRecentFilter allows wildcards for the subtype of a
mime type, so you can e.g. filter for image/*.
</para>
<para>
Normally, filters are used by adding them to a #GtkRecentChooser,
see gtk_recent_chooser_add_filter(), but it is also possible to
manually use a filter on a file with gtk_recent_filter_filter().
</para>
<para>
Recently used files are supported since GTK+ 2.10.
</para>
<!-- ##### SECTION See_Also ##### -->
<para>
#GtkRecentChooser
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### SECTION Image ##### -->
<!-- ##### STRUCT GtkRecentFilter ##### -->
<para>
The <structname>GtkRecentFilter</structname> struct contains
only private fields and should not be directly accessed.
</para>
<!-- ##### STRUCT GtkRecentFilterInfo ##### -->
<para>
A <structname>GtkRecentFilterInfo</structname> struct is used
to pass information about the tested file to gtk_recent_filter_filter().
</para>
@contains: Flags indicating which of the following fields need
are filled
@uri: the URI of the file being tested
@display_name: the string that will be used to display the file
in the recent chooser
@mime_type: the mime type of the file
@applications: the list of applications that have registered the file
@groups: the groups to which the file belongs to
@age: the number of days elapsed since the file has been registered
<!-- ##### ENUM GtkRecentFilterFlags ##### -->
<para>
These flags indicate what parts of a #GtkRecentFilterInfo struct
are filled or need to be filled.
</para>
@GTK_RECENT_FILTER_URI: the URI of the file being tested
@GTK_RECENT_FILTER_DISPLAY_NAME: the string that will be used to
display the file in the recent chooser
@GTK_RECENT_FILTER_MIME_TYPE: the mime type of the file
@GTK_RECENT_FILTER_APPLICATION: the list of applications that have
registered the file
@GTK_RECENT_FILTER_GROUP: the groups to which the file belongs to
@GTK_RECENT_FILTER_AGE: the number of days elapsed since the file
has been registered
<!-- ##### USER_FUNCTION GtkRecentFilterFunc ##### -->
<para>
The type of function that is used with custom filters,
see gtk_recent_filter_add_custom().
</para>
@filter_info: a #GtkRecentFilterInfo that is filled according
to the @needed flags passed to gtk_recent_filter_add_custom()
@user_data: user data passed to gtk_recent_filter_add_custom()
@Returns: %TRUE if the file should be displayed
<!-- ##### FUNCTION gtk_recent_filter_new ##### -->
<para>
</para>
@void:
@Returns:
<!-- ##### FUNCTION gtk_recent_filter_get_name ##### -->
<para>
</para>
@filter:
@Returns:
<!-- ##### FUNCTION gtk_recent_filter_set_name ##### -->
<para>
</para>
@filter:
@name:
<!-- ##### FUNCTION gtk_recent_filter_add_mime_type ##### -->
<para>
</para>
@filter:
@mime_type:
<!-- ##### FUNCTION gtk_recent_filter_add_pattern ##### -->
<para>
</para>
@filter:
@pattern:
<!-- ##### FUNCTION gtk_recent_filter_add_pixbuf_formats ##### -->
<para>
</para>
@filter:
<!-- ##### FUNCTION gtk_recent_filter_add_application ##### -->
<para>
</para>
@filter:
@application:
<!-- ##### FUNCTION gtk_recent_filter_add_group ##### -->
<para>
</para>
@filter:
@group:
<!-- ##### FUNCTION gtk_recent_filter_add_age ##### -->
<para>
</para>
@filter:
@days:
<!-- ##### FUNCTION gtk_recent_filter_add_custom ##### -->
<para>
</para>
@filter:
@needed:
@func:
@data:
@data_destroy:
<!-- ##### FUNCTION gtk_recent_filter_get_needed ##### -->
<para>
</para>
@filter:
@Returns:
<!-- ##### FUNCTION gtk_recent_filter_filter ##### -->
<para>
</para>
@filter:
@filter_info:
@Returns:
......@@ -18,15 +18,86 @@
* Boston, MA 02111-1307, USA.
*/
/**
* SECTION:gtkrecentfilter
* @Short_Description: A filter for selecting a subset of recently used files
* @Title: GtkRecentFilter
*
* A #GtkRecentFilter can be used to restrict the files being shown
* in a #GtkRecentChooser. Files can be filtered based on their name
* (with gtk_recent_filter_add_pattern()), on their mime type (with
* gtk_file_filter_add_mime_type()), on the application that has
* registered them (with gtk_recent_filter_add_application()), or by
* a custom filter function (with gtk_recent_filter_add_custom()).
*
* Filtering by mime type handles aliasing and subclassing of mime
* types; e.g. a filter for text/plain also matches a file with mime
* type application/rtf, since application/rtf is a subclass of text/plain.
* Note that #GtkRecentFilter allows wildcards for the subtype of a
* mime type, so you can e.g. filter for image/*.
*
* Normally, filters are used by adding them to a #GtkRecentChooser,
* see gtk_recent_chooser_add_filter(), but it is also possible to
* manually use a filter on a file with gtk_recent_filter_filter().
*
* Recently used files are supported since GTK+ 2.10.
*
* <refsect2 id="GtkRecentFilter-BUILDER-UI">
* <title>GtkRecentFilter as GtkBuildable</title>
* <para>
* The GtkRecentFilter 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, &lt;pattern&gt or &lt;application&gt is the same
* as calling gtk_recent_filter_add_mime_type(), gtk_recent_filter_add_pattern()
* or gtk_recent_filter_add_application().
*
* <example>
* <title>A UI definition fragment specifying GtkRecentFilter rules</title>
* <programlisting><![CDATA[
* <object class="GtkRecentFilter">
* <mime-types>
* <mime-type>text/plain</mime-type>
* <mime-type>image/*</mime-type>
* </mime-types>
* <patterns>
* <pattern>*.txt</pattern>
* <pattern>*.png</pattern>
* </patterns>
* <applications>
* <application>gimp</application>
* <application>glade</application>
* </applications>
* </object>
* ]]></programlisting>
* </example>
* </para>
* </refsect2>
*/
#include "config.h"
#include <string.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "gtkrecentfilter.h"
#include "gtkbuildable.h"
#include "gtkintl.h"
#include "gtkprivate.h"
static void gtk_recent_filter_buildable_init (GtkBuildableIface *iface);
static gboolean gtk_recent_filter_buildable_custom_tag_start (GtkBuildable *buildable,
GtkBuilder *builder,
GObject *child,
const gchar *tagname,
GMarkupParser *parser,
gpointer *data);
static void gtk_recent_filter_buildable_custom_tag_end (GtkBuildable *buildable,
GtkBuilder *builder,
GObject *child,
const gchar *tagname,
gpointer *data);
typedef struct _GtkRecentFilterClass GtkRecentFilterClass;
typedef struct _FilterRule FilterRule;
......@@ -77,7 +148,9 @@ struct _FilterRule
} u;
};
G_DEFINE_TYPE (GtkRecentFilter, gtk_recent_filter, G_TYPE_INITIALLY_UNOWNED)
G_DEFINE_TYPE_WITH_CODE (GtkRecentFilter, gtk_recent_filter, G_TYPE_INITIALLY_UNOWNED,
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
gtk_recent_filter_buildable_init))
static void
......@@ -149,6 +222,173 @@ gtk_recent_filter_init (GtkRecentFilter *filter)
}
/*
* GtkBuildable implementation
*/
static void
gtk_recent_filter_buildable_init (GtkBuildableIface *iface)
{
iface->custom_tag_start = gtk_recent_filter_buildable_custom_tag_start;
iface->custom_tag_end = gtk_recent_filter_buildable_custom_tag_end;
}
typedef enum {
PARSE_MIME_TYPES,
PARSE_PATTERNS,
PARSE_APPLICATIONS
} ParserType;
typedef struct {
GtkRecentFilter *filter;
ParserType type;
gchar *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 if (strcmp (element_name, "applications") == 0)
return;
else if (strcmp (element_name, "application") == 0)
{
parser_data->parsing = TRUE;
return;
}
else
g_warning ("Unsupported tag for GtkRecentFilter: %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)
parser_data->string = g_strndup (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_recent_filter_add_mime_type (parser_data->filter, parser_data->string);
break;
case PARSE_PATTERNS:
gtk_recent_filter_add_pattern (parser_data->filter, parser_data->string);
break;
case PARSE_APPLICATIONS:
gtk_recent_filter_add_application (parser_data->filter, parser_data->string);
break;
default:
break;
}
g_free (parser_data->string);
}
parser_data->string = NULL;
parser_data->parsing = FALSE;
}
static const GMarkupParser sub_parser =
{
parser_start_element,
parser_end_element,
parser_text_element,
};
static gboolean
gtk_recent_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->type = PARSE_MIME_TYPES;
parser_data->filter = GTK_RECENT_FILTER (buildable);
*parser = sub_parser;
*data = parser_data;
}
else if (strcmp (tagname, "patterns") == 0)
{
parser_data = g_slice_new0 (SubParserData);
parser_data->type = PARSE_PATTERNS;
parser_data->filter = GTK_RECENT_FILTER (buildable);
*parser = sub_parser;
*data = parser_data;
}
else if (strcmp (tagname, "applications") == 0)
{
parser_data = g_slice_new0 (SubParserData);
parser_data->type = PARSE_APPLICATIONS;
parser_data->filter = GTK_RECENT_FILTER (buildable);
*parser = sub_parser;
*data = parser_data;
}
return parser_data != NULL;
}
static void
gtk_recent_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 ||
strcmp (tagname, "applications") == 0)
{
g_slice_free (SubParserData, (gpointer)data);
}
}
/*
* Public API
*/
......
......@@ -36,6 +36,21 @@ G_BEGIN_DECLS
typedef struct _GtkRecentFilter GtkRecentFilter;
typedef struct _GtkRecentFilterInfo GtkRecentFilterInfo;
/**
* GtkRecentFilterFlags:
* @GTK_RECENT_FILTER_URI: the URI of the file being tested
* @GTK_RECENT_FILTER_DISPLAY_NAME: the string that will be used to
* display the file in the recent chooser
* @GTK_RECENT_FILTER_MIME_TYPE: the mime type of the file
* @GTK_RECENT_FILTER_APPLICATION: the list of applications that have
* registered the file
* @GTK_RECENT_FILTER_GROUP: the groups to which the file belongs to
* @GTK_RECENT_FILTER_AGE: the number of days elapsed since the file
* has been registered
*
* These flags indicate what parts of a #GtkRecentFilterInfo struct
* are filled or need to be filled.
*/
typedef enum {
GTK_RECENT_FILTER_URI = 1 << 0,
GTK_RECENT_FILTER_DISPLAY_NAME = 1 << 1,
......@@ -45,9 +60,27 @@ typedef enum {
GTK_RECENT_FILTER_AGE = 1 << 5
} GtkRecentFilterFlags;
/**
* GtkRecentFilterFunc:
* @filter_info: a #GtkRecentFilterInfo that is filled according
* to the @needed flags passed to gtk_recent_filter_add_custom()
* @user_data: user data passed to gtk_recent_filter_add_custom()
*
* The type of function that is used with custom filters,
* see gtk_recent_filter_add_custom().
*
* Return value: %TRUE if the file should be displayed
*/
typedef gboolean (*GtkRecentFilterFunc) (const GtkRecentFilterInfo *filter_info,
gpointer user_data);
/**
* GtkRecentFilterInfo:
*
* A GtkRecentFilterInfo struct is used
* to pass information about the tested file to gtk_recent_filter_filter().
*/
struct _GtkRecentFilterInfo
{
GtkRecentFilterFlags contains;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment