changeset 14239:a0b1ab181316

[gaim-migrate @ 16921] Allow remapping keys for widgets. committer: Tailor Script <tailor@pidgin.im>
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Sun, 20 Aug 2006 22:46:20 +0000
parents f189327b9968
children efc3836b7e8b
files console/libgnt/gntstyle.c console/libgnt/gntstyle.h console/libgnt/gntwidget.c console/libgnt/gntwidget.h
diffstat 4 files changed, 125 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/console/libgnt/gntstyle.c	Sun Aug 20 22:24:13 2006 +0000
+++ b/console/libgnt/gntstyle.c	Sun Aug 20 22:46:20 2006 +0000
@@ -3,6 +3,10 @@
 
 #include <string.h>
 
+#if GLIB_CHECK_VERSION(2,6,0)
+static GKeyFile *gkfile;
+#endif
+
 static char * str_styles[GNT_STYLES];
 static int int_styles[GNT_STYLES];
 static int bool_styles[GNT_STYLES];
@@ -41,6 +45,89 @@
 	return bool_styles[style];
 }
 
+void refine(char *text)
+{
+	char *s = text, *t = text;
+
+	while (*s)
+	{
+		if (*s == '^' && *(s + 1) == '[')
+		{
+			*t = '\033';  /* escape */
+			s++;
+		}
+		else if (*s == '\\')
+		{
+			if (*(s + 1) == '\0')
+				*t = ' ';
+			else
+			{
+				s++;
+				if (*s == 'r' || *s == 'n')
+					*t = '\r';
+				else if (*s == 't')
+					*t = '\t';
+				else
+					*t = *s;
+			}
+		}
+		else
+			*t = *s;
+		t++;
+		s++;
+	}
+	*t = '\0';
+}
+
+void gnt_styles_get_keyremaps(GType type, GHashTable *hash)
+{
+#if GLIB_CHECK_VERSION(2,6,0)
+	char *name;
+	GError *error = NULL;
+	
+	name = g_strdup_printf("%s::remap", g_type_name(type));
+
+	if (g_key_file_has_group(gkfile, name))
+	{
+		unsigned int len = 0;
+		char **keys;
+		
+		keys = g_key_file_get_keys(gkfile, name, &len, &error);
+		if (error)
+		{
+			g_printerr("GntStyle: %s\n", error->message);
+			g_error_free(error);
+			return;
+		}
+
+		while (len--)
+		{
+			char *key, *replace;
+
+			key = g_strdup(keys[len]);
+			replace = g_key_file_get_string(gkfile, name, keys[len], &error);
+
+			if (error)
+			{
+				g_printerr("GntStyle: %s\n", error->message);
+				g_error_free(error);
+				error = NULL;
+				g_free(key);
+			}
+			else
+			{
+				refine(key);
+				refine(replace);
+				g_hash_table_insert(hash, key, replace);
+			}
+		}
+		g_strfreev(keys);
+	}
+
+	g_free(name);
+#endif
+}
+
 #if GLIB_CHECK_VERSION(2,6,0)
 static void
 read_general_style(GKeyFile *kfile)
@@ -58,7 +145,7 @@
 
 	if (error)
 	{
-		/* XXX: some error happened. */
+		g_printerr("GntStyle: %s\n", error->message);
 		g_error_free(error);
 	}
 	else
@@ -70,25 +157,24 @@
 					g_key_file_get_string(kfile, "general", styles[i].style, &error);
 		}
 	}
+	g_strfreev(keys);
 }
 #endif
 
 void gnt_style_read_configure_file(const char *filename)
 {
 #if GLIB_CHECK_VERSION(2,6,0)
-	GKeyFile *kfile = g_key_file_new();
+	gkfile = g_key_file_new();
 	GError *error = NULL;
 
-	if (!g_key_file_load_from_file(kfile, filename, G_KEY_FILE_NONE, &error))
+	if (!g_key_file_load_from_file(gkfile, filename, G_KEY_FILE_NONE, &error))
 	{
-		/* XXX: Print the error or something */
+		g_printerr("GntStyle: %s\n", error->message);
 		g_error_free(error);
 		return;
 	}
-	gnt_colors_parse(kfile);
-	read_general_style(kfile);
-
-	g_key_file_free(kfile);
+	gnt_colors_parse(gkfile);
+	read_general_style(gkfile);
 #endif
 }
 
@@ -108,5 +194,9 @@
 	int i;
 	for (i = 0; i < GNT_STYLES; i++)
 		g_free(str_styles[i]);
+
+#if GLIB_CHECK_VERSION(2,6,0)
+	g_key_file_free(gkfile);
+#endif
 }
 
--- a/console/libgnt/gntstyle.h	Sun Aug 20 22:24:13 2006 +0000
+++ b/console/libgnt/gntstyle.h	Sun Aug 20 22:46:20 2006 +0000
@@ -13,6 +13,9 @@
 
 gboolean gnt_style_get_bool(GntStyle style, gboolean def);
 
+/* This should be called only once for the each type */
+void gnt_styles_get_keyremaps(GType type, GHashTable *hash);
+
 void gnt_init_styles();
 
 void gnt_uninit_styles();
--- a/console/libgnt/gntwidget.c	Sun Aug 20 22:24:13 2006 +0000
+++ b/console/libgnt/gntwidget.c	Sun Aug 20 22:46:20 2006 +0000
@@ -96,7 +96,6 @@
 	return continue_emission;
 }
 
-
 static void
 gnt_widget_class_init(GntWidgetClass *klass)
 {
@@ -214,6 +213,7 @@
 					 gnt_boolean_handled_accumulator, NULL,
 					 gnt_closure_marshal_BOOLEAN__STRING,
 					 G_TYPE_BOOLEAN, 1, G_TYPE_STRING);
+
 	DEBUG;
 }
 
@@ -231,7 +231,7 @@
 			NULL,					/* base_init		*/
 			NULL,					/* base_finalize	*/
 			(GClassInitFunc)gnt_widget_class_init,
-			NULL,					/* class_finalize	*/
+			NULL,
 			NULL,					/* class_data		*/
 			sizeof(GntWidget),
 			0,						/* n_preallocs		*/
@@ -246,6 +246,24 @@
 	return type;
 }
 
+static const char *
+gnt_widget_remap_keys(GntWidget *widget, const char *text)
+{
+	const char *remap = NULL;
+	GType type = G_OBJECT_TYPE(widget);
+	GntWidgetClass *klass = GNT_WIDGET_CLASS(G_OBJECT_GET_CLASS(widget));
+
+	if (klass->remaps == NULL)
+	{
+		klass->remaps = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+		gnt_styles_get_keyremaps(type, klass->remaps);
+	}
+
+	remap = g_hash_table_lookup(klass->remaps, text);
+
+	return (remap ? remap : text);
+}
+
 static void
 gnt_widget_take_focus(GntWidget *widget)
 {
@@ -327,6 +345,8 @@
 	gboolean ret;
 	if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_CAN_TAKE_FOCUS))
 		return FALSE;
+
+	keys = gnt_widget_remap_keys(widget, keys);
 	g_signal_emit(widget, signals[SIG_KEY_PRESSED], 0, keys, &ret);
 	return ret;
 }
--- a/console/libgnt/gntwidget.h	Sun Aug 20 22:24:13 2006 +0000
+++ b/console/libgnt/gntwidget.h	Sun Aug 20 22:46:20 2006 +0000
@@ -76,6 +76,8 @@
 {
 	GObjectClass parent;
 
+	GHashTable *remaps;   /* Key remaps */
+
 	void (*map)(GntWidget *obj);
 	void (*show)(GntWidget *obj);		/* This will call draw() and take focus (if it can take focus) */
 	void (*destroy)(GntWidget *obj);