From d1330fff6d1a6cf2c37c14d1054ef9cf73d5f5fe Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Sun, 12 Nov 2000 20:20:05 +0000 Subject: [PATCH] Text printing changes. Formats are now optionally saved to each line so later if you used /format it would change the old lines too. However the actual line changing doesn't work yet :) git-svn-id: http://svn.irssi.org/repos/irssi/trunk@836 dbcabf3a-b0e7-0310-adc4-f8d773084564 --- src/fe-common/core/fe-log.c | 14 +- src/fe-common/core/formats.c | 359 +++++++++++++++++++++++++-- src/fe-common/core/formats.h | 29 ++- src/fe-common/core/hilight-text.c | 31 +-- src/fe-common/core/module-formats.c | 2 +- src/fe-common/core/printtext.c | 346 +++----------------------- src/fe-common/core/printtext.h | 11 - src/fe-common/core/window-activity.c | 29 ++- src/fe-common/core/windows.c | 3 +- src/fe-text/gui-printtext.c | 64 ++++- src/fe-text/gui-textwidget.c | 1 + src/fe-text/gui-windows.c | 6 +- src/fe-text/gui-windows.h | 8 +- src/fe-text/statusbar-items.c | 3 +- 14 files changed, 515 insertions(+), 391 deletions(-) diff --git a/src/fe-common/core/fe-log.c b/src/fe-common/core/fe-log.c index 5486bea1..426a7e47 100644 --- a/src/fe-common/core/fe-log.c +++ b/src/fe-common/core/fe-log.c @@ -429,21 +429,19 @@ static void log_line(WINDOW_REC *window, void *server, g_strfreev(lines); } -static void sig_printtext_stripped(WINDOW_REC *window, void *server, - const char *target, gpointer levelp, - const char *text) +static void sig_printtext_stripped(TEXT_DEST_REC *dest, const char *text) { if (skip_next_printtext) { skip_next_printtext = FALSE; return; } - log_line(window, server, target, GPOINTER_TO_INT(levelp), text); + log_line(dest->window, dest->server, dest->target, + dest->level, text); } static void sig_print_format(THEME_REC *theme, const char *module, - TEXT_DEST_REC *dest, void *formatnum, - va_list va) + TEXT_DEST_REC *dest, void *formatnum, char **args) { char *str, *stripped, *linestart, *tmp; @@ -457,8 +455,8 @@ static void sig_print_format(THEME_REC *theme, const char *module, if (theme == log_theme) return; - str = format_get_text_theme_args(log_theme, module, dest, - GPOINTER_TO_INT(formatnum), va); + str = format_get_text_theme_charargs(log_theme, module, dest, + GPOINTER_TO_INT(formatnum), args); skip_next_printtext = TRUE; if (*str != '\0') { diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index dd2fe8a4..4b0df726 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -22,12 +22,17 @@ #include "module-formats.h" #include "signals.h" #include "special-vars.h" +#include "settings.h" #include "levels.h" #include "windows.h" #include "formats.h" #include "themes.h" +#include "translation.h" + +static int signal_gui_print_text; +static int hide_text_style; int format_expand_styles(GString *out, char format, TEXT_DEST_REC *dest) { @@ -112,7 +117,7 @@ int format_expand_styles(GString *out, char format, TEXT_DEST_REC *dest) return TRUE; } -static void read_arglist(va_list va, FORMAT_REC *format, +void format_read_arglist(va_list va, FORMAT_REC *format, char **arglist, int arglist_size, char *buffer, int buffer_size) { @@ -186,22 +191,13 @@ void format_create_dest(TEXT_DEST_REC *dest, window_find_closest(server, target, level); } -static char *format_get_text_args(TEXT_DEST_REC *dest, FORMAT_REC *format, - const char *text, va_list va) +static char *format_get_text_args(TEXT_DEST_REC *dest, + const char *text, char **arglist) { GString *out; - char *arglist[10]; - char buffer[200]; /* should be enough? (won't overflow even if it isn't) */ - char code, *ret; int need_free; - /* read all optional arguments to arglist[] list - so they can be used in any order.. */ - read_arglist(va, format, - arglist, sizeof(arglist)/sizeof(void*), - buffer, sizeof(buffer)); - out = g_string_new(NULL); code = 0; @@ -271,17 +267,33 @@ char *format_get_text_theme(THEME_REC *theme, const char *module, char *format_get_text_theme_args(THEME_REC *theme, const char *module, TEXT_DEST_REC *dest, int formatnum, va_list va) +{ + char *arglist[MAX_FORMAT_PARAMS]; + char buffer[DEFAULT_FORMAT_ARGLIST_SIZE]; + FORMAT_REC *formats; + + formats = g_hash_table_lookup(default_formats, module); + format_read_arglist(va, &formats[formatnum], + arglist, sizeof(arglist)/sizeof(char *), + buffer, sizeof(buffer)); + + return format_get_text_theme_charargs(theme, module, dest, + formatnum, arglist); +} + +char *format_get_text_theme_charargs(THEME_REC *theme, const char *module, + TEXT_DEST_REC *dest, int formatnum, + char **args) { MODULE_THEME_REC *module_theme; FORMAT_REC *formats; - char *str; + char *text; module_theme = g_hash_table_lookup(theme->modules, module); formats = g_hash_table_lookup(default_formats, module); - str = format_get_text_args(dest, &formats[formatnum], - module_theme->expanded_formats[formatnum], va); - return str; + text = module_theme->expanded_formats[formatnum]; + return format_get_text_args(dest, text, args); } char *format_get_text(const char *module, WINDOW_REC *window, @@ -352,3 +364,318 @@ char *format_get_line_start(THEME_REC *theme, TEXT_DEST_REC *dest) return format_get_text_theme(theme, MODULE_NAME, dest, format); } + +void format_newline(WINDOW_REC *window) +{ + window->lines++; + if (window->lines != 1) { + signal_emit_id(signal_gui_print_text, 6, window, + GINT_TO_POINTER(-1), GINT_TO_POINTER(-1), + GINT_TO_POINTER(PRINTFLAG_NEWLINE), + "", GINT_TO_POINTER(-1)); + } +} + +/* parse ANSI color string */ +static char *get_ansi_color(THEME_REC *theme, char *str, + int *fg_ret, int *bg_ret, int *flags_ret) +{ + static char ansitab[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; + char *start; + int fg, bg, flags, num; + + if (*str != '[') + return str; + start = str++; + + fg = fg_ret == NULL || *fg_ret < 0 ? theme->default_color : *fg_ret; + bg = bg_ret == NULL || *bg_ret < 0 ? -1 : *bg_ret; + flags = flags_ret == NULL ? 0 : *flags_ret; + + num = 0; + for (;; str++) { + if (*str == '\0') return start; + + if (isdigit((int) *str)) { + num = num*10 + (*str-'0'); + continue; + } + + if (*str != ';' && *str != 'm') + return start; + + switch (num) { + case 0: + /* reset colors back to default */ + fg = theme->default_color; + bg = -1; + flags &= ~(PRINTFLAG_BEEP|PRINTFLAG_INDENT); + break; + case 1: + /* hilight */ + flags |= PRINTFLAG_BOLD; + break; + case 5: + /* blink */ + flags |= PRINTFLAG_BLINK; + break; + case 7: + /* reverse */ + flags |= PRINTFLAG_REVERSE; + break; + default: + if (num >= 30 && num <= 37) + fg = (fg & 0xf8) + ansitab[num-30]; + if (num >= 40 && num <= 47) { + if (bg == -1) bg = 0; + bg = (bg & 0xf8) + ansitab[num-40]; + } + break; + } + num = 0; + + if (*str == 'm') { + if (fg_ret != NULL) *fg_ret = fg; + if (bg_ret != NULL) *bg_ret = bg; + if (flags_ret != NULL) *flags_ret = flags; + + str++; + break; + } + } + + return str; +} + +/* parse MIRC color string */ +static void get_mirc_color(const char **str, int *fg_ret, int *bg_ret) +{ + int fg, bg; + + fg = fg_ret == NULL ? -1 : *fg_ret; + bg = bg_ret == NULL ? -1 : *bg_ret; + + if (!isdigit((int) **str) && **str != ',') { + fg = -1; + bg = -1; + } else { + /* foreground color */ + if (**str != ',') { + fg = **str-'0'; + (*str)++; + if (isdigit((int) **str)) { + fg = fg*10 + (**str-'0'); + (*str)++; + } + } + if (**str == ',') { + /* background color */ + (*str)++; + if (!isdigit((int) **str)) + bg = -1; + else { + bg = **str-'0'; + (*str)++; + if (isdigit((int) **str)) { + bg = bg*10 + (**str-'0'); + (*str)++; + } + } + } + } + + if (fg_ret) *fg_ret = fg; + if (bg_ret) *bg_ret = bg; +} + +#define IS_COLOR_CODE(c) \ + ((c) == 2 || (c) == 3 || (c) == 4 || (c) == 6 || (c) == 7 || \ + (c) == 15 || (c) == 22 || (c) == 27 || (c) == 31) + +char *strip_codes(const char *input) +{ + const char *p; + char *str, *out; + + out = str = g_strdup(input); + for (p = input; *p != '\0'; p++) { + if (*p == 3) { + p++; + + /* mirc color */ + get_mirc_color(&p, NULL, NULL); + p--; + continue; + } + + if (*p == 4 && p[1] != '\0') { + if (p[1] >= FORMAT_STYLE_SPECIAL) { + p++; + continue; + } + + /* irssi color */ + if (p[2] != '\0') { + p += 2; + continue; + } + } + + if (!IS_COLOR_CODE(*p)) + *out++ = *p; + } + + *out = '\0'; + return str; +} + +/* send a fully parsed text string for GUI to print */ +void format_send_to_gui(TEXT_DEST_REC *dest, const char *text) +{ + char *dup, *str, *ptr, type; + int fgcolor, bgcolor; + int flags; + + dup = str = g_strdup(text); + + flags = 0; fgcolor = -1; bgcolor = -1; + while (*str != '\0') { + type = '\0'; + for (ptr = str; *ptr != '\0'; ptr++) { + if (IS_COLOR_CODE(*ptr) || *ptr == '\n') { + type = *ptr; + *ptr++ = '\0'; + break; + } + + *ptr = (char) translation_in[(int) (unsigned char) *ptr]; + } + + if (type == 7) { + /* bell */ + if (settings_get_bool("bell_beeps")) + flags |= PRINTFLAG_BEEP; + } + + if (*str != '\0' || (flags & PRINTFLAG_BEEP)) { + /* send the text to gui handler */ + signal_emit_id(signal_gui_print_text, 6, dest->window, + GINT_TO_POINTER(fgcolor), + GINT_TO_POINTER(bgcolor), + GINT_TO_POINTER(flags), str, + dest->level); + flags &= ~(PRINTFLAG_BEEP | PRINTFLAG_INDENT); + } + + if (type == '\n') + format_newline(dest->window); + + if (*ptr == '\0') + break; + + switch (type) + { + case 2: + /* bold */ + if (!hide_text_style) + flags ^= PRINTFLAG_BOLD; + break; + case 3: + /* MIRC color */ + get_mirc_color((const char **) &ptr, + hide_text_style ? NULL : &fgcolor, + hide_text_style ? NULL : &bgcolor); + if (!hide_text_style) + flags |= PRINTFLAG_MIRC_COLOR; + break; + case 4: + /* user specific colors */ + flags &= ~PRINTFLAG_MIRC_COLOR; + switch (*ptr) { + case FORMAT_STYLE_UNDERLINE: + flags ^= PRINTFLAG_UNDERLINE; + break; + case FORMAT_STYLE_BOLD: + flags ^= PRINTFLAG_BOLD; + break; + case FORMAT_STYLE_REVERSE: + flags ^= PRINTFLAG_REVERSE; + break; + case FORMAT_STYLE_INDENT: + flags |= PRINTFLAG_INDENT; + break; + case FORMAT_STYLE_DEFAULTS: + fgcolor = bgcolor = -1; + flags &= PRINTFLAG_INDENT; + break; + default: + if (*ptr != FORMAT_COLOR_NOCHANGE) { + fgcolor = (unsigned char) *ptr-'0'; + if (fgcolor <= 7) + flags &= ~PRINTFLAG_BOLD; + else { + /* bold */ + if (fgcolor != 8) fgcolor -= 8; + flags |= PRINTFLAG_BOLD; + } + } + ptr++; + if (*ptr != FORMAT_COLOR_NOCHANGE) + bgcolor = *ptr-'0'; + } + ptr++; + break; + case 6: + /* blink */ + if (!hide_text_style) + flags ^= PRINTFLAG_BLINK; + break; + case 15: + /* remove all styling */ + flags &= PRINTFLAG_BEEP; + fgcolor = bgcolor = -1; + break; + case 22: + /* reverse */ + if (!hide_text_style) + flags ^= PRINTFLAG_REVERSE; + break; + case 31: + /* underline */ + if (!hide_text_style) + flags ^= PRINTFLAG_UNDERLINE; + break; + case 27: + /* ansi color code */ + ptr = get_ansi_color(dest->window->theme == NULL ? + current_theme : dest->window->theme, + ptr, + hide_text_style ? NULL : &fgcolor, + hide_text_style ? NULL : &bgcolor, + hide_text_style ? NULL : &flags); + break; + } + + str = ptr; + } + + g_free(dup); +} + +static void read_settings(void) +{ + hide_text_style = settings_get_bool("hide_text_style"); +} + +void formats_init(void) +{ + signal_gui_print_text = signal_get_uniq_id("gui print text"); + + read_settings(); + signal_add("setup changed", (SIGNAL_FUNC) read_settings); +} + +void formats_deinit(void) +{ + signal_remove("setup changed", (SIGNAL_FUNC) read_settings); +} diff --git a/src/fe-common/core/formats.h b/src/fe-common/core/formats.h index a448bc21..52c5cc24 100644 --- a/src/fe-common/core/formats.h +++ b/src/fe-common/core/formats.h @@ -4,6 +4,18 @@ #include "themes.h" #include "windows.h" +#define PRINTFLAG_BOLD 0x01 +#define PRINTFLAG_REVERSE 0x02 +#define PRINTFLAG_UNDERLINE 0x04 +#define PRINTFLAG_BEEP 0x08 +#define PRINTFLAG_BLINK 0x10 +#define PRINTFLAG_MIRC_COLOR 0x20 +#define PRINTFLAG_INDENT 0x40 +#define PRINTFLAG_NEWLINE 0x80 + +#define MAX_FORMAT_PARAMS 10 +#define DEFAULT_FORMAT_ARGLIST_SIZE 200 + enum { FORMAT_STRING, FORMAT_INT, @@ -16,7 +28,7 @@ struct _FORMAT_REC { char *def; int params; - int paramtypes[10]; + int paramtypes[MAX_FORMAT_PARAMS]; }; typedef struct { @@ -30,11 +42,18 @@ char *format_get_text(const char *module, WINDOW_REC *window, void *server, const char *target, int formatnum, ...); +/* good size for buffer is DEFAULT_FORMAT_ARGLIST_SIZE */ +void format_read_arglist(va_list va, FORMAT_REC *format, + char **arglist, int arglist_size, + char *buffer, int buffer_size); char *format_get_text_theme(THEME_REC *theme, const char *module, TEXT_DEST_REC *dest, int formatnum, ...); char *format_get_text_theme_args(THEME_REC *theme, const char *module, TEXT_DEST_REC *dest, int formatnum, va_list va); +char *format_get_text_theme_charargs(THEME_REC *theme, const char *module, + TEXT_DEST_REC *dest, int formatnum, + char **args); /* add `linestart' to start of each line in `text'. `text' may contain multiple lines separated with \n. */ @@ -49,6 +68,14 @@ void format_create_dest(TEXT_DEST_REC *dest, void *server, const char *target, int level, WINDOW_REC *window); +void format_newline(WINDOW_REC *window); + +/* strip all color (etc.) codes from `input'. returns newly allocated string. */ +char *strip_codes(const char *input); + +/* send a fully parsed text string for GUI to print */ +void format_send_to_gui(TEXT_DEST_REC *dest, const char *text); + #define FORMAT_COLOR_NOCHANGE ('0'-1) #define FORMAT_STYLE_SPECIAL 0x60 diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index 94b2952f..b74059d1 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -31,6 +31,7 @@ #include "hilight-text.h" #include "printtext.h" +#include "formats.h" #define DEFAULT_HILIGHT_LEVEL \ (MSGLEVEL_PUBLIC | MSGLEVEL_MSGS | \ @@ -135,7 +136,7 @@ static HILIGHT_REC *hilight_find(const char *text, char **channels) return NULL; } -static void sig_print_text(WINDOW_REC *window, SERVER_REC *server, const char *channel, gpointer level, const char *str) +static void sig_print_text(TEXT_DEST_REC *dest, const char *str) { if (hilight_next) { hilight_next = FALSE; @@ -243,38 +244,38 @@ char *hilight_match(const char *channel, const char *nickmask, int level, const return g_strconcat(isdigit(*color) ? "\003" : "", color, NULL); } -static void sig_print_text_stripped(WINDOW_REC *window, SERVER_REC *server, const char *channel, gpointer plevel, const char *str) +static void sig_print_text_stripped(TEXT_DEST_REC *dest, const char *str) { char *newstr, *color; - int level, oldlevel; + int oldlevel; g_return_if_fail(str != NULL); - level = GPOINTER_TO_INT(plevel); - if (level & (MSGLEVEL_NOHILIGHT|MSGLEVEL_HILIGHT)) return; + if (dest->level & (MSGLEVEL_NOHILIGHT|MSGLEVEL_HILIGHT)) + return; - color = hilight_match(channel, NULL, level, str); + color = hilight_match(dest->target, NULL, dest->level, str); if (color == NULL) return; if (*color == 3) { /* colorify */ - window->last_color = atoi(color+1); + dest->window->last_color = atoi(color+1); } - if (window != active_win) { - oldlevel = window->new_data; - window->new_data = NEWDATA_HILIGHT; - signal_emit("window hilight", 2, window, GINT_TO_POINTER(oldlevel)); - signal_emit("window activity", 2, window, GINT_TO_POINTER(oldlevel)); + if (dest->window != active_win) { + oldlevel = dest->window->new_data; + dest->window->new_data = NEWDATA_HILIGHT; + signal_emit("window hilight", 2, dest->window, GINT_TO_POINTER(oldlevel)); + signal_emit("window activity", 2, dest->window, GINT_TO_POINTER(oldlevel)); } hilight_next = FALSE; - signal_emit("print text stripped", 5, window, server, channel, GINT_TO_POINTER(level | MSGLEVEL_HILIGHT), str); - signal_stop(); + /* update the level, but let the signal pass through.. */ + dest->level |= MSGLEVEL_HILIGHT; newstr = g_strconcat(color, str, NULL); - signal_emit("print text", 5, window, server, channel, GINT_TO_POINTER(level | MSGLEVEL_HILIGHT), newstr); + signal_emit("print text", 2, dest, newstr); g_free(newstr); hilight_next = TRUE; diff --git a/src/fe-common/core/module-formats.c b/src/fe-common/core/module-formats.c index ba42964f..7a93ebe0 100644 --- a/src/fe-common/core/module-formats.c +++ b/src/fe-common/core/module-formats.c @@ -178,7 +178,7 @@ FORMAT_REC fecommon_core_formats[] = { { "theme_save_failed", "Error saving theme to $0", 1, { 0 } }, { "theme_not_found", "Theme {hilight $0} not found", 1, { 0 } }, { "window_theme_changed", "Using theme {hilight $0} in this window", 1, { 0 } }, - { "format_title", "%:[{hilight $0}] - [{hilight $1}]%:%:", 2, { 0, 0 } }, + { "format_title", "%:[{hilight $0}] - [{hilight $1}]%:", 2, { 0, 0 } }, { "format_subtitle", "[{hilight $0}]", 1, { 0 } }, { "format_item", "$0 = $1", 2, { 0, 0 } }, diff --git a/src/fe-common/core/printtext.c b/src/fe-common/core/printtext.c index d7ddb50a..6019ba88 100644 --- a/src/fe-common/core/printtext.c +++ b/src/fe-common/core/printtext.c @@ -28,13 +28,12 @@ #include "levels.h" #include "servers.h" -#include "translation.h" #include "themes.h" #include "windows.h" #include "printtext.h" static int beep_msg_level, beep_when_away; -static int timestamps, msgs_timestamps, hide_text_style; +static int timestamps, msgs_timestamps; static int timestamp_timeout; static int signal_gui_print_text; @@ -51,176 +50,39 @@ void printbeep(void) GINT_TO_POINTER(PRINTFLAG_BEEP), "", MSGLEVEL_NEVER); } -static void get_mirc_color(const char **str, int *fg_ret, int *bg_ret) +static void printformat_module_dest(const char *module, TEXT_DEST_REC *dest, + int formatnum, va_list va) { - int fg, bg; + char *arglist[MAX_FORMAT_PARAMS]; + char buffer[DEFAULT_FORMAT_ARGLIST_SIZE]; + FORMAT_REC *formats; + THEME_REC *theme; + char *str; - fg = fg_ret == NULL ? -1 : *fg_ret; - bg = bg_ret == NULL ? -1 : *bg_ret; + theme = dest->window->theme == NULL ? current_theme : + dest->window->theme; - if (!isdigit((int) **str) && **str != ',') { - fg = -1; - bg = -1; - } else { - /* foreground color */ - if (**str != ',') { - fg = **str-'0'; - (*str)++; - if (isdigit((int) **str)) { - fg = fg*10 + (**str-'0'); - (*str)++; - } - } - if (**str == ',') { - /* background color */ - (*str)++; - if (!isdigit((int) **str)) - bg = -1; - else { - bg = **str-'0'; - (*str)++; - if (isdigit((int) **str)) { - bg = bg*10 + (**str-'0'); - (*str)++; - } - } - } - } + formats = g_hash_table_lookup(default_formats, module); + format_read_arglist(va, &formats[formatnum], + arglist, sizeof(arglist)/sizeof(char *), + buffer, sizeof(buffer)); - if (fg_ret) *fg_ret = fg; - if (bg_ret) *bg_ret = bg; -} + signal_emit_id(signal_print_format, 5, theme, module, + dest, GINT_TO_POINTER(formatnum), arglist); -#define IS_COLOR_CODE(c) \ - ((c) == 2 || (c) == 3 || (c) == 4 || (c) == 6 || (c) == 7 || \ - (c) == 15 || (c) == 22 || (c) == 27 || (c) == 31) - -char *strip_codes(const char *input) -{ - const char *p; - char *str, *out; - - out = str = g_strdup(input); - for (p = input; *p != '\0'; p++) { - if (*p == 3) { - p++; - - /* mirc color */ - get_mirc_color(&p, NULL, NULL); - p--; - continue; - } - - if (*p == 4 && p[1] != '\0') { - if (p[1] >= FORMAT_STYLE_SPECIAL) { - p++; - continue; - } - - /* irssi color */ - if (p[2] != '\0') { - p += 2; - continue; - } - } - - if (!IS_COLOR_CODE(*p)) - *out++ = *p; - } - - *out = '\0'; - return str; -} - -/* parse ANSI color string */ -static char *get_ansi_color(THEME_REC *theme, char *str, - int *fg_ret, int *bg_ret, int *flags_ret) -{ - static char ansitab[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; - char *start; - int fg, bg, flags, num; - - if (*str != '[') - return str; - start = str++; - - fg = fg_ret == NULL || *fg_ret < 0 ? theme->default_color : *fg_ret; - bg = bg_ret == NULL || *bg_ret < 0 ? -1 : *bg_ret; - flags = flags_ret == NULL ? 0 : *flags_ret; - - num = 0; - for (;; str++) { - if (*str == '\0') return start; - - if (isdigit((int) *str)) { - num = num*10 + (*str-'0'); - continue; - } - - if (*str != ';' && *str != 'm') - return start; - - switch (num) { - case 0: - /* reset colors back to default */ - fg = theme->default_color; - bg = -1; - flags &= ~(PRINTFLAG_BEEP|PRINTFLAG_INDENT); - break; - case 1: - /* hilight */ - flags |= PRINTFLAG_BOLD; - break; - case 5: - /* blink */ - flags |= PRINTFLAG_BLINK; - break; - case 7: - /* reverse */ - flags |= PRINTFLAG_REVERSE; - break; - default: - if (num >= 30 && num <= 37) - fg = (fg & 0xf8) + ansitab[num-30]; - if (num >= 40 && num <= 47) { - if (bg == -1) bg = 0; - bg = (bg & 0xf8) + ansitab[num-40]; - } - break; - } - num = 0; - - if (*str == 'm') { - if (fg_ret != NULL) *fg_ret = fg; - if (bg_ret != NULL) *bg_ret = bg; - if (flags_ret != NULL) *flags_ret = flags; - - str++; - break; - } - } - - return str; + str = format_get_text_theme_args(theme, module, dest, formatnum, va); + if (*str != '\0') print_line(dest, str); + g_free(str); } void printformat_module_args(const char *module, void *server, const char *target, int level, int formatnum, va_list va) { - THEME_REC *theme; TEXT_DEST_REC dest; - char *str; format_create_dest(&dest, server, target, level, NULL); - theme = dest.window->theme == NULL ? current_theme : - dest.window->theme; - - signal_emit_id(signal_print_format, 5, theme, module, - &dest, GINT_TO_POINTER(formatnum), va); - - str = format_get_text_theme_args(theme, module, &dest, formatnum, va); - if (*str != '\0') print_line(&dest, str); - g_free(str); + printformat_module_dest(module, &dest, formatnum, va); } void printformat_module(const char *module, void *server, const char *target, int level, int formatnum, ...) @@ -235,20 +97,10 @@ void printformat_module(const char *module, void *server, const char *target, in void printformat_module_window_args(const char *module, WINDOW_REC *window, int level, int formatnum, va_list va) { - THEME_REC *theme; TEXT_DEST_REC dest; - char *str; format_create_dest(&dest, NULL, NULL, level, window); - theme = window->theme == NULL ? current_theme : - window->theme; - - signal_emit_id(signal_print_format, 5, theme, module, - &dest, GINT_TO_POINTER(formatnum), va); - - str = format_get_text_theme_args(theme, module, &dest, formatnum, va); - if (*str != '\0') print_line(&dest, str); - g_free(str); + printformat_module_dest(module, &dest, formatnum, va); } void printformat_module_window(const char *module, WINDOW_REC *window, @@ -263,7 +115,6 @@ void printformat_module_window(const char *module, WINDOW_REC *window, static void print_line(TEXT_DEST_REC *dest, const char *text) { - void *levelp; char *str, *tmp; g_return_if_fail(dest != NULL); @@ -273,14 +124,12 @@ static void print_line(TEXT_DEST_REC *dest, const char *text) str = format_add_linestart(text, tmp); g_free_not_null(tmp); - levelp = GINT_TO_POINTER(dest->level); - /* send the plain text version for logging etc.. */ tmp = strip_codes(str); - signal_emit_id(signal_print_text_stripped, 5, dest->window, dest->server, dest->target, levelp, tmp); + signal_emit_id(signal_print_text_stripped, 2, dest, tmp); g_free(tmp); - signal_emit_id(signal_print_text, 5, dest->window, dest->server, dest->target, levelp, str); + signal_emit_id(signal_print_text, 2, dest, str); g_free(str); } @@ -401,16 +250,6 @@ void printtext_window(WINDOW_REC *window, int level, const char *text, ...) g_free(str); } -static void newline(WINDOW_REC *window) -{ - window->lines++; - if (window->lines != 1) { - signal_emit_id(signal_gui_print_text, 6, window, - GINT_TO_POINTER(-1), GINT_TO_POINTER(-1), - GINT_TO_POINTER(0), "\n", GINT_TO_POINTER(-1)); - } -} - #define show_timestamp(level) \ ((level & (MSGLEVEL_NEVER|MSGLEVEL_LASTLOG)) == 0 && \ (timestamps || (msgs_timestamps && ((level) & MSGLEVEL_MSGS)))) @@ -484,141 +323,23 @@ static char *fix_line_start(TEXT_DEST_REC *dest, const char *text) return str; } -static void sig_print_text(WINDOW_REC *window, SERVER_REC *server, - const char *target, gpointer level, - const char *text) +static void sig_print_text(TEXT_DEST_REC *dest, const char *text) { - TEXT_DEST_REC dest; - char *dup, *ptr, type, *str; - int fgcolor, bgcolor; - int flags; + char *str; + g_return_if_fail(dest != NULL); g_return_if_fail(text != NULL); - g_return_if_fail(window != NULL); - format_create_dest(&dest, server, target, - GPOINTER_TO_INT(level), window); - msg_beep_check(server, dest.level); + msg_beep_check(dest->server, dest->level); - window->last_line = time(NULL); - newline(window); + dest->window->last_line = time(NULL); + format_newline(dest->window); - dup = str = fix_line_start(&dest, text); - flags = 0; fgcolor = -1; bgcolor = -1; type = '\0'; - while (*str != '\0') { - for (ptr = str; *ptr != '\0'; ptr++) { - if (IS_COLOR_CODE(*ptr)) { - type = *ptr; - *ptr++ = '\0'; - break; - } + str = fix_line_start(dest, text); + format_send_to_gui(dest, str); + g_free(str); - *ptr = (char) translation_in[(int) (unsigned char) *ptr]; - } - - if (type == 7) { - /* bell */ - if (settings_get_bool("bell_beeps")) - flags |= PRINTFLAG_BEEP; - } - if (*str != '\0' || flags & PRINTFLAG_BEEP) { - /* send the text to gui handler */ - signal_emit_id(signal_gui_print_text, 6, window, - GINT_TO_POINTER(fgcolor), - GINT_TO_POINTER(bgcolor), - GINT_TO_POINTER(flags), str, level); - flags &= ~(PRINTFLAG_BEEP|PRINTFLAG_INDENT); - } - - if (*ptr == '\0') - break; - - switch (type) - { - case 2: - /* bold */ - if (!hide_text_style) - flags ^= PRINTFLAG_BOLD; - break; - case 6: - /* blink */ - if (!hide_text_style) - flags ^= PRINTFLAG_BLINK; - break; - case 15: - /* remove all styling */ - flags &= PRINTFLAG_BEEP; - fgcolor = bgcolor = -1; - break; - case 22: - /* reverse */ - if (!hide_text_style) - flags ^= PRINTFLAG_REVERSE; - break; - case 31: - /* underline */ - if (!hide_text_style) - flags ^= PRINTFLAG_UNDERLINE; - case 27: - /* ansi color code */ - ptr = get_ansi_color(window->theme == NULL ? - current_theme : window->theme, - ptr, - hide_text_style ? NULL : &fgcolor, - hide_text_style ? NULL : &bgcolor, - hide_text_style ? NULL : &flags); - break; - case 4: - /* user specific colors */ - flags &= ~PRINTFLAG_MIRC_COLOR; - switch (*ptr) { - case FORMAT_STYLE_UNDERLINE: - flags ^= PRINTFLAG_UNDERLINE; - break; - case FORMAT_STYLE_BOLD: - flags ^= PRINTFLAG_BOLD; - break; - case FORMAT_STYLE_REVERSE: - flags ^= PRINTFLAG_REVERSE; - break; - case FORMAT_STYLE_INDENT: - flags |= PRINTFLAG_INDENT; - break; - case FORMAT_STYLE_DEFAULTS: - fgcolor = bgcolor = -1; - flags &= PRINTFLAG_INDENT; - break; - default: - if (*ptr != FORMAT_COLOR_NOCHANGE) { - fgcolor = (unsigned char) *ptr-'0'; - if (fgcolor <= 7) - flags &= ~PRINTFLAG_BOLD; - else { - /* bold */ - if (fgcolor != 8) fgcolor -= 8; - flags |= PRINTFLAG_BOLD; - } - } - ptr++; - if (*ptr != FORMAT_COLOR_NOCHANGE) - bgcolor = *ptr-'0'; - } - ptr++; - break; - case 3: - /* MIRC color */ - get_mirc_color((const char **) &ptr, - hide_text_style ? NULL : &fgcolor, - hide_text_style ? NULL : &bgcolor); - if (!hide_text_style) - flags |= PRINTFLAG_MIRC_COLOR; - break; - } - - str = ptr; - } - g_free(dup); - signal_emit_id(signal_print_text_finished, 1, window); + signal_emit_id(signal_print_text_finished, 1, dest->window); } void printtext_multiline(void *server, const char *target, int level, @@ -654,7 +375,6 @@ static void read_settings(void) timestamps = settings_get_bool("timestamps"); timestamp_timeout = settings_get_int("timestamp_timeout"); msgs_timestamps = settings_get_bool("msgs_timestamps"); - hide_text_style = settings_get_bool("hide_text_style"); beep_msg_level = level2bits(settings_get_str("beep_on_msg")); beep_when_away = settings_get_bool("beep_when_away"); } diff --git a/src/fe-common/core/printtext.h b/src/fe-common/core/printtext.h index 9ec79023..cc2ad2fb 100644 --- a/src/fe-common/core/printtext.h +++ b/src/fe-common/core/printtext.h @@ -3,14 +3,6 @@ #include "windows.h" -#define PRINTFLAG_BOLD 0x01 -#define PRINTFLAG_REVERSE 0x02 -#define PRINTFLAG_UNDERLINE 0x04 -#define PRINTFLAG_BEEP 0x08 -#define PRINTFLAG_BLINK 0x10 -#define PRINTFLAG_MIRC_COLOR 0x20 -#define PRINTFLAG_INDENT 0x40 - void printformat_module(const char *module, void *server, const char *target, int level, int formatnum, ...); void printformat_module_window(const char *module, WINDOW_REC *window, int level, int formatnum, ...); @@ -22,9 +14,6 @@ void printtext_window(WINDOW_REC *window, int level, const char *text, ...); void printtext_multiline(void *server, const char *target, int level, const char *format, const char *text); void printbeep(void); -/* strip all color (etc.) codes from `input'. returns newly allocated string. */ -char *strip_codes(const char *input); - void printtext_init(void); void printtext_deinit(void); diff --git a/src/fe-common/core/window-activity.c b/src/fe-common/core/window-activity.c index 12188d96..96237e6a 100644 --- a/src/fe-common/core/window-activity.c +++ b/src/fe-common/core/window-activity.c @@ -29,39 +29,38 @@ #include "window-items.h" #include "nicklist.h" #include "hilight-text.h" +#include "formats.h" static const char *noact_channels; static int hilight_level, activity_level; -static void sig_hilight_text(WINDOW_REC *window, SERVER_REC *server, - const char *channel, void *levelptr, - const char *msg) +static void sig_hilight_text(TEXT_DEST_REC *dest, const char *msg) { - int level, oldlevel, new_data; + int oldlevel, new_data; - level = GPOINTER_TO_INT(levelptr); - if (window == active_win || (level & (MSGLEVEL_NEVER|MSGLEVEL_NO_ACT))) + if (dest->window == active_win || + (dest->level & (MSGLEVEL_NEVER|MSGLEVEL_NO_ACT))) return; /* hilights and private messages get HILIGHT status, public messages get MSGS status and rest get TEXT */ - new_data = (level & (MSGLEVEL_HILIGHT|hilight_level)) ? + new_data = (dest->level & (MSGLEVEL_HILIGHT|hilight_level)) ? NEWDATA_HILIGHT : - ((level & activity_level) ? NEWDATA_MSG : NEWDATA_TEXT); + ((dest->level & activity_level) ? NEWDATA_MSG : NEWDATA_TEXT); /* check that channel isn't in "don't show activity" list */ if (new_data < NEWDATA_HILIGHT && - channel != NULL && find_substr(noact_channels, channel)) + dest->target != NULL && find_substr(noact_channels, dest->target)) return; - oldlevel = window->new_data; - if (window->new_data < new_data) { - window->new_data = new_data; - window->last_color = hilight_last_nick_color();; - signal_emit("window hilight", 1, window); + oldlevel = dest->window->new_data; + if (dest->window->new_data < new_data) { + dest->window->new_data = new_data; + dest->window->last_color = hilight_last_nick_color();; + signal_emit("window hilight", 1, dest->window); } - signal_emit("window activity", 2, window, GINT_TO_POINTER(oldlevel)); + signal_emit("window activity", 2, dest->window, GINT_TO_POINTER(oldlevel)); } static void sig_dehilight(WINDOW_REC *window, WI_ITEM_REC *item) diff --git a/src/fe-common/core/windows.c b/src/fe-common/core/windows.c index 994bcfe2..88127452 100644 --- a/src/fe-common/core/windows.c +++ b/src/fe-common/core/windows.c @@ -416,7 +416,8 @@ static void sig_print_text(void) /* day changed, print notice about it to every window */ for (tmp = windows; tmp != NULL; tmp = tmp->next) { printformat_window(tmp->data, MSGLEVEL_NEVER, IRCTXT_DAYCHANGE, - tm->tm_mday, tm->tm_mon+1, 1900+tm->tm_year, month); + tm->tm_mday, tm->tm_mon+1, + 1900+tm->tm_year, month); } } diff --git a/src/fe-text/gui-printtext.c b/src/fe-text/gui-printtext.c index 19329216..f7ca62bd 100644 --- a/src/fe-text/gui-printtext.c +++ b/src/fe-text/gui-printtext.c @@ -23,8 +23,9 @@ #include "commands.h" #include "settings.h" -#include "printtext.h" #include "windows.h" +#include "formats.h" +#include "printtext.h" #include "themes.h" #include "screen.h" @@ -35,6 +36,9 @@ int mirc_colors[] = { 15, 0, 1, 2, 12, 6, 5, 4, 14, 10, 3, 11, 9, 13, 8, 7, 15 }; static int scrollback_lines, scrollback_hours; +static int scrollback_save_formats; +static GString *format; + #define mark_temp_eol(text) \ memcpy((text)->buffer + (text)->pos, "\0\200", 2); @@ -256,7 +260,8 @@ static void line_add_colors(GUI_WINDOW_REC *gui, int fg, int bg, int flags) gui->last_color = fg | (bg << 4); } -static void gui_printtext(WINDOW_REC *window, gpointer fgcolor, gpointer bgcolor, gpointer pflags, char *str, gpointer level) +static void gui_printtext(WINDOW_REC *window, void *fgcolor, void *bgcolor, + void *pflags, char *str, void *level) { GUI_WINDOW_REC *gui; LINE_REC *line; @@ -275,9 +280,8 @@ static void gui_printtext(WINDOW_REC *window, gpointer fgcolor, gpointer bgcolor if (gui->cur_text == NULL) create_text_chunk(gui); - /* \n can be only at the start of the line.. */ - if (*str == '\n') { - str++; + /* newline can be only at the start of the line.. */ + if (flags & PRINTFLAG_NEWLINE) { linebuf_add(gui, "\0\200", 2); /* mark EOL */ line = create_line(gui, 0); @@ -368,6 +372,15 @@ static void sig_printtext_finished(WINDOW_REC *window) GUI_WINDOW_REC *gui; gui = WINDOW_GUI(window); + + if (format->len > 0) { + /* save format of the line */ + linebuf_add(gui, format->str, format->len); + mark_temp_eol(gui->cur_text); + + g_string_truncate(format, 0); + } + if (is_window_visible(window)) { #ifdef USE_CURSES_WINDOWS screen_refresh(gui->parent->curses_win); @@ -377,19 +390,57 @@ static void sig_printtext_finished(WINDOW_REC *window) } } +static void sig_print_format(THEME_REC *theme, const char *module, + TEXT_DEST_REC *dest, void *formatnump, + char **args) +{ + FORMAT_REC *formats; + int formatnum, n; + + if (!scrollback_save_formats) + return; + + formatnum = GPOINTER_TO_INT(formatnump); + formats = g_hash_table_lookup(default_formats, module); + + /* */ + g_string_truncate(format, 0); + + g_string_append_c(format, '\0'); + g_string_append_c(format, (char)LINE_CMD_FORMAT); + + g_string_append(format, module); + g_string_append_c(format, '\0'); + + g_string_append_c(format, (char)LINE_CMD_FORMAT); + g_string_append(format, formats[formatnum].tag); + + for (n = 0; n < formats[formatnum].params; n++) { + g_string_append_c(format, '\0'); + g_string_append_c(format, (char)LINE_CMD_FORMAT); + + g_string_append(format, args[n]); + } +} + static void read_settings(void) { scrollback_lines = settings_get_int("scrollback_lines"); scrollback_hours = settings_get_int("scrollback_hours"); + scrollback_save_formats = settings_get_bool("scrollback_save_formats"); } void gui_printtext_init(void) { + format = g_string_new(NULL); + settings_add_int("history", "scrollback_lines", 500); settings_add_int("history", "scrollback_hours", 24); + settings_add_bool("history", "scrollback_save_formats", FALSE); signal_add("gui print text", (SIGNAL_FUNC) gui_printtext); signal_add("print text finished", (SIGNAL_FUNC) sig_printtext_finished); + signal_add("print format", (SIGNAL_FUNC) sig_print_format); signal_add("setup changed", (SIGNAL_FUNC) read_settings); command_bind("clear", NULL, (SIGNAL_FUNC) cmd_clear); @@ -398,8 +449,11 @@ void gui_printtext_init(void) void gui_printtext_deinit(void) { + g_string_free(format, TRUE); + signal_remove("gui print text", (SIGNAL_FUNC) gui_printtext); signal_remove("print text finished", (SIGNAL_FUNC) sig_printtext_finished); + signal_remove("print format", (SIGNAL_FUNC) sig_print_format); signal_remove("setup changed", (SIGNAL_FUNC) read_settings); command_unbind("clear", (SIGNAL_FUNC) cmd_clear); } diff --git a/src/fe-text/gui-textwidget.c b/src/fe-text/gui-textwidget.c index 04055bb4..c691f63b 100644 --- a/src/fe-text/gui-textwidget.c +++ b/src/fe-text/gui-textwidget.c @@ -63,6 +63,7 @@ static gchar *gui_window_line2text(LINE_REC *line) else switch ((guchar) *ptr) { case LINE_CMD_EOL: + case LINE_CMD_FORMAT: ret = str->str; g_string_free(str, FALSE); return ret; diff --git a/src/fe-text/gui-windows.c b/src/fe-text/gui-windows.c index 52947d16..fefb9ae7 100644 --- a/src/fe-text/gui-windows.c +++ b/src/fe-text/gui-windows.c @@ -277,7 +277,7 @@ static LINE_CACHE_REC *gui_window_line_cache(GUI_WINDOW_REC *gui, if (*ptr == '\0') { /* command */ ptr++; - if (*ptr == LINE_CMD_EOL) + if (*ptr == LINE_CMD_EOL || *ptr == LINE_CMD_FORMAT) break; if (*ptr == LINE_CMD_CONTINUE) { @@ -445,6 +445,7 @@ static void single_line_draw(GUI_WINDOW_REC *gui, int ypos, case LINE_CMD_OVERFLOW: g_error("buffer overflow! (draw)"); case LINE_CMD_EOL: + case LINE_CMD_FORMAT: return; case LINE_CMD_UNDERLINE: color ^= ATTR_UNDERLINE; @@ -780,7 +781,8 @@ GList *gui_window_find_text(WINDOW_REC *window, gchar *text, GList *startline, i memcpy(&tmp, ptr+1, sizeof(gchar *)); ptr = tmp-1; } - else if ((guchar) *ptr == LINE_CMD_EOL) + else if ((guchar) *ptr == LINE_CMD_EOL || + (guchar) *ptr == LINE_CMD_FORMAT) break; else if ((guchar) *ptr == LINE_CMD_OVERFLOW) g_error("buffer overflow! (find)"); diff --git a/src/fe-text/gui-windows.h b/src/fe-text/gui-windows.h index 1600ab3b..1d037722 100644 --- a/src/fe-text/gui-windows.h +++ b/src/fe-text/gui-windows.h @@ -19,8 +19,12 @@ enum { LINE_CMD_COLOR0, /* change to black, would be same as \0\0 but it breaks things.. */ LINE_CMD_COLOR8, /* change to dark grey, normally 8 = bold black */ LINE_CMD_UNDERLINE, /* enable/disable underlining */ - LINE_CMD_INDENT, /* if line is split, indent it at this position */ - LINE_CMD_BLINK /* blinking background */ + LINE_CMD_INDENT, /* if line is split, indent it at this position */ + LINE_CMD_BLINK, /* blinking background */ + LINE_CMD_FORMAT /* end of line, but next will come the format that was used to create the + text in format - fields are separated + with \0 and last argument ends with \0. \0 is allowed + anywhere */ }; typedef struct { diff --git a/src/fe-text/statusbar-items.c b/src/fe-text/statusbar-items.c index 37c060dc..0d316880 100644 --- a/src/fe-text/statusbar-items.c +++ b/src/fe-text/statusbar-items.c @@ -32,9 +32,10 @@ #include "windows.h" #include "window-items.h" +#include "printtext.h" +#include "formats.h" #include "screen.h" -#include "printtext.h" #include "statusbar.h" #include "gui-windows.h" #include "gui-printtext.h"