2 textbuffer-reformat.c : Reformatting lines in text buffer
4 Copyright (C) 1999-2001 Timo Sirainen
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include "gui-windows.h"
28 #include "gui-printtext.h"
29 #include "textbuffer.h"
31 static GString *format;
32 static int scrollback_save_formats;
34 /* Read one block between \0<format>s */
35 static char *line_read_format(unsigned const char **text)
40 str = g_string_new(NULL);
43 if ((*text)[1] == LINE_CMD_EOL) {
44 /* leave text at \0<eof> */
47 if ((*text)[1] == LINE_CMD_FORMAT_CONT) {
48 /* leave text at \0<format_cont> */
53 if (**text == LINE_CMD_FORMAT) {
54 /* move text to start after \0<format> */
59 if (**text == LINE_CMD_CONTINUE) {
62 memcpy(&tmp, (*text)+1, sizeof(char *));
65 } else if (**text & 0x80)
70 g_string_append_c(str, (char) **text);
75 g_string_free(str, FALSE);
79 static char *textbuffer_line_get_format(WINDOW_REC *window, LINE_REC *line,
82 const unsigned char *text;
83 char *module, *format_name, *args[MAX_FORMAT_PARAMS], *ret;
85 int formatnum, argcount;
87 text = (const unsigned char *) line->text;
89 /* skip the beginning of the line until we find the format */
90 g_free(line_read_format(&text));
91 if (text[1] == LINE_CMD_FORMAT_CONT) {
93 g_string_append_c(raw, '\0');
94 g_string_append_c(raw, (char)LINE_CMD_FORMAT_CONT);
99 /* read format information */
100 module = line_read_format(&text);
101 format_name = line_read_format(&text);
104 g_string_append_c(raw, '\0');
105 g_string_append_c(raw, (char)LINE_CMD_FORMAT);
107 g_string_append(raw, module);
109 g_string_append_c(raw, '\0');
110 g_string_append_c(raw, (char)LINE_CMD_FORMAT);
112 g_string_append(raw, format_name);
115 formatnum = format_find_tag(module, format_name);
120 memset(args, 0, sizeof(args));
121 while (*text != '\0' || text[1] != LINE_CMD_EOL) {
122 args[argcount] = line_read_format(&text);
124 g_string_append_c(raw, '\0');
125 g_string_append_c(raw,
126 (char)LINE_CMD_FORMAT);
128 g_string_append(raw, args[argcount]);
133 /* get the format text */
134 format_create_dest(&dest, NULL, NULL, line->info.level, window);
135 ret = format_get_text_theme_charargs(current_theme,
139 g_free(args[--argcount]);
148 void textbuffer_reformat_line(WINDOW_REC *window, LINE_REC *line)
153 LINE_INFO_REC line_info;
155 char *str, *tmp, *prestr, *linestart, *leveltag;
157 gui = WINDOW_GUI(window);
159 raw = g_string_new(NULL);
160 str = textbuffer_line_get_format(window, line, raw);
162 if (str == NULL && raw->len == 2 &&
163 raw->str[1] == (char)LINE_CMD_FORMAT_CONT) {
164 /* multiline format, format explained in one the
165 following lines. remove this line. */
166 textbuffer_view_remove_line(gui->view, line);
167 } else if (str != NULL) {
168 /* FIXME: ugly ugly .. and this can't handle
169 unformatted lines.. */
170 g_string_append_c(raw, '\0');
171 g_string_append_c(raw, (char)LINE_CMD_EOL);
173 line_prev = line->prev;
174 memcpy(&line_info, &line->info, sizeof(line_info));
175 textbuffer_view_remove_line(gui->view, line); line = NULL;
177 format_create_dest(&dest, NULL, NULL, line_info.level, window);
179 linestart = format_get_line_start(current_theme, &dest, line_info.time);
180 leveltag = format_get_level_tag(current_theme, &dest);
182 prestr = g_strconcat(linestart == NULL ? "" : linestart,
184 g_free_not_null(linestart);
185 g_free_not_null(leveltag);
187 tmp = format_add_linestart(str, prestr);
191 gui_printtext_after(&dest, line_prev, tmp);
194 line = textbuffer_insert(gui->view->buffer, gui->insert_after,
195 (unsigned char *) raw->str,
196 raw->len, &line_info);
197 textbuffer_view_insert_line(gui->view, line);
199 g_string_free(raw, TRUE);
202 static void sig_print_format(THEME_REC *theme, const char *module,
203 TEXT_DEST_REC *dest, void *formatnump,
209 if (!scrollback_save_formats)
212 formatnum = GPOINTER_TO_INT(formatnump);
213 formats = g_hash_table_lookup(default_formats, module);
215 /* <module><format_name><arg...> */
216 g_string_truncate(format, 0);
218 g_string_append_c(format, '\0');
219 g_string_append_c(format, (char)LINE_CMD_FORMAT);
221 g_string_append(format, module);
223 g_string_append_c(format, '\0');
224 g_string_append_c(format, (char)LINE_CMD_FORMAT);
226 g_string_append(format, formats[formatnum].tag);
228 for (n = 0; n < formats[formatnum].params; n++) {
229 g_string_append_c(format, '\0');
230 g_string_append_c(format, (char)LINE_CMD_FORMAT);
233 g_string_append(format, args[n]);
237 static void sig_gui_printtext_finished(WINDOW_REC *window)
240 LINE_REC *insert_after;
242 if (format->len == 0)
245 /* save format of the line */
246 gui = WINDOW_GUI(window);
247 insert_after = gui->use_insert_after ?
248 gui->insert_after : gui->view->buffer->cur_line;
250 textbuffer_insert(gui->view->buffer, insert_after,
251 (unsigned char *) format->str,
254 g_string_truncate(format, 0);
257 static void read_settings(void)
259 scrollback_save_formats = settings_get_bool("scrollback_save_formats");
262 void textbuffer_reformat_init(void)
264 format = g_string_new(NULL);
265 settings_add_bool("history", "scrollback_save_formats", FALSE);
268 signal_add("print format", (SIGNAL_FUNC) sig_print_format);
269 signal_add_first("gui print text finished", (SIGNAL_FUNC) sig_gui_printtext_finished);
270 signal_add("setup changed", (SIGNAL_FUNC) read_settings);
273 void textbuffer_reformat_deinit(void)
275 g_string_free(format, TRUE);
277 signal_remove("print format", (SIGNAL_FUNC) sig_print_format);
278 signal_remove("print text finished", (SIGNAL_FUNC) sig_gui_printtext_finished);
279 signal_remove("setup changed", (SIGNAL_FUNC) read_settings);