Recode patch by decadix/senneth

git-svn-id: http://svn.irssi.org/repos/irssi/trunk@3283 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
Timo Sirainen 2004-08-20 00:03:40 +00:00 committed by cras
commit 226a567562
20 changed files with 289 additions and 63 deletions

View file

@ -30,6 +30,7 @@ libfe_common_core_a_SOURCES = \
keyboard.c \
module-formats.c \
printtext.c \
fe-recode.c \
themes.c \
translation.c \
window-activity.c \
@ -56,6 +57,7 @@ pkginc_fe_common_core_HEADERS = \
module-formats.h \
module.h \
printtext.h \
fe-recode.h \
themes.h \
translation.h \
window-activity.h \

View file

@ -788,6 +788,36 @@ GList *completion_get_servers(const char *word)
return list;
}
GList *completion_get_targets(const char *word)
{
CONFIG_NODE *node;
GList *list;
GSList *tmp;
int len;
g_return_val_if_fail(word != NULL, NULL);
len = strlen(word);
list = NULL;
/* get the list of all conversion targets */
node = iconfig_node_traverse("conversions", FALSE);
tmp = node == NULL ? NULL : config_node_first(node->value);
for (; tmp != NULL; tmp = config_node_next(tmp)) {
node = tmp->data;
if (node->type != NODE_TYPE_KEY)
continue;
if (len != 0 && g_strncasecmp(node->key, word, len) != 0)
continue;
list = g_list_append(list, g_strdup(node->key));
}
return list;
}
static void sig_complete_connect(GList **list, WINDOW_REC *window,
const char *word, const char *line,
int *want_space)
@ -881,7 +911,6 @@ static void sig_complete_alias(GList **list, WINDOW_REC *window,
}
}
static void sig_complete_channel(GList **list, WINDOW_REC *window,
const char *word, const char *line,
int *want_space)
@ -904,6 +933,27 @@ static void sig_complete_server(GList **list, WINDOW_REC *window,
if (*list != NULL) signal_stop();
}
static void sig_complete_target(GList **list, WINDOW_REC *window,
const char *word, const char *line,
int *want_space)
{
const char *definition;
g_return_if_fail(list != NULL);
g_return_if_fail(word != NULL);
g_return_if_fail(line != NULL);
if (*line != '\0') {
if ((definition = iconfig_get_str("conversions", line ,NULL)) != NULL) {
*list = g_list_append(NULL, g_strdup(definition));
signal_stop();
}
} else {
*list = completion_get_targets(word);
if (*list != NULL) signal_stop();
}
}
/* expand \n, \t and \\ */
static char *expand_escapes(const char *line, SERVER_REC *server,
WI_ITEM_REC *item)
@ -1090,6 +1140,7 @@ void chat_completion_init(void)
signal_add("complete command window item move", (SIGNAL_FUNC) sig_complete_channel);
signal_add("complete command server add", (SIGNAL_FUNC) sig_complete_server);
signal_add("complete command server remove", (SIGNAL_FUNC) sig_complete_server);
signal_add("complete command recode remove", (SIGNAL_FUNC) sig_complete_target);
signal_add("message public", (SIGNAL_FUNC) sig_message_public);
signal_add("message join", (SIGNAL_FUNC) sig_message_join);
signal_add("message private", (SIGNAL_FUNC) sig_message_private);
@ -1126,6 +1177,7 @@ void chat_completion_deinit(void)
signal_remove("complete command window item move", (SIGNAL_FUNC) sig_complete_channel);
signal_remove("complete command server add", (SIGNAL_FUNC) sig_complete_server);
signal_remove("complete command server remove", (SIGNAL_FUNC) sig_complete_server);
signal_remove("complete command recode remove", (SIGNAL_FUNC) sig_complete_target);
signal_remove("message public", (SIGNAL_FUNC) sig_message_public);
signal_remove("message join", (SIGNAL_FUNC) sig_message_join);
signal_remove("message private", (SIGNAL_FUNC) sig_message_private);

View file

@ -46,6 +46,7 @@
#include "window-activity.h"
#include "window-items.h"
#include "windows-layout.h"
#include "fe-recode.h"
#include <signal.h>
@ -202,6 +203,7 @@ void fe_common_core_init(void)
fe_messages_init();
hilight_text_init();
fe_ignore_messages_init();
fe_recode_init();
settings_check();
@ -244,6 +246,7 @@ void fe_common_core_deinit(void)
fe_messages_deinit();
fe_ignore_messages_deinit();
fe_recode_deinit();
theme_unregister();
themes_deinit();

View file

@ -322,7 +322,7 @@ static int sig_query_autoclose(void)
now-rec->last_unread_msg > query_auto_close)
query_destroy(rec);
}
return 1;
return 1;
}
static void sig_message_private(SERVER_REC *server, const char *msg,

View file

@ -275,7 +275,6 @@ void format_read_arglist(va_list va, FORMAT_REC *format,
}
}
}
void format_create_dest(TEXT_DEST_REC *dest,
void *server, const char *target,
int level, WINDOW_REC *window)
@ -296,16 +295,50 @@ void format_create_dest_tag(TEXT_DEST_REC *dest, void *server,
dest->window = window != NULL ? window :
window_find_closest(server, target, level);
}
#ifdef HAVE_GLIB2
static gboolean term_is_utf8 (void)
{
const char *charset;
charset = settings_get_str("term_charset");
if (*charset)
return ! g_strcasecmp(charset, "utf-8");
return g_get_charset(&charset);
}
static int advance (char const **str, gboolean utf8)
{
if (utf8) {
gunichar c;
c = g_utf8_get_char(*str);
*str = g_utf8_next_char(*str);
return utf8_width(c);
} else {
*str += 1;
return 1;
}
}
#endif
/* Return length of text part in string (ie. without % codes) */
int format_get_length(const char *str)
{
GString *tmp;
GString *tmp;
int len;
#ifdef HAVE_GLIB2
gboolean utf8;
#endif
g_return_val_if_fail(str != NULL, 0);
g_return_val_if_fail(str != NULL, 0);
tmp = g_string_new(NULL);
#ifdef HAVE_GLIB2
utf8 = term_is_utf8() && g_utf8_validate(str, -1, NULL);
#endif
tmp = g_string_new(NULL);
len = 0;
while (*str != '\0') {
if (*str == '%' && str[1] != '\0') {
@ -320,9 +353,12 @@ int format_get_length(const char *str)
if (*str != '%')
len++;
}
len++;
#ifdef HAVE_GLIB2
len += advance(&str, utf8);
#else
len++;
str++;
#endif
}
g_string_free(tmp, TRUE);
@ -336,12 +372,18 @@ int format_real_length(const char *str, int len)
{
GString *tmp;
const char *start;
#ifdef HAVE_GLIB2
gboolean utf8;
#endif
g_return_val_if_fail(str != NULL, 0);
g_return_val_if_fail(len >= 0, 0);
g_return_val_if_fail(str != NULL, 0);
g_return_val_if_fail(len >= 0, 0);
#ifdef HAVE_GLIB2
utf8 = term_is_utf8() && g_utf8_validate(str, -1, NULL);
#endif
start = str;
tmp = g_string_new(NULL);
start = str;
tmp = g_string_new(NULL);
while (*str != '\0' && len > 0) {
if (*str == '%' && str[1] != '\0') {
str++;
@ -358,8 +400,12 @@ int format_real_length(const char *str, int len)
}
}
len--;
#ifdef HAVE_GLIB2
len -= advance(&str, utf8);
#else
len--;
str++;
#endif
}
g_string_free(tmp, TRUE);
@ -883,7 +929,7 @@ char *strip_codes(const char *input)
out = str = g_strdup(input);
for (p = input; *p != '\0'; p++) {
if (*p == 3) {
p++;
p++;
/* mirc color */
get_mirc_color(&p, NULL, NULL);
@ -909,11 +955,11 @@ char *strip_codes(const char *input)
p = get_ansi_color(current_theme, p, NULL, NULL, NULL);
p--;
} else if (!IS_COLOR_CODE(*p))
*out++ = *p;
*out++ = *p;
}
*out = '\0';
return str;
return str;
}
/* send a fully parsed text string for GUI to print */

View file

@ -246,6 +246,17 @@ FORMAT_REC fecommon_core_formats[] = {
{ "ignore_line", "%#$[-4]0 $1: $2 $3 $4", 4, { 1, 0, 0, 0 } },
{ "ignore_footer", "", 0 },
/* ---- */
{ NULL, "Recode", 0 },
{ "not_channel_or_query", "The current window is not a channel or query window", 0 },
{ "conversion_added", "Added {hilight $0}/{hilight $1} to conversion database", 2, { FORMAT_STRING, FORMAT_STRING } },
{ "conversion_removed", "Removed {hilight $0} from conversion database", 1, { FORMAT_STRING } },
{ "conversion_not_found", "{hilight $0} not found in conversion database", 1, { FORMAT_STRING } },
{ "conversion_not_supported", "Conversion to the character set {hilight $0} is not supported",1, { FORMAT_STRING } },
{ "recode_header", "%#Target Character set", 0 },
{ "recode_line", "%#%|$[!30]0 $1", 2, { FORMAT_STRING, FORMAT_STRING } },
/* ---- */
{ NULL, "Misc", 0 },

View file

@ -215,6 +215,16 @@ enum {
TXT_FILL_13,
TXT_NOT_CHANNEL_OR_QUERY,
TXT_CONVERSION_ADDED,
TXT_CONVERSION_REMOVED,
TXT_CONVERSION_NOT_FOUND,
TXT_CONVERSION_NOT_SUPPORTED,
TXT_RECODE_HEADER,
TXT_RECODE_LINE,
TXT_FILL_14,
TXT_UNKNOWN_CHAT_PROTOCOL,
TXT_UNKNOWN_CHATNET,
TXT_NOT_TOGGLE,

View file

@ -23,6 +23,7 @@
#include "modules.h"
#include "signals.h"
#include "commands.h"
#include "recode.h"
#include "settings.h"
#include "levels.h"
@ -159,23 +160,26 @@ void printformat_module_gui(const char *module, int formatnum, ...)
static void print_line(TEXT_DEST_REC *dest, const char *text)
{
THEME_REC *theme;
char *str, *tmp, *stripped;
char *str, *recoded, *tmp, *stripped;
g_return_if_fail(dest != NULL);
g_return_if_fail(text != NULL);
theme = window_get_theme(dest->window);
tmp = format_get_level_tag(theme, dest);
str = !theme->info_eol ? format_add_linestart(text, tmp) :
format_add_lineend(text, tmp);
g_free_not_null(tmp);
recoded = recode_in(str, dest->target);
/* send both the formatted + stripped (for logging etc.) */
stripped = strip_codes(str);
signal_emit_id(signal_print_text, 3, dest, str, stripped);
stripped = strip_codes(recoded);
signal_emit_id(signal_print_text, 3, dest, recoded, stripped);
g_free_and_null(dest->hilight_color);
g_free(str);
g_free(recoded);
g_free(stripped);
}

View file

@ -22,6 +22,7 @@
#include "module-formats.h"
#include "signals.h"
#include "misc.h"
#include "recode.h"
#include "special-vars.h"
#include "settings.h"
@ -56,6 +57,9 @@ static const char *skip_target(const char *target)
/* SYNTAX: ME <message> */
static void cmd_me(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item)
{
const char *target;
char *recoded;
CMD_IRC_SERVER(server);
if (!IS_IRC_ITEM(item))
return;
@ -63,11 +67,16 @@ static void cmd_me(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item)
if (server == NULL || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
signal_emit("message irc own_action", 3, server, data,
target = window_item_get_target(item);
recoded = recode_out(data, target);
signal_emit("message irc own_action", 3, server, recoded,
item->visible_name);
irc_send_cmdv(server, "PRIVMSG %s :\001ACTION %s\001",
window_item_get_target(item), data);
target, recoded);
g_free(recoded);
}
/* SYNTAX: ACTION [-<server tag>] <target> <message> */
@ -75,6 +84,7 @@ static void cmd_action(const char *data, IRC_SERVER_REC *server)
{
GHashTable *optlist;
const char *target, *text;
char *recoded;
void *free_arg;
CMD_IRC_SERVER(server);
@ -90,10 +100,13 @@ static void cmd_action(const char *data, IRC_SERVER_REC *server)
if (server == NULL || !server->connected)
cmd_param_error(CMDERR_NOT_CONNECTED);
irc_send_cmdv(server, "PRIVMSG %s :\001ACTION %s\001", target, text);
recoded = recode_out(text, target);
irc_send_cmdv(server, "PRIVMSG %s :\001ACTION %s\001", target, recoded);
target = skip_target(target);
signal_emit("message irc own_action", 3, server, text, target);
signal_emit("message irc own_action", 3, server, recoded, target);
g_free(recoded);
cmd_params_free(free_arg);
}
@ -101,6 +114,7 @@ static void cmd_notice(const char *data, IRC_SERVER_REC *server,
WI_ITEM_REC *item)
{
const char *target, *msg;
char *recoded;
void *free_arg;
CMD_IRC_SERVER(server);
@ -113,8 +127,11 @@ static void cmd_notice(const char *data, IRC_SERVER_REC *server,
if (*target == '\0' || *msg == '\0')
cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
signal_emit("message irc own_notice", 3, server, msg, target);
recoded = recode_out(msg, target);
signal_emit("message irc own_notice", 3, server, recoded, target);
g_free(recoded);
cmd_params_free(free_arg);
}