gtkhtml r9060 - in trunk: . components/editor gtkhtml
- From: mbarnes svn gnome org
- To: svn-commits-list gnome org
- Subject: gtkhtml r9060 - in trunk: . components/editor gtkhtml
- Date: Tue, 9 Dec 2008 18:30:21 +0000 (UTC)
Author: mbarnes
Date: Tue Dec 9 18:30:21 2008
New Revision: 9060
URL: http://svn.gnome.org/viewvc/gtkhtml?rev=9060&view=rev
Log:
2008-12-09 Matthew Barnes <mbarnes redhat com>
** Fixes bug #563841
* configure.in:
Bump gnome_icon_theme_minimum_version to 2.22.0 to pick up
new "face" icons.
* gtkhtml/htmlengine-edit-cut-and-paste.c (use_pictograms):
Refresh the pictogram parser. Use standard icon names for
smiley faces and recognize more of them.
* components/editor/gtkhtml-editor.ui:
Replace "insert-face-menu" with "insert-face" and also add
it to the HTML toolbar. "insert-face" is a GtkhtmlFaceAction,
which appears as a GtkhtmlFaceChooserMenu or GtkhtmlFaceToolButton.
* components/editor/gtkhtml-editor-actions.c:
Rewrite the insert face action callbacks. Only a single
callback is needed now. Selected face is obtained through
gtkhtml_face_chooser_get_current_face().
* components/editor/gtkhtml-face.c:
* components/editor/gtkhtml-face.h:
New boxed type for dealing with face icons.
* components/editor/gtkhtml-face-chooser.c:
* components/editor/gtkhtml-face-chooser.h:
New interface for choosing a smiley face from a list or table.
Patterned after GtkRecentChooser.
* components/editor/gtkhtml-face-action.c:
* components/editor/gtkhtml-face-action.h:
New GtkAction subclass for choosing from a predefined set of
smiley faces. Patterned after GtkRecentAction. Implements
the GtkhtmlFaceChooser interface.
* components/editor/gtkhtml-face-chooser-menu.c:
* components/editor/gtkhtml-face-chooser-menu.h:
New GtkMenu subclass implements of a menu of smiley faces.
Implements the GtkhtmlFaceChooser interface.
* components/editor/gtkhtml-face-tool-button.c:
* components/editor/gtkhtml-face-tool-button.h:
New GtkToggleToolButton subclass implements a popup smiley face
palette for use in toolbars. Implements the GtkhtmlFaceChooser
interface.
Added:
trunk/components/editor/gtkhtml-face-action.c
trunk/components/editor/gtkhtml-face-action.h
trunk/components/editor/gtkhtml-face-chooser-menu.c
trunk/components/editor/gtkhtml-face-chooser-menu.h
trunk/components/editor/gtkhtml-face-chooser.c
trunk/components/editor/gtkhtml-face-chooser.h
trunk/components/editor/gtkhtml-face-tool-button.c
trunk/components/editor/gtkhtml-face-tool-button.h
trunk/components/editor/gtkhtml-face.c
trunk/components/editor/gtkhtml-face.h
Modified:
trunk/ChangeLog
trunk/components/editor/ChangeLog
trunk/components/editor/Makefile.am
trunk/components/editor/gtkhtml-editor-actions.c
trunk/components/editor/gtkhtml-editor-private.h
trunk/components/editor/gtkhtml-editor.ui
trunk/configure.in
trunk/gtkhtml/ChangeLog
trunk/gtkhtml/htmlengine-edit-cut-and-paste.c
Modified: trunk/components/editor/Makefile.am
==============================================================================
--- trunk/components/editor/Makefile.am (original)
+++ trunk/components/editor/Makefile.am Tue Dec 9 18:30:21 2008
@@ -42,6 +42,16 @@
gtkhtml-editor-private.h \
gtkhtml-editor-signals.c \
gtkhtml-editor-signals.h \
+ gtkhtml-face.c \
+ gtkhtml-face.h \
+ gtkhtml-face-action.c \
+ gtkhtml-face-action.h \
+ gtkhtml-face-chooser.c \
+ gtkhtml-face-chooser.h \
+ gtkhtml-face-chooser-menu.c \
+ gtkhtml-face-chooser-menu.h \
+ gtkhtml-face-tool-button.c \
+ gtkhtml-face-tool-button.h \
gtkhtml-spell-dialog.c \
gtkhtml-spell-dialog.h \
gtkhtml-spell-checker.c \
Modified: trunk/components/editor/gtkhtml-editor-actions.c
==============================================================================
--- trunk/components/editor/gtkhtml-editor-actions.c (original)
+++ trunk/components/editor/gtkhtml-editor-actions.c Tue Dec 9 18:30:21 2008
@@ -213,43 +213,6 @@
}
static void
-insert_emoticon (GtkhtmlEditor *editor,
- GtkAction *action,
- const gchar *alt)
-{
- GtkHTML *html;
- HTMLObject *image;
- GtkIconInfo *icon_info;
- const gchar *filename;
- gchar *icon_name;
- gchar *uri = NULL;
-
- html = gtkhtml_editor_get_html (editor);
-
- g_object_get (action, "icon-name", &icon_name, NULL);
- icon_info = gtk_icon_theme_lookup_icon (
- gtk_icon_theme_get_default (), icon_name, 16, 0);
- g_free (icon_name);
- g_return_if_fail (icon_info != NULL);
-
- filename = gtk_icon_info_get_filename (icon_info);
- if (filename != NULL)
- uri = g_filename_to_uri (filename, NULL, NULL);
- gtk_icon_info_free (icon_info);
- g_return_if_fail (uri != NULL);
-
- image = html_image_new (
- html_engine_get_image_factory (html->engine),
- uri, NULL, NULL, -1, -1, FALSE, FALSE, 0, NULL,
- HTML_VALIGN_MIDDLE, FALSE);
- html_image_set_alt (HTML_IMAGE (image), alt);
- html_engine_paste_object (
- html->engine, image, html_object_get_length (image));
-
- g_free (uri);
-}
-
-static void
insert_text_file_response_cb (GtkFileChooser *file_chooser,
gint response,
GtkhtmlEditor *editor)
@@ -626,6 +589,47 @@
}
static void
+action_insert_face_cb (GtkhtmlFaceAction *action,
+ GtkhtmlEditor *editor)
+{
+ GtkHTML *html;
+ HTMLObject *image;
+ GtkIconInfo *icon_info;
+ GtkIconTheme *icon_theme;
+ GtkhtmlFaceChooser *chooser;
+ GtkhtmlFace *face;
+ const gchar *filename;
+ gchar *uri = NULL;
+
+ html = gtkhtml_editor_get_html (editor);
+
+ chooser = GTKHTML_FACE_CHOOSER (action);
+ face = gtkhtml_face_chooser_get_current_face (chooser);
+ g_return_if_fail (face != NULL);
+
+ icon_theme = gtk_icon_theme_get_default ();
+ icon_info = gtk_icon_theme_lookup_icon (
+ icon_theme, face->icon_name, 16, 0);
+ g_return_if_fail (icon_info != NULL);
+
+ filename = gtk_icon_info_get_filename (icon_info);
+ if (filename != NULL)
+ uri = g_filename_to_uri (filename, NULL, NULL);
+ gtk_icon_info_free (icon_info);
+ g_return_if_fail (uri != NULL);
+
+ image = html_image_new (
+ html_engine_get_image_factory (html->engine),
+ uri, NULL, NULL, -1, -1, FALSE, FALSE, 0, NULL,
+ HTML_VALIGN_MIDDLE, FALSE);
+ html_image_set_alt (HTML_IMAGE (image), face->text_face);
+ html_engine_paste_object (
+ html->engine, image, html_object_get_length (image));
+
+ g_free (uri);
+}
+
+static void
action_insert_html_file_cb (GtkToggleAction *action,
GtkhtmlEditor *editor)
{
@@ -666,125 +670,6 @@
}
static void
-action_insert_face_angel_cb (GtkAction *action,
- GtkhtmlEditor *editor)
-{
- insert_emoticon (editor, action, "O:-)");
-}
-
-static void
-action_insert_face_cool_cb (GtkAction *action,
- GtkhtmlEditor *editor)
-{
- insert_emoticon (editor, action, "B-)");
-}
-
-static void
-action_insert_face_crying_cb (GtkAction *action,
- GtkhtmlEditor *editor)
-{
- insert_emoticon (editor, action, ":'(");
-}
-
-static void
-action_insert_face_devilish_cb (GtkAction *action,
- GtkhtmlEditor *editor)
-{
- insert_emoticon (editor, action, ">:-)");
-}
-
-static void
-action_insert_face_embarrassed_cb (GtkAction *action,
- GtkhtmlEditor *editor)
-{
- insert_emoticon (editor, action, ":\"-)");
-}
-
-static void
-action_insert_face_kiss_cb (GtkAction *action,
- GtkhtmlEditor *editor)
-{
- insert_emoticon (editor, action, ":-*");
-}
-
-static void
-action_insert_face_monkey_cb (GtkAction *action,
- GtkhtmlEditor *editor)
-{
- insert_emoticon (editor, action, ":-(|)");
-}
-
-static void
-action_insert_face_plain_cb (GtkAction *action,
- GtkhtmlEditor *editor)
-{
- insert_emoticon (editor, action, ":-|");
-}
-
-static void
-action_insert_face_raspberry_cb (GtkAction *action,
- GtkhtmlEditor *editor)
-{
- insert_emoticon (editor, action, ":-P");
-}
-
-static void
-action_insert_face_sad_cb (GtkAction *action,
- GtkhtmlEditor *editor)
-{
- insert_emoticon (editor, action, ":-(");
-}
-
-static void
-action_insert_face_smile_cb (GtkAction *action,
- GtkhtmlEditor *editor)
-{
- insert_emoticon (editor, action, ":-)");
-}
-
-static void
-action_insert_face_smile_big_cb (GtkAction *action,
- GtkhtmlEditor *editor)
-{
- insert_emoticon (editor, action, ":-D");
-}
-
-static void
-action_insert_face_smirk_cb (GtkAction *action,
- GtkhtmlEditor *editor)
-{
- insert_emoticon (editor, action, ":-!");
-}
-
-static void
-action_insert_face_surprise_cb (GtkAction *action,
- GtkhtmlEditor *editor)
-{
- insert_emoticon (editor, action, ":-O");
-}
-
-static void
-action_insert_face_wink_cb (GtkAction *action,
- GtkhtmlEditor *editor)
-{
- insert_emoticon (editor, action, ";-)");
-}
-
-static void
-action_insert_smiley_9_cb (GtkAction *action,
- GtkhtmlEditor *editor)
-{
- insert_emoticon (editor, action, ":-/");
-}
-
-static void
-action_insert_smiley_26_cb (GtkAction *action,
- GtkhtmlEditor *editor)
-{
- insert_emoticon (editor, action, ":-Q");
-}
-
-static void
action_insert_table_cb (GtkAction *action,
GtkhtmlEditor *editor)
{
@@ -1345,125 +1230,6 @@
NULL,
G_CALLBACK (action_insert_html_file_cb) },
- { "insert-face-angel",
- "face-angel",
- N_("_Angel"),
- NULL,
- NULL,
- G_CALLBACK (action_insert_face_angel_cb) },
-
- { "insert-face-cool",
- "face-cool",
- N_("_Cool"),
- NULL,
- NULL,
- G_CALLBACK (action_insert_face_cool_cb) },
-
- { "insert-face-crying",
- "face-crying",
- N_("Cr_ying"),
- NULL,
- NULL,
- G_CALLBACK (action_insert_face_crying_cb) },
-
- { "insert-face-devilish",
- "face-devilish",
- N_("_Devilish"),
- NULL,
- NULL,
- G_CALLBACK (action_insert_face_devilish_cb) },
-
- { "insert-face-embarrassed",
- "face-embarrassed",
- N_("_Embarrassed"),
- NULL,
- NULL,
- G_CALLBACK (action_insert_face_embarrassed_cb) },
-
- { "insert-face-kiss",
- "face-kiss",
- N_("_Kiss"),
- NULL,
- NULL,
- G_CALLBACK (action_insert_face_kiss_cb) },
-
- { "insert-face-monkey",
- "face-monkey",
- N_("_Monkey"),
- NULL,
- NULL,
- G_CALLBACK (action_insert_face_monkey_cb) },
-
- { "insert-face-plain",
- "face-plain",
- N_("_Indifferent"),
- NULL,
- NULL,
- G_CALLBACK (action_insert_face_plain_cb) },
-
- { "insert-face-raspberry",
- "face-raspberry",
- N_("_Tongue"),
- NULL,
- NULL,
- G_CALLBACK (action_insert_face_raspberry_cb) },
-
- { "insert-face-sad",
- "face-sad",
- N_("_Frown"),
- NULL,
- NULL,
- G_CALLBACK (action_insert_face_sad_cb) },
-
- { "insert-face-smile",
- "face-smile",
- N_("_Smile"),
- NULL,
- NULL,
- G_CALLBACK (action_insert_face_smile_cb) },
-
- { "insert-face-smile-big",
- "face-smile-big",
- N_("_Laughing"),
- NULL,
- NULL,
- G_CALLBACK (action_insert_face_smile_big_cb) },
-
- { "insert-face-smirk",
- "face-smirk",
- N_("Smi_rk"),
- NULL,
- NULL,
- G_CALLBACK (action_insert_face_smirk_cb) },
-
- { "insert-face-surprise",
- "face-surprise",
- N_("Sur_prised"),
- NULL,
- NULL,
- G_CALLBACK (action_insert_face_surprise_cb) },
-
- { "insert-face-wink",
- "face-wink",
- N_("_Wink"),
- NULL,
- NULL,
- G_CALLBACK (action_insert_face_wink_cb) },
-
- { "insert-smiley-9",
- "stock_smiley-9",
- N_("_Undecided"),
- NULL,
- NULL,
- G_CALLBACK (action_insert_smiley_9_cb) },
-
- { "insert-smiley-26",
- "stock_smiley-26",
- N_("S_ick"),
- NULL,
- NULL,
- G_CALLBACK (action_insert_smiley_26_cb) },
-
{ "insert-text-file",
NULL,
N_("Te_xt File..."),
@@ -1578,13 +1344,6 @@
NULL,
NULL },
- { "insert-face-menu",
- NULL,
- N_("_Emoticon"),
- NULL,
- NULL,
- NULL },
-
{ "insert-menu",
NULL,
N_("_Insert"),
@@ -2291,6 +2050,7 @@
void
gtkhtml_editor_actions_init (GtkhtmlEditor *editor)
{
+ GtkAction *action;
GtkActionGroup *action_group;
GtkUIManager *manager;
const gchar *domain;
@@ -2323,6 +2083,16 @@
G_CALLBACK (action_style_cb), editor);
gtk_ui_manager_insert_action_group (manager, action_group, 0);
+ /* Face Action */
+ action = gtkhtml_face_action_new (
+ "insert-face", _("_Emoticon"),
+ _("Insert Emoticon"), NULL);
+ g_object_set (action, "icon-name", "face-smile", NULL);
+ g_signal_connect (
+ action, "item-activated",
+ G_CALLBACK (action_insert_face_cb), editor);
+ gtk_action_group_add_action (action_group, action);
+
/* Core Actions (HTML only) */
action_group = editor->priv->html_actions;
gtk_action_group_set_translation_domain (action_group, domain);
Modified: trunk/components/editor/gtkhtml-editor-private.h
==============================================================================
--- trunk/components/editor/gtkhtml-editor-private.h (original)
+++ trunk/components/editor/gtkhtml-editor-private.h Tue Dec 9 18:30:21 2008
@@ -31,6 +31,8 @@
#include "gtkhtml-color-palette.h"
#include "gtkhtml-color-swatch.h"
#include "gtkhtml-combo-box.h"
+#include "gtkhtml-face-action.h"
+#include "gtkhtml-face-chooser.h"
#include "gtkhtml-spell-dialog.h"
/* GtkHTML internals */
Modified: trunk/components/editor/gtkhtml-editor.ui
==============================================================================
--- trunk/components/editor/gtkhtml-editor.ui (original)
+++ trunk/components/editor/gtkhtml-editor.ui Tue Dec 9 18:30:21 2008
@@ -34,18 +34,7 @@
<menuitem action='insert-table'/>
<menuitem action='insert-text-file'/>
<menuitem action='insert-html-file'/>
- <menu action='insert-face-menu'>
- <menuitem action='insert-face-smile'/>
- <menuitem action='insert-face-surprise'/>
- <menuitem action='insert-face-wink'/>
- <menuitem action='insert-face-sad'/>
- <menuitem action='insert-face-smile-big'/>
- <menuitem action='insert-face-plain'/>
- <menuitem action='insert-smiley-9'/>
- <menuitem action='insert-face-raspberry'/>
- <menuitem action='insert-face-crying'/>
- <menuitem action='insert-smiley-26'/>
- </menu>
+ <menuitem action='insert-face'/>
</menu>
<placeholder name='pre-format-menu'/>
<menu action='format-menu'>
@@ -135,6 +124,7 @@
<toolitem action='insert-link'/>
<toolitem action='insert-rule'/>
<toolitem action='insert-table'/>
+ <toolitem action='insert-face'/>
</toolbar>
<popup name='context-menu'>
<placeholder name='context-spell-suggest'/>
Added: trunk/components/editor/gtkhtml-face-action.c
==============================================================================
--- (empty file)
+++ trunk/components/editor/gtkhtml-face-action.c Tue Dec 9 18:30:21 2008
@@ -0,0 +1,300 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gtkhtml-face-action.c
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "gtkhtml-face-action.h"
+
+#include "gtkhtml-face-chooser-menu.h"
+#include "gtkhtml-face-tool-button.h"
+
+#define GTKHTML_FACE_ACTION_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), GTKHTML_TYPE_FACE_ACTION, GtkhtmlFaceActionPrivate))
+
+struct _GtkhtmlFaceActionPrivate {
+ GList *choosers;
+ GtkhtmlFaceChooser *current_chooser;
+};
+
+enum {
+ PROP_0,
+ PROP_CURRENT_FACE
+};
+
+static gpointer parent_class;
+
+static void
+face_action_proxy_item_activated_cb (GtkhtmlFaceAction *action,
+ GtkhtmlFaceChooser *chooser)
+{
+ action->priv->current_chooser = chooser;
+
+ g_signal_emit_by_name (action, "item-activated");
+}
+
+static void
+face_action_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CURRENT_FACE:
+ gtkhtml_face_chooser_set_current_face (
+ GTKHTML_FACE_CHOOSER (object),
+ g_value_get_boxed (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+face_action_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CURRENT_FACE:
+ g_value_set_boxed (
+ value, gtkhtml_face_chooser_get_current_face (
+ GTKHTML_FACE_CHOOSER (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+face_action_finalize (GObject *object)
+{
+ GtkhtmlFaceActionPrivate *priv;
+
+ priv = GTKHTML_FACE_ACTION_GET_PRIVATE (object);
+
+ g_list_free (priv->choosers);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+face_action_activate (GtkAction *action)
+{
+ GtkhtmlFaceActionPrivate *priv;
+
+ priv = GTKHTML_FACE_ACTION_GET_PRIVATE (action);
+
+ priv->current_chooser = NULL;
+}
+
+static GtkWidget *
+face_action_create_menu_item (GtkAction *action)
+{
+ GtkWidget *item;
+ GtkWidget *menu;
+
+ item = gtk_image_menu_item_new ();
+ menu = gtk_action_create_menu (action);
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), menu);
+ gtk_widget_show (menu);
+
+ return item;
+}
+
+static GtkWidget *
+face_action_create_tool_item (GtkAction *action)
+{
+ return GTK_WIDGET (gtkhtml_face_tool_button_new ());
+}
+
+static void
+face_action_connect_proxy (GtkAction *action,
+ GtkWidget *proxy)
+{
+ GtkhtmlFaceActionPrivate *priv;
+
+ priv = GTKHTML_FACE_ACTION_GET_PRIVATE (action);
+
+ if (!GTKHTML_IS_FACE_CHOOSER (proxy))
+ goto chainup;
+
+ if (g_list_find (priv->choosers, proxy) != NULL)
+ goto chainup;
+
+ g_signal_connect_swapped (
+ proxy, "item-activated",
+ G_CALLBACK (face_action_proxy_item_activated_cb), action);
+
+chainup:
+ /* Chain up to parent's connect_proxy() method. */
+ GTK_ACTION_CLASS (parent_class)->connect_proxy (action, proxy);
+}
+
+static void
+face_action_disconnect_proxy (GtkAction *action,
+ GtkWidget *proxy)
+{
+ GtkhtmlFaceActionPrivate *priv;
+
+ priv = GTKHTML_FACE_ACTION_GET_PRIVATE (action);
+
+ priv->choosers = g_list_remove (priv->choosers, proxy);
+
+ /* Chain up to parent's disconnect_proxy() method. */
+ GTK_ACTION_CLASS (parent_class)->disconnect_proxy (action, proxy);
+}
+
+static GtkWidget *
+face_action_create_menu (GtkAction *action)
+{
+ GtkhtmlFaceActionPrivate *priv;
+ GtkWidget *widget;
+
+ priv = GTKHTML_FACE_ACTION_GET_PRIVATE (action);
+
+ widget = gtkhtml_face_chooser_menu_new ();
+
+ g_signal_connect_swapped (
+ widget, "item-activated",
+ G_CALLBACK (face_action_proxy_item_activated_cb), action);
+
+ priv->choosers = g_list_prepend (priv->choosers, widget);
+
+ return widget;
+}
+
+static GtkhtmlFace *
+face_action_get_current_face (GtkhtmlFaceChooser *chooser)
+{
+ GtkhtmlFaceActionPrivate *priv;
+ GtkhtmlFace *face = NULL;
+
+ priv = GTKHTML_FACE_ACTION_GET_PRIVATE (chooser);
+
+ if (priv->current_chooser != NULL)
+ face = gtkhtml_face_chooser_get_current_face (
+ priv->current_chooser);
+
+ return face;
+}
+
+static void
+face_action_set_current_face (GtkhtmlFaceChooser *chooser,
+ GtkhtmlFace *face)
+{
+ GtkhtmlFaceActionPrivate *priv;
+ GList *iter;
+
+ priv = GTKHTML_FACE_ACTION_GET_PRIVATE (chooser);
+
+ for (iter = priv->choosers; iter != NULL; iter = iter->next) {
+ GtkhtmlFaceChooser *proxy_chooser = iter->data;
+
+ gtkhtml_face_chooser_set_current_face (proxy_chooser, face);
+ }
+}
+
+static void
+face_action_class_init (GtkhtmlFaceActionClass *class)
+{
+ GObjectClass *object_class;
+ GtkActionClass *action_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (GtkhtmlFaceAction));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = face_action_set_property;
+ object_class->get_property = face_action_get_property;
+ object_class->finalize = face_action_finalize;
+
+ action_class = GTK_ACTION_CLASS (class);
+ action_class->activate = face_action_activate;
+ action_class->create_menu_item = face_action_create_menu_item;
+ action_class->create_tool_item = face_action_create_tool_item;
+ action_class->connect_proxy = face_action_connect_proxy;
+ action_class->disconnect_proxy = face_action_disconnect_proxy;
+ action_class->create_menu = face_action_create_menu;
+
+ g_object_class_override_property (
+ object_class, PROP_CURRENT_FACE, "current-face");
+}
+
+static void
+face_action_iface_init (GtkhtmlFaceChooserIface *iface)
+{
+ iface->get_current_face = face_action_get_current_face;
+ iface->set_current_face = face_action_set_current_face;
+}
+
+static void
+face_action_init (GtkhtmlFaceAction *action)
+{
+ action->priv = GTKHTML_FACE_ACTION_GET_PRIVATE (action);
+}
+
+GType
+gtkhtml_face_action_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (GtkhtmlFaceActionClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) face_action_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (GtkhtmlFaceAction),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) face_action_init,
+ NULL /* value_table */
+ };
+
+ static const GInterfaceInfo iface_info = {
+ (GInterfaceInitFunc) face_action_iface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface_data */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_ACTION, "GtkhtmlFaceAction", &type_info, 0);
+
+ g_type_add_interface_static (
+ type, GTKHTML_TYPE_FACE_CHOOSER, &iface_info);
+ }
+
+ return type;
+}
+
+GtkAction *
+gtkhtml_face_action_new (const gchar *name,
+ const gchar *label,
+ const gchar *tooltip,
+ const gchar *stock_id)
+{
+ g_return_val_if_fail (name != NULL, NULL);
+
+ return g_object_new (
+ GTKHTML_TYPE_FACE_ACTION, "name", name, "label", label,
+ "tooltip", tooltip, "stock-id", stock_id, NULL);
+}
Added: trunk/components/editor/gtkhtml-face-action.h
==============================================================================
--- (empty file)
+++ trunk/components/editor/gtkhtml-face-action.h Tue Dec 9 18:30:21 2008
@@ -0,0 +1,68 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gtkhtml-face-action.h
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GTKHTML_FACE_ACTION_H
+#define GTKHTML_FACE_ACTION_H
+
+#include "gtkhtml-editor-common.h"
+
+/* Standard GObject macros */
+#define GTKHTML_TYPE_FACE_ACTION \
+ (gtkhtml_face_action_get_type ())
+#define GTKHTML_FACE_ACTION(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), GTKHTML_TYPE_FACE_ACTION, GtkhtmlFaceAction))
+#define GTKHTML_FACE_ACTION_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), GTKHTML_TYPE_FACE_ACTION, GtkhtmlFaceActionClass))
+#define GTKHTML_IS_FACE_ACTION(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), GTKHTML_TYPE_FACE_ACTION))
+#define GTKHTML_IS_FACE_ACTION_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), GTKHTML_TYPE_FACE_ACTION))
+#define GTKHTML_FACE_ACTION_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), GTKHTML_TYPE_FACE_ACTION, GtkhtmlFaceActionClass))
+
+G_BEGIN_DECLS
+
+typedef struct _GtkhtmlFaceAction GtkhtmlFaceAction;
+typedef struct _GtkhtmlFaceActionClass GtkhtmlFaceActionClass;
+typedef struct _GtkhtmlFaceActionPrivate GtkhtmlFaceActionPrivate;
+
+struct _GtkhtmlFaceAction {
+ GtkAction parent;
+ GtkhtmlFaceActionPrivate *priv;
+};
+
+struct _GtkhtmlFaceActionClass {
+ GtkActionClass parent_class;
+};
+
+GType gtkhtml_face_action_get_type (void);
+GtkAction * gtkhtml_face_action_new (const gchar *name,
+ const gchar *label,
+ const gchar *tooltip,
+ const gchar *stock_id);
+
+G_END_DECLS
+
+#endif /* GTKHTML_FACE_ACTION_H */
Added: trunk/components/editor/gtkhtml-face-chooser-menu.c
==============================================================================
--- (empty file)
+++ trunk/components/editor/gtkhtml-face-chooser-menu.c Tue Dec 9 18:30:21 2008
@@ -0,0 +1,219 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gtkhtml-face-chooser-menu.c
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "gtkhtml-face-chooser-menu.h"
+
+#define GTKHTML_FACE_CHOOSER_MENU_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), GTKHTML_TYPE_FACE_CHOOSER_MENU, GtkhtmlFaceChooserMenuPrivate))
+
+struct _GtkhtmlFaceChooserMenuPrivate {
+ gint dummy;
+};
+
+enum {
+ PROP_0,
+ PROP_CURRENT_FACE
+};
+
+static gpointer parent_class;
+
+static void
+face_chooser_menu_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CURRENT_FACE:
+ gtkhtml_face_chooser_set_current_face (
+ GTKHTML_FACE_CHOOSER (object),
+ g_value_get_boxed (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+face_chooser_menu_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CURRENT_FACE:
+ g_value_set_boxed (
+ value,
+ gtkhtml_face_chooser_get_current_face (
+ GTKHTML_FACE_CHOOSER (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static GtkhtmlFace *
+face_chooser_menu_get_current_face (GtkhtmlFaceChooser *chooser)
+{
+ GtkhtmlFaceChooserMenuPrivate *priv;
+ GtkWidget *item;
+
+ priv = GTKHTML_FACE_CHOOSER_MENU_GET_PRIVATE (chooser);
+
+ item = gtk_menu_get_active (GTK_MENU (chooser));
+ if (item == NULL)
+ return NULL;
+
+ return g_object_get_data (G_OBJECT (item), "face");
+}
+
+static void
+face_chooser_menu_set_current_face (GtkhtmlFaceChooser *chooser,
+ GtkhtmlFace *face)
+{
+ GtkhtmlFaceChooserMenuPrivate *priv;
+ GList *list, *iter;
+
+ priv = GTKHTML_FACE_CHOOSER_MENU_GET_PRIVATE (chooser);
+
+ list = gtk_container_get_children (GTK_CONTAINER (chooser));
+
+ for (iter = list; iter != NULL; iter = iter->next) {
+ GtkWidget *item = iter->data;
+ GtkhtmlFace *candidate;
+
+ candidate = g_object_get_data (G_OBJECT (item), "face");
+ if (candidate == NULL)
+ continue;
+
+ if (gtkhtml_face_equal (face, candidate)) {
+ gtk_menu_shell_activate_item (
+ GTK_MENU_SHELL (chooser), item, TRUE);
+ break;
+ }
+ }
+
+ g_list_free (list);
+}
+
+static void
+face_chooser_menu_class_init (GtkhtmlFaceChooserMenuClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (GtkhtmlFaceChooserMenuPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = face_chooser_menu_set_property;
+ object_class->get_property = face_chooser_menu_get_property;
+
+ g_object_class_override_property (
+ object_class, PROP_CURRENT_FACE, "current-face");
+}
+
+static void
+face_chooser_menu_iface_init (GtkhtmlFaceChooserIface *iface)
+{
+ iface->get_current_face = face_chooser_menu_get_current_face;
+ iface->set_current_face = face_chooser_menu_set_current_face;
+}
+
+static void
+face_chooser_menu_init (GtkhtmlFaceChooserMenu *chooser_menu)
+{
+ GtkhtmlFaceChooser *chooser;
+ GList *list, *iter;
+
+ chooser_menu->priv =
+ GTKHTML_FACE_CHOOSER_MENU_GET_PRIVATE (chooser_menu);
+
+ chooser = GTKHTML_FACE_CHOOSER (chooser_menu);
+ list = gtkhtml_face_chooser_get_items (chooser);
+
+ for (iter = list; iter != NULL; iter = iter->next) {
+ GtkhtmlFace *face = iter->data;
+ GtkWidget *item;
+
+ item = gtk_image_menu_item_new_with_mnemonic (face->label);
+ gtk_image_menu_item_set_image (
+ GTK_IMAGE_MENU_ITEM (item),
+ gtk_image_new_from_icon_name (
+ face->icon_name, GTK_ICON_SIZE_MENU));
+ gtk_widget_show (item);
+
+ g_object_set_data_full (
+ G_OBJECT (item), "face",
+ gtkhtml_face_copy (face),
+ (GDestroyNotify) gtkhtml_face_free);
+
+ g_signal_connect_swapped (
+ item, "activate",
+ G_CALLBACK (gtkhtml_face_chooser_item_activated),
+ chooser);
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (chooser_menu), item);
+ }
+
+ g_list_free (list);
+}
+
+GType
+gtkhtml_face_chooser_menu_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (GtkhtmlFaceChooserMenuClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) face_chooser_menu_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (GtkhtmlFaceChooserMenu),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) face_chooser_menu_init,
+ NULL /* value_table */
+ };
+
+ static const GInterfaceInfo iface_info = {
+ (GInterfaceInitFunc) face_chooser_menu_iface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface_data */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_MENU, "GtkhtmlFileChooserMenu",
+ &type_info, 0);
+
+ g_type_add_interface_static (
+ type, GTKHTML_TYPE_FACE_CHOOSER, &iface_info);
+ }
+
+ return type;
+}
+
+GtkWidget *
+gtkhtml_face_chooser_menu_new (void)
+{
+ return g_object_new (GTKHTML_TYPE_FACE_CHOOSER_MENU, NULL);
+}
Added: trunk/components/editor/gtkhtml-face-chooser-menu.h
==============================================================================
--- (empty file)
+++ trunk/components/editor/gtkhtml-face-chooser-menu.h Tue Dec 9 18:30:21 2008
@@ -0,0 +1,66 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gtkhtml-face-chooser-menu.h
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GTKHTML_FACE_CHOOSER_MENU_H
+#define GTKHTML_FACE_CHOOSER_MENU_H
+
+#include "gtkhtml-editor-common.h"
+#include "gtkhtml-face-chooser.h"
+
+/* Standard GObject macros */
+#define GTKHTML_TYPE_FACE_CHOOSER_MENU \
+ (gtkhtml_face_chooser_menu_get_type ())
+#define GTKHTML_FACE_CHOOSER_MENU(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), GTKHTML_TYPE_FACE_CHOOSER_MENU, GtkhtmlFaceChooserMenu))
+#define GTKHTML_FACE_CHOOSER_MENU_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), GTKHTML_TYPE_FACE_CHOOSER_MENU, GtkhtmlFaceChooserMenuClass))
+#define GTKHTML_IS_FACE_CHOOSER_MENU(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), GTKHTML_TYPE_FACE_CHOOSER_MENU))
+#define GTKHTML_IS_FACE_CHOOSER_MENU_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), GTKHTML_TYPE_FACE_CHOOSER_MENU))
+#define GTKHTML_FACE_CHOOSER_MENU_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), GTKHTML_TYPE_FACE_CHOOSER_MENU, GtkhtmlFaceChooserMenuClass))
+
+G_BEGIN_DECLS
+
+typedef struct _GtkhtmlFaceChooserMenu GtkhtmlFaceChooserMenu;
+typedef struct _GtkhtmlFaceChooserMenuClass GtkhtmlFaceChooserMenuClass;
+typedef struct _GtkhtmlFaceChooserMenuPrivate GtkhtmlFaceChooserMenuPrivate;
+
+struct _GtkhtmlFaceChooserMenu {
+ GtkMenu parent;
+ GtkhtmlFaceChooserMenuPrivate *priv;
+};
+
+struct _GtkhtmlFaceChooserMenuClass {
+ GtkMenuClass parent_class;
+};
+
+GType gtkhtml_face_chooser_menu_get_type (void);
+GtkWidget * gtkhtml_face_chooser_menu_new (void);
+
+G_END_DECLS
+
+#endif /* GTKHTML_FACE_CHOOSER_MENU_H */
Added: trunk/components/editor/gtkhtml-face-chooser.c
==============================================================================
--- (empty file)
+++ trunk/components/editor/gtkhtml-face-chooser.c Tue Dec 9 18:30:21 2008
@@ -0,0 +1,151 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gtkhtml-face-chooser.c
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "gtkhtml-face-chooser.h"
+
+#include <glib/gi18n-lib.h>
+
+static GtkhtmlFace available_faces[] = {
+ { N_("_Smile"), "face-smile", ":-)" },
+ { N_("S_ad"), "face-sad", ":-(" },
+ { N_("_Wink"), "face-wink", ";-)" },
+ { N_("Ton_gue"), "face-raspberry", ":-P" },
+ { N_("Laug_h"), "face-laugh", ":-))" },
+ { N_("_Plain"), "face-plain", ":-|" },
+ { N_("Smi_rk"), "face-smirk", ":-!" },
+ { N_("_Embarrassed"), "face-embarrassed", ":\"-)" },
+ { N_("_Big Smile"), "face-smile-big", ":-D" },
+ { N_("Uncer_tain"), "face-uncertain", ":-/" },
+ { N_("S_urprise"), "face-surprise", ":-O" },
+ { N_("W_orried"), "face-worried", ":-S" },
+ { N_("_Kiss"), "face-kiss", ":-*" },
+ { N_("A_ngry"), "face-angry", "X-(" },
+ { N_("_Cool"), "face-cool", "B-)" },
+ { N_("Ange_l"), "face-angel", "O:-)" },
+ { N_("Cr_ying"), "face-crying", ":'(" },
+ { N_("S_ick"), "face-sick", ":-Q" },
+ { N_("Tire_d"), "face-tired", "|-)" },
+ { N_("De_vilish"), "face-devilish", ">:-)" },
+ { N_("_Monkey"), "face-monkey", ":-(|)" }
+};
+
+enum {
+ ITEM_ACTIVATED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+static void
+face_chooser_class_init (GtkhtmlFaceChooserIface *iface)
+{
+ g_object_interface_install_property (
+ iface,
+ g_param_spec_boxed (
+ "current-face",
+ "Current Face",
+ "Currently selected face",
+ GTKHTML_TYPE_FACE,
+ G_PARAM_READWRITE));
+
+ signals[ITEM_ACTIVATED] = g_signal_new (
+ "item-activated",
+ G_TYPE_FROM_INTERFACE (iface),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GtkhtmlFaceChooserIface, item_activated),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+GType
+gtkhtml_face_chooser_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (GtkhtmlFaceChooserIface),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) face_chooser_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ 0, /* instance_size */
+ 0, /* n_preallocs */
+ NULL, /* instance_init */
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ G_TYPE_INTERFACE, "GtkhtmlFaceChooser", &type_info, 0);
+
+ g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
+ }
+
+ return type;
+}
+
+GtkhtmlFace *
+gtkhtml_face_chooser_get_current_face (GtkhtmlFaceChooser *chooser)
+{
+ GtkhtmlFaceChooserIface *iface;
+
+ g_return_val_if_fail (GTKHTML_IS_FACE_CHOOSER (chooser), NULL);
+
+ iface = GTKHTML_FACE_CHOOSER_GET_IFACE (chooser);
+ g_return_val_if_fail (iface->get_current_face != NULL, NULL);
+
+ return iface->get_current_face (chooser);
+}
+
+void
+gtkhtml_face_chooser_set_current_face (GtkhtmlFaceChooser *chooser,
+ GtkhtmlFace *face)
+{
+ GtkhtmlFaceChooserIface *iface;
+
+ g_return_if_fail (GTKHTML_IS_FACE_CHOOSER (chooser));
+
+ iface = GTKHTML_FACE_CHOOSER_GET_IFACE (chooser);
+ g_return_if_fail (iface->set_current_face != NULL);
+
+ iface->set_current_face (chooser, face);
+}
+
+void
+gtkhtml_face_chooser_item_activated (GtkhtmlFaceChooser *chooser)
+{
+ g_return_if_fail (GTKHTML_IS_FACE_CHOOSER (chooser));
+
+ g_signal_emit (chooser, signals[ITEM_ACTIVATED], 0);
+}
+
+GList *
+gtkhtml_face_chooser_get_items (GtkhtmlFaceChooser *chooser)
+{
+ GList *list = NULL;
+ gint ii;
+
+ for (ii = 0; ii < G_N_ELEMENTS (available_faces); ii++)
+ list = g_list_prepend (list, &available_faces[ii]);
+
+ return g_list_reverse (list);
+}
Added: trunk/components/editor/gtkhtml-face-chooser.h
==============================================================================
--- (empty file)
+++ trunk/components/editor/gtkhtml-face-chooser.h Tue Dec 9 18:30:21 2008
@@ -0,0 +1,69 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gtkhtml-face-chooser.h
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GTKHTML_FACE_CHOOSER_H
+#define GTKHTML_FACE_CHOOSER_H
+
+#include "gtkhtml-editor-common.h"
+#include "gtkhtml-face.h"
+
+/* Standard GObject macros */
+#define GTKHTML_TYPE_FACE_CHOOSER \
+ (gtkhtml_face_chooser_get_type ())
+#define GTKHTML_FACE_CHOOSER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), GTKHTML_TYPE_FACE_CHOOSER, GtkhtmlFaceChooser))
+#define GTKHTML_IS_FACE_CHOOSER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), GTKHTML_TYPE_FACE_CHOOSER))
+#define GTKHTML_FACE_CHOOSER_GET_IFACE(obj) \
+ (G_TYPE_INSTANCE_GET_INTERFACE \
+ ((obj), GTKHTML_TYPE_FACE_CHOOSER, GtkhtmlFaceChooserIface))
+
+G_BEGIN_DECLS
+
+typedef struct _GtkhtmlFaceChooser GtkhtmlFaceChooser;
+typedef struct _GtkhtmlFaceChooserIface GtkhtmlFaceChooserIface;
+
+struct _GtkhtmlFaceChooserIface {
+ GTypeInterface parent_iface;
+
+ /* Methods */
+ GtkhtmlFace * (*get_current_face) (GtkhtmlFaceChooser *chooser);
+ void (*set_current_face) (GtkhtmlFaceChooser *chooser,
+ GtkhtmlFace *face);
+
+ /* Signals */
+ void (*item_activated) (GtkhtmlFaceChooser *chooser);
+};
+
+GType gtkhtml_face_chooser_get_type (void);
+GtkhtmlFace * gtkhtml_face_chooser_get_current_face
+ (GtkhtmlFaceChooser *chooser);
+void gtkhtml_face_chooser_set_current_face
+ (GtkhtmlFaceChooser *chooser,
+ GtkhtmlFace *face);
+void gtkhtml_face_chooser_item_activated
+ (GtkhtmlFaceChooser *chooser);
+GList * gtkhtml_face_chooser_get_items (GtkhtmlFaceChooser *chooser);
+
+G_END_DECLS
+
+#endif /* GTKHTML_FACE_CHOOSER_H */
Added: trunk/components/editor/gtkhtml-face-tool-button.c
==============================================================================
--- (empty file)
+++ trunk/components/editor/gtkhtml-face-tool-button.c Tue Dec 9 18:30:21 2008
@@ -0,0 +1,675 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gtkhtml-face-tool-button.c
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "gtkhtml-face-tool-button.h"
+
+/* XXX The "button" aspects of this widget are based heavily on the
+ * GtkComboBox tree-view implementation. Consider splitting it
+ * into a reusable "button-with-an-empty-window" widget. */
+
+#include <string.h>
+#include <glib/gi18n-lib.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "gtkhtml-face-chooser.h"
+
+#define GTKHTML_FACE_TOOL_BUTTON_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), GTKHTML_TYPE_FACE_TOOL_BUTTON, GtkhtmlFaceToolButtonPrivate))
+
+/* XXX Should calculate this dynamically. */
+#define NUM_ROWS 7
+#define NUM_COLS 3
+
+enum {
+ PROP_0,
+ PROP_CURRENT_FACE,
+ PROP_POPUP_SHOWN
+};
+
+enum {
+ POPUP,
+ POPDOWN,
+ LAST_SIGNAL
+};
+
+struct _GtkhtmlFaceToolButtonPrivate {
+ GtkWidget *active_button; /* not referenced */
+ GtkWidget *table;
+ GtkWidget *window;
+
+ guint popup_shown : 1;
+ guint popup_in_progress : 1;
+};
+
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
+
+/* XXX Copied from _gtk_toolbar_elide_underscores() */
+static gchar *
+face_tool_button_elide_underscores (const gchar *original)
+{
+ gchar *q, *result;
+ const gchar *p, *end;
+ gsize len;
+ gboolean last_underscore;
+
+ if (!original)
+ return NULL;
+
+ len = strlen (original);
+ q = result = g_malloc (len + 1);
+ last_underscore = FALSE;
+
+ end = original + len;
+ for (p = original; p < end; p++) {
+ if (!last_underscore && *p == '_')
+ last_underscore = TRUE;
+ else {
+ last_underscore = FALSE;
+ if (original + 2 <= p && p + 1 <= end &&
+ p[-2] == '(' && p[-1] == '_' &&
+ p[0] != '_' && p[1] == ')') {
+ q--;
+ *q = '\0';
+ p++;
+ } else
+ *q++ = *p;
+ }
+ }
+
+ if (last_underscore)
+ *q++ = '_';
+
+ *q = '\0';
+
+ return result;
+}
+
+static void
+face_tool_button_reposition_window (GtkhtmlFaceToolButton *button)
+{
+ GdkScreen *screen;
+ GdkWindow *window;
+ GdkRectangle monitor;
+ gint monitor_num;
+ gint x, y, width, height;
+
+ window = GTK_WIDGET (button)->window;
+ screen = gtk_widget_get_screen (GTK_WIDGET (button));
+ monitor_num = gdk_screen_get_monitor_at_window (screen, window);
+ gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+
+ gdk_window_get_origin (window, &x, &y);
+
+ if (GTK_WIDGET_NO_WINDOW (button)) {
+ x += GTK_WIDGET (button)->allocation.x;
+ y += GTK_WIDGET (button)->allocation.y;
+ }
+
+ width = button->priv->window->allocation.width;
+ height = button->priv->window->allocation.height;
+
+ x = CLAMP (x, monitor.x, monitor.x + monitor.width - width);
+ y = CLAMP (y, monitor.y, monitor.y + monitor.height - height);
+
+ gtk_window_move (GTK_WINDOW (button->priv->window), x, y);
+}
+
+static void
+face_tool_button_face_clicked_cb (GtkhtmlFaceToolButton *button,
+ GtkWidget *face_button)
+{
+ button->priv->active_button = face_button;
+ gtkhtml_face_tool_button_popdown (button);
+}
+
+static gboolean
+face_tool_button_face_release_event_cb (GtkhtmlFaceToolButton *button,
+ GdkEventButton *event,
+ GtkButton *face_button)
+{
+ if (GTK_WIDGET_STATE (button) != GTK_STATE_NORMAL)
+ gtk_button_clicked (face_button);
+
+ return FALSE;
+}
+
+static gboolean
+face_tool_button_button_release_event_cb (GtkhtmlFaceToolButton *button,
+ GdkEventButton *event)
+{
+ GtkToggleToolButton *tool_button;
+ GtkWidget *event_widget;
+ gboolean popup_in_progress;
+
+ tool_button = GTK_TOGGLE_TOOL_BUTTON (button);
+ event_widget = gtk_get_event_widget ((GdkEvent *) event);
+
+ popup_in_progress = button->priv->popup_in_progress;
+ button->priv->popup_in_progress = FALSE;
+
+ if (event_widget != GTK_WIDGET (button))
+ goto popdown;
+
+ if (popup_in_progress)
+ return FALSE;
+
+ if (gtk_toggle_tool_button_get_active (tool_button))
+ goto popdown;
+
+ return FALSE;
+
+popdown:
+ gtkhtml_face_tool_button_popdown (button);
+
+ return TRUE;
+}
+
+static void
+face_tool_button_child_show_cb (GtkhtmlFaceToolButton *button)
+{
+ button->priv->popup_shown = TRUE;
+ g_object_notify (G_OBJECT (button), "popup-shown");
+}
+
+static void
+face_tool_button_child_hide_cb (GtkhtmlFaceToolButton *button)
+{
+ button->priv->popup_shown = FALSE;
+ g_object_notify (G_OBJECT (button), "popup-shown");
+}
+
+static gboolean
+face_tool_button_child_key_press_event_cb (GtkhtmlFaceToolButton *button,
+ GdkEventKey *event)
+{
+ GtkWidget *window = button->priv->window;
+
+ if (!gtk_bindings_activate_event (GTK_OBJECT (window), event))
+ gtk_bindings_activate_event (GTK_OBJECT (button), event);
+
+ return TRUE;
+}
+
+static void
+face_tool_button_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CURRENT_FACE:
+ gtkhtml_face_chooser_set_current_face (
+ GTKHTML_FACE_CHOOSER (object),
+ g_value_get_boxed (value));
+ return;
+
+ case PROP_POPUP_SHOWN:
+ if (g_value_get_boolean (value))
+ gtkhtml_face_tool_button_popup (
+ GTKHTML_FACE_TOOL_BUTTON (object));
+ else
+ gtkhtml_face_tool_button_popdown (
+ GTKHTML_FACE_TOOL_BUTTON (object));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+face_tool_button_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkhtmlFaceToolButtonPrivate *priv;
+
+ priv = GTKHTML_FACE_TOOL_BUTTON_GET_PRIVATE (object);
+
+ switch (property_id) {
+ case PROP_CURRENT_FACE:
+ g_value_set_boxed (
+ value,
+ gtkhtml_face_chooser_get_current_face (
+ GTKHTML_FACE_CHOOSER (object)));
+ return;
+
+ case PROP_POPUP_SHOWN:
+ g_value_set_boolean (value, priv->popup_shown);
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+face_tool_button_dispose (GObject *object)
+{
+ GtkhtmlFaceToolButtonPrivate *priv;
+
+ priv = GTKHTML_FACE_TOOL_BUTTON_GET_PRIVATE (object);
+
+ if (priv->window != NULL) {
+ g_object_unref (priv->window);
+ priv->window = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static gboolean
+face_tool_button_press_event (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ GtkhtmlFaceToolButton *button;
+ GtkToggleToolButton *toggle_button;
+ GtkWidget *event_widget;
+
+ button = GTKHTML_FACE_TOOL_BUTTON (widget);
+
+ event_widget = gtk_get_event_widget ((GdkEvent *) event);
+
+ if (event_widget == button->priv->window)
+ return TRUE;
+
+ if (event_widget != widget)
+ return FALSE;
+
+ toggle_button = GTK_TOGGLE_TOOL_BUTTON (widget);
+ if (gtk_toggle_tool_button_get_active (toggle_button))
+ return FALSE;
+
+ gtkhtml_face_tool_button_popup (button);
+
+ button->priv->popup_in_progress = TRUE;
+
+ return TRUE;
+}
+
+static void
+face_tool_button_toggled (GtkToggleToolButton *button)
+{
+ if (gtk_toggle_tool_button_get_active (button))
+ gtkhtml_face_tool_button_popup (
+ GTKHTML_FACE_TOOL_BUTTON (button));
+ else
+ gtkhtml_face_tool_button_popdown (
+ GTKHTML_FACE_TOOL_BUTTON (button));
+}
+
+static void
+face_tool_button_popup (GtkhtmlFaceToolButton *button)
+{
+ GtkToggleToolButton *tool_button;
+ GdkWindow *window;
+ GdkGrabStatus status;
+
+ if (!GTK_WIDGET_REALIZED (button))
+ return;
+
+ if (button->priv->popup_shown)
+ return;
+
+ /* Position the window over the button. */
+ face_tool_button_reposition_window (button);
+
+ /* Show the pop-up. */
+ gtk_widget_show (button->priv->window);
+ gtk_widget_grab_focus (button->priv->window);
+
+ /* Activate the tool button. */
+ tool_button = GTK_TOGGLE_TOOL_BUTTON (button);
+ gtk_toggle_tool_button_set_active (tool_button, TRUE);
+
+ /* Try to grab the pointer and keyboard. */
+ window = button->priv->window->window;
+ status = gdk_pointer_grab (
+ window, TRUE,
+ GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_MASK, NULL, NULL, GDK_CURRENT_TIME);
+ if (status == GDK_GRAB_SUCCESS) {
+ status = gdk_keyboard_grab (window, TRUE, GDK_CURRENT_TIME);
+ if (status != GDK_GRAB_SUCCESS)
+ gdk_display_pointer_ungrab (
+ gdk_drawable_get_display (window),
+ GDK_CURRENT_TIME);
+ }
+
+ if (status == GDK_GRAB_SUCCESS)
+ gtk_grab_add (button->priv->window);
+ else
+ gtk_widget_hide (button->priv->window);
+}
+
+static void
+face_tool_button_popdown (GtkhtmlFaceToolButton *button)
+{
+ GtkToggleToolButton *tool_button;
+
+ if (!GTK_WIDGET_REALIZED (button))
+ return;
+
+ if (!button->priv->popup_shown)
+ return;
+
+ /* Hide the pop-up. */
+ gtk_grab_remove (button->priv->window);
+ gtk_widget_hide (button->priv->window);
+
+ /* Deactivate the tool button. */
+ tool_button = GTK_TOGGLE_TOOL_BUTTON (button);
+ gtk_toggle_tool_button_set_active (tool_button, FALSE);
+}
+
+static GtkhtmlFace *
+face_tool_button_get_current_face (GtkhtmlFaceChooser *chooser)
+{
+ GtkhtmlFaceToolButtonPrivate *priv;
+
+ priv = GTKHTML_FACE_TOOL_BUTTON_GET_PRIVATE (chooser);
+
+ if (priv->active_button == NULL)
+ return NULL;
+
+ return g_object_get_data (G_OBJECT (priv->active_button), "face");
+}
+
+static void
+face_tool_button_set_current_face (GtkhtmlFaceChooser *chooser,
+ GtkhtmlFace *face)
+{
+ GtkhtmlFaceToolButtonPrivate *priv;
+ GList *list, *iter;
+
+ priv = GTKHTML_FACE_TOOL_BUTTON_GET_PRIVATE (chooser);
+
+ list = gtk_container_get_children (GTK_CONTAINER (priv->table));
+
+ for (iter = list; iter != NULL; iter = iter->next) {
+ GtkWidget *item = iter->data;
+ GtkhtmlFace *candidate;
+
+ candidate = g_object_get_data (G_OBJECT (item), "face");
+ if (candidate == NULL)
+ continue;
+
+ if (gtkhtml_face_equal (face, candidate)) {
+ gtk_button_clicked (GTK_BUTTON (item));
+ break;
+ }
+ }
+
+ g_list_free (list);
+}
+
+static void
+face_tool_button_class_init (GtkhtmlFaceToolButtonClass *class)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+ GtkToggleToolButtonClass *toggle_tool_button_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (GtkhtmlFaceToolButtonPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = face_tool_button_set_property;
+ object_class->get_property = face_tool_button_get_property;
+ object_class->dispose = face_tool_button_dispose;
+
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->button_press_event = face_tool_button_press_event;
+
+ toggle_tool_button_class = GTK_TOGGLE_TOOL_BUTTON_CLASS (class);
+ toggle_tool_button_class->toggled = face_tool_button_toggled;
+
+ class->popup = face_tool_button_popup;
+ class->popdown = face_tool_button_popdown;
+
+ g_object_class_override_property (
+ object_class, PROP_CURRENT_FACE, "current-face");
+
+ g_object_class_install_property (
+ object_class,
+ PROP_POPUP_SHOWN,
+ g_param_spec_boolean (
+ "popup-shown",
+ "Popup Shown",
+ "Whether the button's dropdown is shown",
+ FALSE,
+ G_PARAM_READWRITE));
+
+ signals[POPUP] = g_signal_new (
+ "popup",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GtkhtmlFaceToolButtonClass, popup),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[POPDOWN] = g_signal_new (
+ "popdown",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GtkhtmlFaceToolButtonClass, popdown),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ gtk_binding_entry_add_signal (
+ gtk_binding_set_by_class (class),
+ GDK_Down, GDK_MOD1_MASK, "popup", 0);
+ gtk_binding_entry_add_signal (
+ gtk_binding_set_by_class (class),
+ GDK_KP_Down, GDK_MOD1_MASK, "popup", 0);
+
+ gtk_binding_entry_add_signal (
+ gtk_binding_set_by_class (class),
+ GDK_Up, GDK_MOD1_MASK, "popdown", 0);
+ gtk_binding_entry_add_signal (
+ gtk_binding_set_by_class (class),
+ GDK_KP_Up, GDK_MOD1_MASK, "popdown", 0);
+ gtk_binding_entry_add_signal (
+ gtk_binding_set_by_class (class),
+ GDK_Escape, 0, "popdown", 0);
+}
+
+static void
+face_tool_button_iface_init (GtkhtmlFaceChooserIface *iface)
+{
+ iface->get_current_face = face_tool_button_get_current_face;
+ iface->set_current_face = face_tool_button_set_current_face;
+}
+
+static void
+face_tool_button_init (GtkhtmlFaceToolButton *button)
+{
+ GtkhtmlFaceChooser *chooser;
+ GtkWidget *toplevel;
+ GtkWidget *container;
+ GtkWidget *widget;
+ GtkWidget *window;
+ GList *list, *iter;
+ gint ii;
+
+ button->priv = GTKHTML_FACE_TOOL_BUTTON_GET_PRIVATE (button);
+
+ /* Build the pop-up window. */
+
+ window = gtk_window_new (GTK_WINDOW_POPUP);
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (button));
+ gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
+ gtk_window_set_type_hint (
+ GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_COMBO);
+ if (GTK_WIDGET_TOPLEVEL (toplevel)) {
+ gtk_window_group_add_window (
+ gtk_window_get_group (GTK_WINDOW (toplevel)),
+ GTK_WINDOW (window));
+ gtk_window_set_transient_for (
+ GTK_WINDOW (window), GTK_WINDOW (toplevel));
+ }
+ button->priv->window = g_object_ref (window);
+
+ g_signal_connect_swapped (
+ window, "show",
+ G_CALLBACK (face_tool_button_child_show_cb), button);
+ g_signal_connect_swapped (
+ window, "hide",
+ G_CALLBACK (face_tool_button_child_hide_cb), button);
+ g_signal_connect_swapped (
+ window, "button-release-event",
+ G_CALLBACK (face_tool_button_button_release_event_cb),
+ button);
+ g_signal_connect_swapped (
+ window, "key-press-event",
+ G_CALLBACK (face_tool_button_child_key_press_event_cb),
+ button);
+
+ /* Build the pop-up window contents. */
+
+ widget = gtk_frame_new (NULL);
+ gtk_frame_set_shadow_type (GTK_FRAME (widget), GTK_SHADOW_OUT);
+ gtk_container_add (GTK_CONTAINER (window), widget);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_table_new (NUM_ROWS, NUM_COLS, TRUE);
+ gtk_table_set_row_spacings (GTK_TABLE (widget), 0);
+ gtk_table_set_col_spacings (GTK_TABLE (widget), 0);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ button->priv->table = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ chooser = GTKHTML_FACE_CHOOSER (button);
+ list = gtkhtml_face_chooser_get_items (chooser);
+ g_assert (g_list_length (list) <= NUM_ROWS * NUM_COLS);
+
+ for (iter = list, ii = 0; iter != NULL; iter = iter->next, ii++) {
+ GtkhtmlFace *face = iter->data;
+ guint left = ii % NUM_COLS;
+ guint top = ii / NUM_COLS;
+ gchar *tooltip;
+
+ tooltip = face_tool_button_elide_underscores (
+ gettext (face->label));
+
+ widget = gtk_button_new ();
+ gtk_button_set_image (
+ GTK_BUTTON (widget),
+ gtk_image_new_from_icon_name (
+ face->icon_name, GTK_ICON_SIZE_BUTTON));
+ gtk_button_set_relief (GTK_BUTTON (widget), GTK_RELIEF_NONE);
+ gtk_widget_set_tooltip_text (widget, tooltip);
+ gtk_widget_show (widget);
+
+ g_object_set_data_full (
+ G_OBJECT (widget), "face",
+ gtkhtml_face_copy (face),
+ (GDestroyNotify) gtkhtml_face_free);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (face_tool_button_face_clicked_cb),
+ button);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (gtkhtml_face_chooser_item_activated),
+ chooser);
+
+ g_signal_connect_swapped (
+ widget, "button-release-event",
+ G_CALLBACK (face_tool_button_face_release_event_cb),
+ button);
+
+ gtk_table_attach (
+ GTK_TABLE (container), widget,
+ left, left + 1, top, top + 1, 0, 0, 0, 0);
+
+ g_free (tooltip);
+ }
+
+ g_list_free (list);
+}
+
+GType
+gtkhtml_face_tool_button_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (GtkhtmlFaceToolButtonClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) face_tool_button_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (GtkhtmlFaceToolButton),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) face_tool_button_init,
+ NULL /* value_table */
+ };
+
+ static const GInterfaceInfo iface_info = {
+ (GInterfaceInitFunc) face_tool_button_iface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface_data */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_TOGGLE_TOOL_BUTTON,
+ "GtkhtmlFaceToolButton", &type_info, 0);
+
+ g_type_add_interface_static (
+ type, GTKHTML_TYPE_FACE_CHOOSER, &iface_info);
+ }
+
+ return type;
+}
+
+GtkToolItem *
+gtkhtml_face_tool_button_new (void)
+{
+ return g_object_new (GTKHTML_TYPE_FACE_TOOL_BUTTON, NULL);
+}
+
+void
+gtkhtml_face_tool_button_popup (GtkhtmlFaceToolButton *button)
+{
+ g_return_if_fail (GTKHTML_IS_FACE_TOOL_BUTTON (button));
+
+ g_signal_emit (button, signals[POPUP], 0);
+}
+
+void
+gtkhtml_face_tool_button_popdown (GtkhtmlFaceToolButton *button)
+{
+ g_return_if_fail (GTKHTML_IS_FACE_TOOL_BUTTON (button));
+
+ g_signal_emit (button, signals[POPDOWN], 0);
+}
Added: trunk/components/editor/gtkhtml-face-tool-button.h
==============================================================================
--- (empty file)
+++ trunk/components/editor/gtkhtml-face-tool-button.h Tue Dec 9 18:30:21 2008
@@ -0,0 +1,70 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gtkhtml-face-tool-button.h
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GTKHTML_FACE_TOOL_BUTTON_H
+#define GTKHTML_FACE_TOOL_BUTTON_H
+
+#include "gtkhtml-editor-common.h"
+
+/* Standard GObject macros */
+#define GTKHTML_TYPE_FACE_TOOL_BUTTON \
+ (gtkhtml_face_tool_button_get_type ())
+#define GTKHTML_FACE_TOOL_BUTTON(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), GTKHTML_TYPE_FACE_TOOL_BUTTON, GtkhtmlFaceToolButton))
+#define GTKHTML_FACE_TOOL_BUTTON_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), GTKHTML_TYPE_FACE_TOOL_BUTTON, GtkhtmlFaceToolButtonClass))
+#define GTKHTML_IS_FACE_TOOL_BUTTON(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), GTKHTML_TYPE_FACE_TOOL_BUTTON))
+#define GTKHTML_IS_FACE_TOOL_BUTTON_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), GTKHTML_TYPE_FACE_TOOL_BUTTON))
+#define GTKHTML_FACE_TOOL_BUTTON_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), GTKHTML_TYPE_FACE_TOOL_BUTTON, GtkhtmlFaceToolButtonClass))
+
+G_BEGIN_DECLS
+
+typedef struct _GtkhtmlFaceToolButton GtkhtmlFaceToolButton;
+typedef struct _GtkhtmlFaceToolButtonClass GtkhtmlFaceToolButtonClass;
+typedef struct _GtkhtmlFaceToolButtonPrivate GtkhtmlFaceToolButtonPrivate;
+
+struct _GtkhtmlFaceToolButton {
+ GtkToggleToolButton parent;
+ GtkhtmlFaceToolButtonPrivate *priv;
+};
+
+struct _GtkhtmlFaceToolButtonClass {
+ GtkToggleToolButtonClass parent_class;
+
+ void (*popup) (GtkhtmlFaceToolButton *button);
+ void (*popdown) (GtkhtmlFaceToolButton *button);
+};
+
+GType gtkhtml_face_tool_button_get_type (void);
+GtkToolItem * gtkhtml_face_tool_button_new (void);
+void gtkhtml_face_tool_button_popup (GtkhtmlFaceToolButton *button);
+void gtkhtml_face_tool_button_popdown (GtkhtmlFaceToolButton *button);
+
+G_END_DECLS
+
+#endif /* GTKHTML_FACE_TOOL_BUTTON_H */
Added: trunk/components/editor/gtkhtml-face.c
==============================================================================
--- (empty file)
+++ trunk/components/editor/gtkhtml-face.c Tue Dec 9 18:30:21 2008
@@ -0,0 +1,88 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gtkhtml-face.h
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "gtkhtml-face.h"
+
+static GtkhtmlFace *
+face_copy (GtkhtmlFace *face)
+{
+ GtkhtmlFace *copy;
+
+ copy = g_slice_new (GtkhtmlFace);
+ copy->label = g_strdup (face->label);
+ copy->icon_name = g_strdup (face->icon_name);
+ copy->text_face = g_strdup (face->text_face);
+
+ return copy;
+}
+
+static void
+face_free (GtkhtmlFace *face)
+{
+ g_free (face->label);
+ g_free (face->icon_name);
+ g_free (face->text_face);
+ g_slice_free (GtkhtmlFace, face);
+}
+
+GType
+gtkhtml_face_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0))
+ type = g_boxed_type_register_static (
+ "GtkhtmlFace",
+ (GBoxedCopyFunc) face_copy,
+ (GBoxedFreeFunc) face_free);
+
+ return type;
+}
+
+gboolean
+gtkhtml_face_equal (GtkhtmlFace *face_a,
+ GtkhtmlFace *face_b)
+{
+ if (face_a == face_b)
+ return TRUE;
+
+ if (g_strcmp0 (face_a->label, face_b->label) != 0)
+ return FALSE;
+
+ if (g_strcmp0 (face_a->icon_name, face_b->icon_name) != 0)
+ return FALSE;
+
+ if (g_strcmp0 (face_a->text_face, face_b->text_face) != 0)
+ return FALSE;
+
+ return TRUE;
+}
+
+GtkhtmlFace *
+gtkhtml_face_copy (GtkhtmlFace *face)
+{
+ return g_boxed_copy (GTKHTML_TYPE_FACE, face);
+}
+
+void
+gtkhtml_face_free (GtkhtmlFace *face)
+{
+ g_boxed_free (GTKHTML_TYPE_FACE, face);
+}
Added: trunk/components/editor/gtkhtml-face.h
==============================================================================
--- (empty file)
+++ trunk/components/editor/gtkhtml-face.h Tue Dec 9 18:30:21 2008
@@ -0,0 +1,47 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gtkhtml-face.h
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GTKHTML_FACE_H
+#define GTKHTML_FACE_H
+
+#include "gtkhtml-editor-common.h"
+
+#define GTKHTML_TYPE_FACE \
+ (gtkhtml_face_get_type ())
+
+G_BEGIN_DECLS
+
+typedef struct _GtkhtmlFace GtkhtmlFace;
+
+struct _GtkhtmlFace {
+ gchar *label;
+ gchar *icon_name;
+ gchar *text_face;
+};
+
+GType gtkhtml_face_get_type (void);
+gboolean gtkhtml_face_equal (GtkhtmlFace *face_a,
+ GtkhtmlFace *face_b);
+GtkhtmlFace * gtkhtml_face_copy (GtkhtmlFace *face);
+void gtkhtml_face_free (GtkhtmlFace *face);
+
+G_END_DECLS
+
+#endif /* GTKHTML_FACE_H */
Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in (original)
+++ trunk/configure.in Tue Dec 9 18:30:21 2008
@@ -8,7 +8,7 @@
# Required Package Versions
m4_define([gtk_minimum_version], [2.12.0])
m4_define([gail_minimum_version], [1.1.0])
-m4_define([gnome_icon_theme_minimum_version], [1.2.0])
+m4_define([gnome_icon_theme_minimum_version], [2.22.0])
m4_define([libbonobo_minimum_version], [2.20.3])
m4_define([libbonoboui_minimum_version], [2.2.4])
m4_define([libglade_minimum_version], [2.0.0])
Modified: trunk/gtkhtml/htmlengine-edit-cut-and-paste.c
==============================================================================
--- trunk/gtkhtml/htmlengine-edit-cut-and-paste.c (original)
+++ trunk/gtkhtml/htmlengine-edit-cut-and-paste.c Tue Dec 9 18:30:21 2008
@@ -1266,21 +1266,46 @@
html_engine_thaw (e);
}
-static char *picto_chars = "DO)(|/PQ\0:-\0:\0:-\0:\0:;=-\0:;\0:-~\0:\0:\0:-\0:\0:-\0:\0:-\0:\0:-\0:\0";
-static gint picto_states [] = { 9, 14, 19, 27, 35, 40, 45, 50, 0, -1, 12, 0, -1, 0, -2, 17, 0, -2, 0, -3, -4, -5, 24, 0, -3, -4, 0, -6, 31, 33, 0, -6, 0, -11, 0, -8, 38, 0, -8, 0, -9, 43, 0, -9, 0, -10, 48, 0, -10, 0, -12, 53, 0, -12, 0};
+static char *picto_chars =
+ /* 0 */ "DO)(|/PQ*!"
+ /* 10 */ "S\0:-\0:\0:-\0"
+ /* 20 */ ":\0:;=-\"\0:;"
+ /* 30 */ "B\"|\0:-'\0:X"
+ /* 40 */ "\0:\0:-\0:\0:-"
+ /* 50 */ "\0:\0:-\0:\0:-"
+ /* 60 */ "\0:\0:\0:-\0:\0"
+ /* 70 */ ":-\0:\0:-\0:\0";
+static gint picto_states [] = {
+ /* 0 */ 12, 17, 22, 34, 43, 48, 53, 58, 65, 70,
+ /* 10 */ 75, 0, -15, 15, 0, -15, 0, -17, 20, 0,
+ /* 20 */ -17, 0, -14, -20, -14, 28, 63, 0, -14, -20,
+ /* 30 */ -3, 63, -18, 0, -12, 38, 41, 0, -12, -2,
+ /* 40 */ 0, -4, 0, -10, 46, 0, -10, 0, -19, 51,
+ /* 50 */ 0, -19, 0, -11, 56, 0, -11, 0, -13, 61,
+ /* 60 */ 0, -13, 0, -6, 0, 68, -7, 0, -7, 0,
+ /* 70 */ -16, 73, 0, -16, 0, -21, 78, 0, -21, 0 };
static gchar *picto_icon_names [] = {
- "stock_smiley-6",
- "stock_smiley-5",
- "stock_smiley-1",
- "stock_smiley-3",
- "stock_smiley-2",
- "stock_smiley-4",
- "stock_smiley-7", /* XXX No idea if this one is correct */
- "stock_smiley-8",
- "stock_smiley-9",
- "stock_smiley-10",
- "stock_smiley-11",
- "stock_smiley-26",
+ "face-angel",
+ "face-angry",
+ "face-cool",
+ "face-crying",
+ "face-devilish",
+ "face-embarrassed",
+ "face-kiss",
+ "face-laugh", /* not used */
+ "face-monkey", /* not used */
+ "face-plain",
+ "face-raspberry",
+ "face-sad",
+ "face-sick",
+ "face-smile",
+ "face-smile-big",
+ "face-smirk",
+ "face-surprise",
+ "face-tired",
+ "face-uncertain",
+ "face-wink",
+ "face-worried"
};
static void
@@ -1311,6 +1336,18 @@
pos --;
}
+ /* Special case needed to recognize angel and devilish. */
+ if (pos > 0 && state == -14) {
+ uc = html_text_get_char (HTML_TEXT (e->cursor->object), pos - 1);
+ if (uc == 'O') {
+ state = -1;
+ pos--;
+ } else if (uc == '>') {
+ state = -5;
+ pos--;
+ }
+ }
+
if (state < 0) {
HTMLObject *image;
GtkIconInfo *icon_info;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]