ekiga r6456 - trunk/lib/gui
- From: jpuydt svn gnome org
- To: svn-commits-list gnome org
- Subject: ekiga r6456 - trunk/lib/gui
- Date: Tue, 15 Jul 2008 13:58:11 +0000 (UTC)
Author: jpuydt
Date: Tue Jul 15 13:58:11 2008
New Revision: 6456
URL: http://svn.gnome.org/viewvc/ekiga?rev=6456&view=rev
Log:
New code to handle anchored text styles and smileys in text buffers -- the previous code was having issues with things like "<u><b>foo</b></u>", for example!
Added:
trunk/lib/gui/gm-text-anchored-tag.c
trunk/lib/gui/gm-text-anchored-tag.h
trunk/lib/gui/gm-text-buffer-enhancer-helper-iface.c
trunk/lib/gui/gm-text-buffer-enhancer-helper-iface.h
trunk/lib/gui/gm-text-buffer-enhancer.c
trunk/lib/gui/gm-text-buffer-enhancer.h
trunk/lib/gui/gm-text-smiley.c
trunk/lib/gui/gm-text-smiley.h
Modified:
trunk/lib/gui/Makefile.am
Modified: trunk/lib/gui/Makefile.am
==============================================================================
--- trunk/lib/gui/Makefile.am (original)
+++ trunk/lib/gui/Makefile.am Tue Jul 15 13:58:11 2008
@@ -36,7 +36,15 @@
gmcellrendererexpander.c \
gmcellrendererexpander.h \
gm-cell-renderer-bitext.c \
- gm-cell-renderer-bitext.h
+ gm-cell-renderer-bitext.h \
+ gm-text-buffer-enhancer-helper-iface.c \
+ gm-text-buffer-enhancer-helper-iface.h \
+ gm-text-anchored-tag.c \
+ gm-text-anchored-tag.h \
+ gm-text-smiley.c \
+ gm-text-smiley.h \
+ gm-text-buffer-enhancer.c \
+ gm-text-buffer-enhancer.h
if !WIN32
Added: trunk/lib/gui/gm-text-anchored-tag.c
==============================================================================
--- (empty file)
+++ trunk/lib/gui/gm-text-anchored-tag.c Tue Jul 15 13:58:11 2008
@@ -0,0 +1,239 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * Ekiga is licensed under the GPL license and as a special exception,
+ * you have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
+ * without applying the requirements of the GNU GPL to the OPAL, OpenH323
+ * and PWLIB programs, as long as you do follow the requirements of the
+ * GNU GPL for all the rest of the software thus combined.
+ */
+
+
+/*
+ * gm-text-anchored-tag.c - description
+ * --------------------------------
+ * begin : written in july 2008 by Julien Puydt
+ * copyright : (C) 2008 by Julien Puydt
+ * description : Implementation of an anchor-based text decorator
+ *
+ */
+
+#include "gm-text-anchored-tag.h"
+
+#include <string.h>
+
+typedef struct _GmTextAnchoredTagPrivate GmTextAnchoredTagPrivate;
+
+struct _GmTextAnchoredTagPrivate {
+ gchar* anchor;
+ GtkTextTag* tag;
+ gboolean opening;
+};
+
+#define GM_TEXT_ANCHORED_TAG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), GM_TYPE_TEXT_ANCHORED_TAG, GmTextAnchoredTagPrivate))
+
+static GObjectClass* parent_class = NULL;
+
+/* declaration of the GmTextBufferEnhancerHelperIFace code */
+
+static void enhancer_helper_check (GmTextBufferEnhancerHelperIFace* self,
+ const gchar* full_text,
+ gint from,
+ gint* start,
+ gint* length);
+
+static void enhancer_helper_enhance (GmTextBufferEnhancerHelperIFace* self,
+ GtkTextBuffer* buffer,
+ GtkTextIter* iter,
+ GSList** tags,
+ const gchar* full_text,
+ gint* start,
+ gint length);
+
+static void enhancer_helper_iface_init (gpointer g_iface,
+ gpointer iface_data);
+
+/* implementation of the GmTextBufferEnhancerHelperIFace code */
+
+static void
+enhancer_helper_check (GmTextBufferEnhancerHelperIFace* self,
+ const gchar* full_text,
+ gint from,
+ gint* start,
+ gint* length)
+{
+ GmTextAnchoredTagPrivate* priv = GM_TEXT_ANCHORED_TAG_GET_PRIVATE (self);
+ char* found = NULL;
+
+ found = strstr (full_text + from, priv->anchor);
+
+ if (found != NULL) {
+
+ *start = found - full_text;
+ *length = strlen (priv->anchor);
+ } else
+ *length = 0;
+}
+
+static void
+enhancer_helper_enhance (GmTextBufferEnhancerHelperIFace* self,
+ G_GNUC_UNUSED GtkTextBuffer* buffer,
+ G_GNUC_UNUSED GtkTextIter* iter,
+ GSList** tags,
+ G_GNUC_UNUSED const gchar* full_text,
+ gint* start,
+ gint length)
+{
+ GmTextAnchoredTagPrivate* priv = GM_TEXT_ANCHORED_TAG_GET_PRIVATE (self);
+
+ if (priv->opening)
+ *tags = g_slist_prepend (*tags, priv->tag);
+ else
+ *tags = g_slist_remove (*tags, priv->tag);
+
+ *start = *start + length;
+}
+
+static void
+enhancer_helper_iface_init (gpointer g_iface,
+ G_GNUC_UNUSED gpointer iface_data)
+{
+ GmTextBufferEnhancerHelperIFaceClass* iface = NULL;
+
+ iface = (GmTextBufferEnhancerHelperIFaceClass*)g_iface;
+ iface->do_check = &enhancer_helper_check;
+ iface->do_enhance = &enhancer_helper_enhance;
+}
+
+/* GObject boilerplate */
+
+static void
+gm_text_anchored_tag_dispose (GObject* obj)
+{
+ GmTextAnchoredTagPrivate* priv = GM_TEXT_ANCHORED_TAG_GET_PRIVATE(obj);
+
+ if (priv->tag != NULL) {
+
+ g_object_unref (priv->tag);
+ priv->tag = NULL;
+ }
+
+ parent_class->dispose (obj);
+}
+
+static void
+gm_text_anchored_tag_finalize (GObject* obj)
+{
+ GmTextAnchoredTagPrivate* priv = GM_TEXT_ANCHORED_TAG_GET_PRIVATE(obj);
+
+ if (priv->anchor != NULL) {
+
+ g_free (priv->anchor);
+ priv->anchor = NULL;
+ }
+
+ parent_class->finalize (obj);
+}
+
+static void
+gm_text_anchored_tag_class_init (GmTextAnchoredTagClass* g_class)
+{
+ GObjectClass* gobject_class = NULL;
+
+ parent_class = g_type_class_peek_parent (g_class);
+
+ gobject_class = (GObjectClass*)g_class;
+ gobject_class->dispose = gm_text_anchored_tag_dispose;
+ gobject_class->finalize = gm_text_anchored_tag_finalize;
+
+ g_type_class_add_private (gobject_class, sizeof (GmTextAnchoredTagPrivate));
+}
+
+static void
+gm_text_anchored_tag_init (GmTextAnchoredTag* obj)
+{
+ GmTextAnchoredTagPrivate* priv = GM_TEXT_ANCHORED_TAG_GET_PRIVATE(obj);
+
+ priv->anchor = NULL;
+ priv->tag = NULL;
+ priv->opening = TRUE;
+}
+
+GType
+gm_text_anchored_tag_get_type (void)
+{
+ static GType result = 0;
+ if (!result) {
+
+ static const GTypeInfo my_info = {
+ sizeof(GmTextAnchoredTagClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gm_text_anchored_tag_class_init,
+ NULL,
+ NULL,
+ sizeof(GmTextAnchoredTag),
+ 0,
+ (GInstanceInitFunc) gm_text_anchored_tag_init,
+ NULL
+ };
+
+ static const GInterfaceInfo enhancer_helper_info = {
+ enhancer_helper_iface_init,
+ NULL,
+ NULL
+ };
+
+ result = g_type_register_static (G_TYPE_OBJECT,
+ "GmTextAnchoredTag",
+ &my_info, 0);
+ g_type_add_interface_static (result,
+ GM_TYPE_TEXT_BUFFER_ENHANCER_HELPER_IFACE,
+ &enhancer_helper_info);
+ }
+ return result;
+}
+
+/* Implementation of the public api */
+
+GmTextBufferEnhancerHelperIFace*
+gm_text_anchored_tag_new (const gchar* anchor,
+ GtkTextTag* tag,
+ gboolean opening)
+{
+ GmTextAnchoredTag* result = NULL;
+ GmTextAnchoredTagPrivate* priv = NULL;
+
+ g_return_val_if_fail (anchor != NULL, NULL);
+ g_return_val_if_fail (GTK_IS_TEXT_TAG (tag), NULL);
+
+ result = (GmTextAnchoredTag*)g_object_new (GM_TYPE_TEXT_ANCHORED_TAG, NULL);
+
+ priv = GM_TEXT_ANCHORED_TAG_GET_PRIVATE (result);
+
+ priv->anchor = g_strdup (anchor);
+
+ g_object_ref (tag);
+ priv->tag = tag;
+
+ priv->opening = opening;
+
+ return GM_TEXT_BUFFER_ENHANCER_HELPER_IFACE (result);
+}
Added: trunk/lib/gui/gm-text-anchored-tag.h
==============================================================================
--- (empty file)
+++ trunk/lib/gui/gm-text-anchored-tag.h Tue Jul 15 13:58:11 2008
@@ -0,0 +1,93 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * Ekiga is licensed under the GPL license and as a special exception,
+ * you have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
+ * without applying the requirements of the GNU GPL to the OPAL, OpenH323
+ * and PWLIB programs, as long as you do follow the requirements of the
+ * GNU GPL for all the rest of the software thus combined.
+ */
+
+
+/*
+ * gm-text-anchored-tag.h - description
+ * --------------------------------
+ * begin : written in july 2008 by Julien Puydt
+ * copyright : (C) 2008 by Julien Puydt
+ * description : Declaration of an anchor-based text decorator
+ *
+ */
+
+#ifndef __GM_TEXT_ANCHORED_TAG_H__
+#define __GM_TEXT_ANCHORED_TAG_H__
+
+#include "gm-text-buffer-enhancer-helper-iface.h"
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+/* public api */
+
+/* The anchor parameter is the text this decorator should look for,
+ * the tag parameter is the tag which this decorator should apply/unapply,
+ * and the opening parameter tells if it must apply (TRUE) or unapply (FALSE)
+ *
+ * Here is sample code showing how to use it :
+ * tag = gtk_text_buffer_create_tag (buffer, "bold",
+ * "weight", PANGO_WEIGHT_BOLD,
+ * NULL);
+ * helper = gm_text_anchored_tag_new ("<b>", tag, TRUE);
+ * gm_text_buffer_enhancer_add_helper (enhancer, helper);
+ * g_object_unref (helper);
+ * helper = gm_text_anchored_tag_new ("</b>", tag, FALSE);
+ * gm_text_buffer_enhancer_add_helper (enhancer, helper);
+ * g_object_unref (helper);
+ *
+ */
+GmTextBufferEnhancerHelperIFace* gm_text_anchored_tag_new (const gchar* anchor,
+ GtkTextTag* tag,
+ gboolean opening);
+
+/* GObject boilerplate */
+
+typedef struct _GmTextAnchoredTag GmTextAnchoredTag;
+typedef struct _GmTextAnchoredTagClass GmTextAnchoredTagClass;
+
+struct _GmTextAnchoredTag {
+ GObject parent;
+};
+
+struct _GmTextAnchoredTagClass {
+ GObjectClass parent_class;
+};
+
+GType gm_text_anchored_tag_get_type () G_GNUC_CONST;
+
+#define GM_TYPE_TEXT_ANCHORED_TAG (gm_text_anchored_tag_get_type())
+#define GM_TEXT_ANCHORED_TAG(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GM_TYPE_TEXT_ANCHORED_TAG,GmTextAnchoredTag))
+#define GM_TEXT_ANCHORED_TAG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GM_TYPE_TEXT_ANCHORED_TAG,GObject))
+#define GM_IS_TEXT_ANCHORED_TAG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GM_TYPE_TEXT_ANCHORED_TAG))
+#define GM_IS_TEXT_ANCHORED_TAG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GM_TYPE_TEXT_ANCHORED_TAG))
+#define GM_TEXT_ANCHORED_TAG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GM_TYPE_TEXT_ANCHORED_TAG,GmTextAnchoredTagClass))
+
+G_END_DECLS
+
+#endif /* __GM_TEXT_ANCHORED_TAG_H__ */
Added: trunk/lib/gui/gm-text-buffer-enhancer-helper-iface.c
==============================================================================
--- (empty file)
+++ trunk/lib/gui/gm-text-buffer-enhancer-helper-iface.c Tue Jul 15 13:58:11 2008
@@ -0,0 +1,102 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * Ekiga is licensed under the GPL license and as a special exception,
+ * you have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
+ * without applying the requirements of the GNU GPL to the OPAL, OpenH323
+ * and PWLIB programs, as long as you do follow the requirements of the
+ * GNU GPL for all the rest of the software thus combined.
+ */
+
+
+/*
+ * gm-text-buffer-enhancer-helper-iface.c - description
+ * --------------------------------
+ * begin : written in july 2008 by Julien Puydt
+ * copyright : (C) 2008 by Julien Puydt
+ * description : Implementation of the interface of a text decorator
+ * (for use with GmTextBufferEnhancer)
+ *
+ */
+
+#include "gm-text-buffer-enhancer-helper-iface.h"
+
+/* GObject code */
+
+static void
+gm_text_buffer_enhancer_helper_iface_base_init (G_GNUC_UNUSED gpointer g_class)
+{
+ static gboolean initialized = FALSE;
+ if (!initialized) {
+ /* nothing */
+ initialized = TRUE;
+ }
+}
+GType
+gm_text_buffer_enhancer_helper_iface_get_type (void)
+{
+ static GType result = 0;
+ if (!result) {
+
+ static const GTypeInfo my_info = {
+ sizeof(GmTextBufferEnhancerHelperIFaceClass),
+ gm_text_buffer_enhancer_helper_iface_base_init,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 0,
+ 0,
+ NULL,
+ NULL
+ };
+
+ result = g_type_register_static (G_TYPE_INTERFACE,
+ "GmTextBufferEnhancerHelperIFace",
+ &my_info, 0);
+
+ g_type_interface_add_prerequisite (result, G_TYPE_OBJECT);
+ }
+ return result;
+}
+
+/* public api */
+
+void
+gm_text_buffer_enhancer_helper_check (GmTextBufferEnhancerHelperIFace* self,
+ const gchar* full_text,
+ gint from,
+ gint* start,
+ gint* length)
+{
+ return GM_TEXT_BUFFER_ENHANCER_HELPER_IFACE_GET_CLASS (self)->do_check (self, full_text, from, start, length);
+}
+
+void
+gm_text_buffer_enhancer_helper_enhance (GmTextBufferEnhancerHelperIFace* self,
+ GtkTextBuffer* buffer,
+ GtkTextIter* iter,
+ GSList** tags,
+ const gchar* full_text,
+ gint* start,
+ gint length)
+{
+ GM_TEXT_BUFFER_ENHANCER_HELPER_IFACE_GET_CLASS (self)->do_enhance (self, buffer, iter, tags, full_text, start, length);
+}
Added: trunk/lib/gui/gm-text-buffer-enhancer-helper-iface.h
==============================================================================
--- (empty file)
+++ trunk/lib/gui/gm-text-buffer-enhancer-helper-iface.h Tue Jul 15 13:58:11 2008
@@ -0,0 +1,129 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * Ekiga is licensed under the GPL license and as a special exception,
+ * you have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
+ * without applying the requirements of the GNU GPL to the OPAL, OpenH323
+ * and PWLIB programs, as long as you do follow the requirements of the
+ * GNU GPL for all the rest of the software thus combined.
+ */
+
+
+/*
+ * gm-text-buffer-enhancer-helper-iface.h - description
+ * --------------------------------
+ * begin : written in july 2008 by Julien Puydt
+ * copyright : (C) 2008 by Julien Puydt
+ * description : Declaration of the interface of a text decorator
+ * (for use with GmTextBufferEnhancer)
+ *
+ */
+
+#ifndef __GM_TEXT_BUFFER_ENHANCER_HELPER_IFACE_H__
+#define __GM_TEXT_BUFFER_ENHANCER_HELPER_IFACE_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GmTextBufferEnhancerHelperIFace GmTextBufferEnhancerHelperIFace;
+typedef struct _GmTextBufferEnhancerHelperIFaceClass GmTextBufferEnhancerHelperIFaceClass;
+
+/* public api */
+
+/* This method is used to have all enhancers tell what they think they can do
+ * to enhance a text ; then the enhancer will choose the most suitable helper
+ * and use the next method.
+ * For this reason, the helper receives :
+ * - the full text (full_text parameter) ;
+ * - where in the full text it should start looking for interesting things (from
+ * parameter) ;
+ * and it returns two values (the start and length out parameters) :
+ * - where it thinks it can do something (the start parameter) ;
+ * - on which length it will do it (the length parameter).
+ *
+ * The idea is :
+ * - return a zero length if nothing interesting can be done (start will then
+ * be ignored by the caller) ;
+ * - the length allows the enhancer to prefer the helper which saw "fooz" when
+ * compared to the one which saw "foo".
+ */
+void gm_text_buffer_enhancer_helper_check (GmTextBufferEnhancerHelperIFace* self,
+ const gchar* full_text,
+ gint from,
+ gint* start,
+ gint* length);
+
+
+/* This method is called by the enhancer when the helper has been choosen
+ * to act ; it receives :
+ * - the buffer (buffer parameter) in which the enhanced text has to go ;
+ * - the iterator (iter parameter) where to insert the enhanced text ;
+ * - the active tags (tags parameter), which is an in&out parameter, hence
+ * the enhancer can change them and use them ;
+ * - the full text which the enhancer is trying to insert ;
+ * - where in the text the helper said it would work (the start parameter),
+ * as in&out parameter so the helper can swallow it ;
+ * - the length (length parameter) of the part the helper said was interested
+ * in.
+ *
+ * "the helper said" means those values are those the helper answered in its
+ * check method.
+ */
+void gm_text_buffer_enhancer_helper_enhance (GmTextBufferEnhancerHelperIFace* self,
+ GtkTextBuffer* buffer,
+ GtkTextIter* iter,
+ GSList** tags,
+ const gchar* full_text,
+ gint* start,
+ gint length);
+
+/* GObject boilerplate */
+
+struct _GmTextBufferEnhancerHelperIFaceClass {
+ GTypeInterface parent;
+
+ void (*do_check) (GmTextBufferEnhancerHelperIFace* self,
+ const gchar* full_text,
+ gint from,
+ gint* start,
+ gint* length);
+
+ void (*do_enhance) (GmTextBufferEnhancerHelperIFace* self,
+ GtkTextBuffer* buffer,
+ GtkTextIter* iter,
+ GSList** tags,
+ const gchar* full_text,
+ gint* start,
+ gint length);
+};
+
+#define GM_TYPE_TEXT_BUFFER_ENHANCER_HELPER_IFACE (gm_text_buffer_enhancer_helper_iface_get_type())
+#define GM_TEXT_BUFFER_ENHANCER_HELPER_IFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GM_TYPE_TEXT_BUFFER_ENHANCER_HELPER_IFACE,GmTextBufferEnhancerHelperIFace))
+#define GM_TEXT_BUFFER_ENHANCER_HELPER_IFACE_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST((vtable),GM_TYPE_TEXT_BUFFER_ENHANCER_HELPER_IFACE,GTypeInterface))
+#define GM_IS_TEXT_BUFFER_ENHANCER_HELPER_IFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GM_TYPE_TEXT_BUFFER_ENHANCER_HELPER_IFACE))
+#define GM_IS_TEXT_BUFFER_ENHANCER_HELPER_IFACE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable),GM_TYPE_TEXT_BUFFER_ENHANCER_HELPER_IFACE))
+#define GM_TEXT_BUFFER_ENHANCER_HELPER_IFACE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst),GM_TYPE_TEXT_BUFFER_ENHANCER_HELPER_IFACE,GmTextBufferEnhancerHelperIFaceClass))
+
+GType gm_text_buffer_enhancer_helper_iface_get_type () G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __GM_TEXT_BUFFER_ENHANCER_HELPER_IFACE_H__ */
Added: trunk/lib/gui/gm-text-buffer-enhancer.c
==============================================================================
--- (empty file)
+++ trunk/lib/gui/gm-text-buffer-enhancer.c Tue Jul 15 13:58:11 2008
@@ -0,0 +1,228 @@
+/* gm-text-buffer-enhancer.c */
+
+/* insert (c)/licensing information) */
+
+#include "gm-text-buffer-enhancer.h"
+
+#include <string.h>
+
+static void gm_text_buffer_enhancer_class_init (GmTextBufferEnhancerClass* g_class);
+static void gm_text_buffer_enhancer_init (GmTextBufferEnhancer* obj);
+static void gm_text_buffer_enhancer_dispose (GObject* obj);
+static void gm_text_buffer_enhancer_finalize (GObject* obj);
+
+typedef struct _GmTextBufferEnhancerPrivate GmTextBufferEnhancerPrivate;
+struct _GmTextBufferEnhancerPrivate {
+ GtkTextBuffer* buffer;
+ GSList* helpers;
+};
+
+#define GM_TEXT_BUFFER_ENHANCER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
+ GM_TYPE_TEXT_BUFFER_ENHANCER, \
+ GmTextBufferEnhancerPrivate))
+
+static GObjectClass* parent_class = NULL;
+
+GType
+gm_text_buffer_enhancer_get_type (void)
+{
+ static GType result = 0;
+ if (!result) {
+ static const GTypeInfo my_info = {
+ sizeof(GmTextBufferEnhancerClass),
+ NULL, /* base init */
+ NULL, /* base finalize */
+ (GClassInitFunc) gm_text_buffer_enhancer_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof(GmTextBufferEnhancer),
+ 1, /* n_preallocs */
+ (GInstanceInitFunc) gm_text_buffer_enhancer_init,
+ NULL
+ };
+ result = g_type_register_static (G_TYPE_OBJECT,
+ "GmTextBufferEnhancer",
+ &my_info, 0);
+ }
+ return result;
+}
+
+static void
+gm_text_buffer_enhancer_class_init (GmTextBufferEnhancerClass* g_class)
+{
+ GObjectClass* gobject_class = NULL;
+
+ parent_class = g_type_class_peek_parent (g_class);
+
+ gobject_class = (GObjectClass*)g_class;
+ gobject_class->dispose = gm_text_buffer_enhancer_dispose;
+ gobject_class->finalize = gm_text_buffer_enhancer_finalize;
+
+ g_type_class_add_private (gobject_class,
+ sizeof(GmTextBufferEnhancerPrivate));
+}
+
+static void
+gm_text_buffer_enhancer_init (GmTextBufferEnhancer* obj)
+{
+ GmTextBufferEnhancerPrivate* priv = GM_TEXT_BUFFER_ENHANCER_GET_PRIVATE(obj);
+
+ priv->buffer = NULL;
+ priv->helpers = NULL;
+}
+
+static void
+gm_text_buffer_enhancer_dispose (GObject* obj)
+{
+ GmTextBufferEnhancerPrivate* priv = GM_TEXT_BUFFER_ENHANCER_GET_PRIVATE(obj);
+
+ if (priv->buffer != NULL) {
+
+ g_object_unref (priv->buffer);
+ priv->buffer = NULL;
+ }
+
+ if (priv->helpers != NULL) {
+
+ g_slist_foreach (priv->helpers, (GFunc)g_object_unref, NULL);
+ g_slist_free (priv->helpers);
+ priv->helpers = NULL;
+ }
+
+ G_OBJECT_CLASS(parent_class)->dispose (obj);
+}
+
+static void
+gm_text_buffer_enhancer_finalize (GObject* obj)
+{
+ G_OBJECT_CLASS(parent_class)->finalize (obj);
+}
+
+GmTextBufferEnhancer*
+gm_text_buffer_enhancer_new (GtkTextBuffer* buffer)
+{
+ GmTextBufferEnhancer* result = NULL;
+ GmTextBufferEnhancerPrivate* priv = NULL;
+
+ g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
+
+ result
+ = (GmTextBufferEnhancer*)g_object_new(GM_TYPE_TEXT_BUFFER_ENHANCER, NULL);
+
+ priv = GM_TEXT_BUFFER_ENHANCER_GET_PRIVATE (result);
+ g_object_ref (buffer);
+ priv->buffer = buffer;
+
+ return result;
+}
+
+void
+gm_text_buffer_enhancer_add_helper (GmTextBufferEnhancer* self,
+ GmTextBufferEnhancerHelperIFace* helper)
+{
+ GmTextBufferEnhancerPrivate* priv = NULL;
+
+ g_return_if_fail (GM_IS_TEXT_BUFFER_ENHANCER (self));
+ g_return_if_fail (GM_IS_TEXT_BUFFER_ENHANCER_HELPER_IFACE (helper));
+
+ priv = GM_TEXT_BUFFER_ENHANCER_GET_PRIVATE(self);
+ g_object_ref (helper);
+ priv->helpers = g_slist_prepend (priv->helpers, helper);
+}
+
+void
+gm_text_buffer_enhancer_insert_text (GmTextBufferEnhancer* self,
+ GtkTextIter* iter,
+ const gchar* text,
+ gint len)
+{
+ GmTextBufferEnhancerPrivate* priv = NULL;
+ gint position = 0;
+ gint length = 0;
+ GSList* active_tags = NULL;
+ GmTextBufferEnhancerHelperIFace* best_helper = NULL;
+ gint best_start = 0;
+ gint best_length = 0;
+ GSList* helper_ptr = NULL;
+ GmTextBufferEnhancerHelperIFace* considered_helper = NULL;
+ gint considered_start = 0;
+ gint considered_length = 0;
+ GSList* tag_ptr = NULL;
+ GtkTextMark* mark = NULL;
+ GtkTextIter tag_start_iter;
+
+ g_return_if_fail (GM_IS_TEXT_BUFFER_ENHANCER (self));
+ g_return_if_fail (iter != NULL); // can't do better
+ g_return_if_fail (text != NULL);
+
+ priv = GM_TEXT_BUFFER_ENHANCER_GET_PRIVATE (self);
+
+ if (len < 0)
+ length = strlen (text);
+ else
+ length = len;
+
+ mark = gtk_text_buffer_create_mark (priv->buffer, NULL, iter, TRUE);
+
+ while (position < length) {
+
+ /* try to find the best helper,
+ * starting for the worse case that none is good */
+ best_helper = NULL;
+ best_start = length;
+ best_length = 0;
+ for (helper_ptr = priv->helpers ;
+ helper_ptr != NULL ;
+ helper_ptr = g_slist_next (helper_ptr)) {
+
+ considered_helper
+ = GM_TEXT_BUFFER_ENHANCER_HELPER_IFACE (helper_ptr->data);
+ gm_text_buffer_enhancer_helper_check (considered_helper,
+ text, position,
+ &considered_start,
+ &considered_length);
+ if (((considered_start < best_start)
+ && (considered_length > 0))
+ || ((considered_start == best_start)
+ && (considered_length > best_length))) {
+
+ best_helper = considered_helper;
+ best_start = considered_start;
+ best_length = considered_length;
+ }
+ }
+
+ /* whatever we found can be further down : just apply the tags to
+ * the part of the text before */
+ if (position < best_start) {
+
+ gtk_text_buffer_move_mark (priv->buffer, mark, iter);
+ gtk_text_buffer_insert (priv->buffer, iter,
+ text + position, best_start - position);
+ gtk_text_buffer_get_iter_at_mark (priv->buffer, &tag_start_iter, mark);
+ for (tag_ptr = active_tags;
+ tag_ptr != NULL;
+ tag_ptr = g_slist_next (tag_ptr)) {
+
+ gtk_text_buffer_apply_tag (priv->buffer, GTK_TEXT_TAG (tag_ptr->data),
+ &tag_start_iter, iter);
+ }
+ position = best_start;
+ }
+
+ /* ok, now we're either at the end without a best helper or still in the
+ * middle with a best helper : apply that one if it's there!
+ */
+ if (best_helper != NULL)
+ gm_text_buffer_enhancer_helper_enhance (best_helper,
+ priv->buffer,
+ iter,
+ &active_tags,
+ text,
+ &position,
+ best_length);
+ }
+
+ gtk_text_buffer_delete_mark (priv->buffer, mark);
+ g_slist_free (active_tags);
+}
Added: trunk/lib/gui/gm-text-buffer-enhancer.h
==============================================================================
--- (empty file)
+++ trunk/lib/gui/gm-text-buffer-enhancer.h Tue Jul 15 13:58:11 2008
@@ -0,0 +1,46 @@
+/* gm-text-buffer-enhancer.h */
+/* insert (c)/licensing information) */
+
+#ifndef __GM_TEXT_BUFFER_ENHANCER_H__
+#define __GM_TEXT_BUFFER_ENHANCER_H__
+
+#include <gtk/gtk.h>
+#include "gm-text-buffer-enhancer-helper-iface.h"
+
+G_BEGIN_DECLS
+
+/* convenience macros */
+#define GM_TYPE_TEXT_BUFFER_ENHANCER (gm_text_buffer_enhancer_get_type())
+#define GM_TEXT_BUFFER_ENHANCER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GM_TYPE_TEXT_BUFFER_ENHANCER,GmTextBufferEnhancer))
+#define GM_TEXT_BUFFER_ENHANCER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GM_TYPE_TEXT_BUFFER_ENHANCER,GObject))
+#define GM_IS_TEXT_BUFFER_ENHANCER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GM_TYPE_TEXT_BUFFER_ENHANCER))
+#define GM_IS_TEXT_BUFFER_ENHANCER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GM_TYPE_TEXT_BUFFER_ENHANCER))
+#define GM_TEXT_BUFFER_ENHANCER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GM_TYPE_TEXT_BUFFER_ENHANCER,GmTextBufferEnhancerClass))
+
+typedef struct _GmTextBufferEnhancer GmTextBufferEnhancer;
+typedef struct _GmTextBufferEnhancerClass GmTextBufferEnhancerClass;
+
+struct _GmTextBufferEnhancer {
+ GObject parent;
+};
+
+struct _GmTextBufferEnhancerClass {
+ GObjectClass parent_class;
+};
+
+/* member functions */
+GType gm_text_buffer_enhancer_get_type () G_GNUC_CONST;
+
+GmTextBufferEnhancer* gm_text_buffer_enhancer_new (GtkTextBuffer* buffer);
+
+void gm_text_buffer_enhancer_add_helper (GmTextBufferEnhancer* self,
+ GmTextBufferEnhancerHelperIFace* helper);
+
+void gm_text_buffer_enhancer_insert_text (GmTextBufferEnhancer* self,
+ GtkTextIter* iter,
+ const gchar* text,
+ gint len);
+
+G_END_DECLS
+
+#endif /* __GM_TEXT_BUFFER_ENHANCER_H__ */
Added: trunk/lib/gui/gm-text-smiley.c
==============================================================================
--- (empty file)
+++ trunk/lib/gui/gm-text-smiley.c Tue Jul 15 13:58:11 2008
@@ -0,0 +1,224 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * Ekiga is licensed under the GPL license and as a special exception,
+ * you have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
+ * without applying the requirements of the GNU GPL to the OPAL, OpenH323
+ * and PWLIB programs, as long as you do follow the requirements of the
+ * GNU GPL for all the rest of the software thus combined.
+ */
+
+
+/*
+ * gm-text-smiley.c - description
+ * --------------------------------
+ * begin : written in july 2008 by Julien Puydt
+ * copyright : (C) 2008 by Julien Puydt
+ * description : Implementation of a text decorator for smileys
+ *
+ */
+
+#include "gm-text-smiley.h"
+
+#include <string.h>
+
+/* here are the smileys */
+static const char* smileys[] = {
+ /* smiley, pixbux */
+ "0:-)", "face-angel",
+ "B-)", "face-cool",
+ ":'-(", "face-crying",
+ ":-[", "face-embarassed",
+ ">:-)", "face-devilish",
+ ":-*", "face-kiss",
+ ":-(|)", "face-monkey",
+ ":-|", "face-plain",
+ ":-P", "face-raspberry",
+ ":-(", "face-sad",
+ ":-)", "face-smile",
+ ":-D", "face-smile-big",
+ ":-!", "face-smirk",
+ ":-O", "face-surprise",
+ ";-)", "face-wink",
+ NULL
+};
+
+static GObjectClass* parent_class = NULL;
+
+/* declaration of the GmTextBufferEnhancerHelperIFace code */
+
+static void enhancer_helper_check (GmTextBufferEnhancerHelperIFace* self,
+ const gchar* full_text,
+ gint from,
+ gint* start,
+ gint* length);
+
+static void enhancer_helper_enhance (GmTextBufferEnhancerHelperIFace* self,
+ GtkTextBuffer* buffer,
+ GtkTextIter* iter,
+ GSList** tags,
+ const gchar* full_text,
+ gint* start,
+ gint length);
+
+static void enhancer_helper_iface_init (gpointer g_iface,
+ gpointer iface_data);
+
+/* implementation of the GmTextBufferEnhancerHelperIFace code */
+
+static void
+enhancer_helper_check (G_GNUC_UNUSED GmTextBufferEnhancerHelperIFace* self,
+ const gchar* full_text,
+ gint from,
+ gint* start,
+ gint* length)
+{
+ gint smiley = 0;
+ gint best_start = 0;
+ gint best_smiley = -1;
+ char* found = NULL;
+ gint found_start = 0;
+
+ for (smiley = 0;
+ smileys[smiley] != NULL;
+ smiley = smiley + 2) {
+
+ found = strstr (full_text + from, smileys[smiley]);
+ if (found != NULL) {
+
+ found_start = found - full_text;
+ if ((best_smiley == -1)
+ || ((found_start <= best_start)
+ && (strlen (smileys[smiley]) > strlen (smileys[best_smiley])))) {
+
+ best_smiley = smiley;
+ best_start = found_start;
+ }
+ }
+ }
+
+
+ if (best_smiley != -1) {
+
+ *start = best_start;
+ *length = strlen (smileys[best_smiley]);
+ } else
+ *length = 0;
+}
+
+static void
+enhancer_helper_enhance (G_GNUC_UNUSED GmTextBufferEnhancerHelperIFace* self,
+ GtkTextBuffer* buffer,
+ GtkTextIter* iter,
+ G_GNUC_UNUSED GSList** tags,
+ G_GNUC_UNUSED const gchar* full_text,
+ gint* start,
+ gint length)
+{
+ gchar* smiley = NULL;
+ gint ii = 0;
+ const gchar* pixbuf_name = NULL;
+ GdkPixbuf* pixbuf = NULL;
+
+ smiley = g_malloc0 (length + 1);
+
+ strncpy (smiley, full_text + *start, length);
+
+ for (ii = 0;
+ smileys[ii] != NULL;
+ ii = ii + 2) {
+
+ if (strcmp (smiley, smileys[ii]) == 0)
+ pixbuf_name = smileys[ii + 1];
+ }
+
+ if (pixbuf_name != NULL) {
+
+ pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
+ pixbuf_name, 16, 0, NULL);
+ gtk_text_buffer_insert_pixbuf (buffer, iter, pixbuf);
+ g_object_unref (pixbuf);
+ *start = *start + length;
+ }
+
+ g_free (smiley);
+}
+
+static void
+enhancer_helper_iface_init (gpointer g_iface,
+ G_GNUC_UNUSED gpointer iface_data)
+{
+ GmTextBufferEnhancerHelperIFaceClass* iface = NULL;
+
+ iface = (GmTextBufferEnhancerHelperIFaceClass*)g_iface;
+ iface->do_check = &enhancer_helper_check;
+ iface->do_enhance = &enhancer_helper_enhance;
+}
+
+/* GObject boilerplate */
+
+static void
+gm_text_smiley_class_init (GmTextSmileyClass* g_class)
+{
+ parent_class = g_type_class_peek_parent (g_class);
+}
+
+GType
+gm_text_smiley_get_type ()
+{
+ static GType result = 0;
+ if (!result) {
+
+ static const GTypeInfo my_info = {
+ sizeof(GmTextSmileyClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gm_text_smiley_class_init,
+ NULL,
+ NULL,
+ sizeof(GmTextSmiley),
+ 0,
+ NULL,
+ NULL
+ };
+
+ static const GInterfaceInfo enhancer_helper_info = {
+ enhancer_helper_iface_init,
+ NULL,
+ NULL
+ };
+
+ result = g_type_register_static (G_TYPE_OBJECT,
+ "GmTextSmiley",
+ &my_info, 0);
+ g_type_add_interface_static (result,
+ GM_TYPE_TEXT_BUFFER_ENHANCER_HELPER_IFACE,
+ &enhancer_helper_info);
+ }
+ return result;
+}
+
+/* public api */
+
+GmTextBufferEnhancerHelperIFace*
+gm_text_smiley_new (void)
+{
+ return (GmTextBufferEnhancerHelperIFace*)g_object_new(GM_TYPE_TEXT_SMILEY, NULL);
+}
Added: trunk/lib/gui/gm-text-smiley.h
==============================================================================
--- (empty file)
+++ trunk/lib/gui/gm-text-smiley.h Tue Jul 15 13:58:11 2008
@@ -0,0 +1,73 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * Ekiga is licensed under the GPL license and as a special exception,
+ * you have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
+ * without applying the requirements of the GNU GPL to the OPAL, OpenH323
+ * and PWLIB programs, as long as you do follow the requirements of the
+ * GNU GPL for all the rest of the software thus combined.
+ */
+
+
+/*
+ * gm-text-smiley.h - description
+ * --------------------------------
+ * begin : written in july 2008 by Julien Puydt
+ * copyright : (C) 2008 by Julien Puydt
+ * description : Declaration of a text decorator for smileys
+ *
+ */
+
+#ifndef __GM_TEXT_SMILEY_H__
+#define __GM_TEXT_SMILEY_H__
+
+#include "gm-text-buffer-enhancer-helper-iface.h"
+
+G_BEGIN_DECLS
+
+/* public api */
+
+GmTextBufferEnhancerHelperIFace* gm_text_smiley_new ();
+
+/* GObject boilerplate */
+
+typedef struct _GmTextSmiley GmTextSmiley;
+typedef struct _GmTextSmileyClass GmTextSmileyClass;
+
+struct _GmTextSmiley {
+ GObject parent;
+};
+
+struct _GmTextSmileyClass {
+ GObjectClass parent_class;
+};
+
+#define GM_TYPE_TEXT_SMILEY (gm_text_smiley_get_type())
+#define GM_TEXT_SMILEY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GM_TYPE_TEXT_SMILEY,GmTextSmiley))
+#define GM_TEXT_SMILEY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GM_TYPE_TEXT_SMILEY,GObject))
+#define GM_IS_TEXT_SMILEY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GM_TYPE_TEXT_SMILEY))
+#define GM_IS_TEXT_SMILEY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GM_TYPE_TEXT_SMILEY))
+#define GM_TEXT_SMILEY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GM_TYPE_TEXT_SMILEY,GmTextSmileyClass))
+
+GType gm_text_smiley_get_type () G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __GM_TEXT_SMILEY_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]