summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Sirainen <cras@irssi.org>2000-11-12 20:20:05 +0000
committercras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564>2000-11-12 20:20:05 +0000
commitd1330fff6d1a6cf2c37c14d1054ef9cf73d5f5fe (patch)
treee0778ca64424eae592e2c7edb1c0e7b01dec139e
parent61f33a6bb2d319aba85406a1788da230dca1f5a8 (diff)
downloadirssi-d1330fff6d1a6cf2c37c14d1054ef9cf73d5f5fe.zip
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
-rw-r--r--src/fe-common/core/fe-log.c14
-rw-r--r--src/fe-common/core/formats.c359
-rw-r--r--src/fe-common/core/formats.h29
-rw-r--r--src/fe-common/core/hilight-text.c31
-rw-r--r--src/fe-common/core/module-formats.c2
-rw-r--r--src/fe-common/core/printtext.c346
-rw-r--r--src/fe-common/core/printtext.h11
-rw-r--r--src/fe-common/core/window-activity.c29
-rw-r--r--src/fe-common/core/windows.c3
-rw-r--r--src/fe-text/gui-printtext.c64
-rw-r--r--src/fe-text/gui-textwidget.c1
-rw-r--r--src/fe-text/gui-windows.c6
-rw-r--r--src/fe-text/gui-windows.h8
-rw-r--r--src/fe-text/statusbar-items.c3
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;
@@ -272,16 +268,32 @@ 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;
-
- 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;
-}
-
-/* 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;
+ char *arglist[MAX_FORMAT_PARAMS];
+ char buffer[DEFAULT_FORMAT_ARGLIST_SIZE];
+ FORMAT_REC *formats;
+ THEME_REC *theme;
+ char *str;
- 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;
+ theme = dest->window->theme == NULL ? current_theme :
+ dest->window->theme;
- if (*str == 'm') {
- if (fg_ret != NULL) *fg_ret = fg;
- if (bg_ret != NULL) *bg_ret = bg;
- if (flags_ret != NULL) *flags_ret = flags;
+ formats = g_hash_table_lookup(default_formats, module);
+ format_read_arglist(va, &formats[formatnum],
+ arglist, sizeof(arglist)/sizeof(char *),
+ buffer, sizeof(buffer));
- str++;
- break;
- }
- }
+ signal_emit_id(signal_print_format, 5, theme, module,
+ dest, GINT_TO_POINTER(formatnum), arglist);
- 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);
-
- window->last_line = time(NULL);
- newline(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;
- }
+ msg_beep_check(dest->server, dest->level);
- *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;
+ dest->window->last_line = time(NULL);
+ format_newline(dest->window);
- 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 = fix_line_start(dest, text);
+ format_send_to_gui(dest, str);
+ g_free(str);
- 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);
+
+ /* <module><format_name><arg...> */
+ 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 <module><format_name><arg><arg2...> - fields are separated
+ with \0<format> and last argument ends with \0<eol>. \0<continue> 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"