diff options
author | Timo Sirainen <cras@irssi.org> | 2001-04-14 22:24:56 +0000 |
---|---|---|
committer | cras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564> | 2001-04-14 22:24:56 +0000 |
commit | adb7eced395ba88816a365768fee56e04a0a0ec5 (patch) | |
tree | d4eedd91f292418468acf3eb68aef9bdfe4d3563 /src/fe-text/textbuffer-commands.c | |
parent | d98fddd79647e9387ecbf674f317b02f4b78d7e2 (diff) | |
download | irssi-adb7eced395ba88816a365768fee56e04a0a0ec5.zip |
Rewrote text buffer handling in windows - try #3.
/SET scrollback_save_formats + /SB REDRAW is broken currently. There's some
other minor things that might need to be changed.
This time it allows the same window to be visible multiple times in screen,
like you could make a new split window where to scroll back and find
something while still seeing the new messages at the other window, this
however doesn't work yet but it should be quite easy to make it :)
I've tested that pretty much everything should work with this, new lines can
be added at any position and lines can be removed from any position and
screen should be updated properly. Screen resizing should also work
perfectly now (maybe it did previously too, not sure) and hopefully now we
won't see any of those ugly strange bugs some people were having. Also this
time the same code isn't written 2-3 times to do some specific thing, like
scrolling has now only one view_scroll() function instead of the 3 separate
functions it used to have :)
git-svn-id: http://svn.irssi.org/repos/irssi/trunk@1442 dbcabf3a-b0e7-0310-adc4-f8d773084564
Diffstat (limited to 'src/fe-text/textbuffer-commands.c')
-rw-r--r-- | src/fe-text/textbuffer-commands.c | 297 |
1 files changed, 297 insertions, 0 deletions
diff --git a/src/fe-text/textbuffer-commands.c b/src/fe-text/textbuffer-commands.c new file mode 100644 index 00000000..92ec70bd --- /dev/null +++ b/src/fe-text/textbuffer-commands.c @@ -0,0 +1,297 @@ +/* + textbuffer-commands.c : Text buffer handling + + Copyright (C) 1999-2001 Timo Sirainen + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "module.h" +#include "signals.h" +#include "commands.h" +#include "misc.h" +#include "levels.h" + +#include "printtext.h" +#include "gui-windows.h" + +/* SYNTAX: CLEAR */ +static void cmd_clear(const char *data) +{ + GHashTable *optlist; + void *free_arg; + GSList *tmp; + + g_return_if_fail(data != NULL); + + if (!cmd_get_params(data, &free_arg, PARAM_FLAG_OPTIONS, + "clear", &optlist)) return; + + if (g_hash_table_lookup(optlist, "all") == NULL) { + /* clear active window */ + textbuffer_view_clear(WINDOW_GUI(active_win)->view); + } else { + /* clear all windows */ + for (tmp = windows; tmp != NULL; tmp = tmp->next) { + WINDOW_REC *window = tmp->data; + + textbuffer_view_clear(WINDOW_GUI(window)->view); + } + } + + cmd_params_free(free_arg); +} + +static void cmd_scrollback(const char *data, SERVER_REC *server, + WI_ITEM_REC *item) +{ + command_runsub("scrollback", data, server, item); +} + +/* SYNTAX: SCROLLBACK CLEAR */ +static void cmd_scrollback_clear(void) +{ + textbuffer_view_remove_all_lines(WINDOW_GUI(active_win)->view); +} + +static void scrollback_goto_line(int linenum) +{ + TEXT_BUFFER_VIEW_REC *view; + + view = WINDOW_GUI(active_win)->view; + if (view->buffer->lines_count == 0) + return; + + textbuffer_view_scroll_line(view, view->buffer->lines->data); + gui_window_scroll(active_win, linenum); +} + +static void scrollback_goto_time(const char *datearg, const char *timearg) +{ + GList *tmp; + struct tm tm; + time_t now, stamp; + int day, month; + + /* [dd[.mm] | -<days ago>] hh:mi[:ss] */ + now = stamp = time(NULL); + if (*datearg == '-') { + /* -<days ago> */ + stamp -= atoi(datearg+1) * 3600*24; + memcpy(&tm, localtime(&stamp), sizeof(struct tm)); + } else if (*timearg != '\0') { + /* dd[.mm] */ + memcpy(&tm, localtime(&stamp), sizeof(struct tm)); + + day = month = 0; + sscanf(datearg, "%d.%d", &day, &month); + if (day <= 0) return; + + if (month <= 0) { + /* month not given */ + if (day > tm.tm_mday) { + /* last month's day */ + if (tm.tm_mon > 0) + tm.tm_mon--; + else { + /* last year's day.. */ + tm.tm_year--; + tm.tm_mon = 11; + } + } + } else { + month--; + if (month > tm.tm_mon) + tm.tm_year--; + tm.tm_mon = month; + } + + tm.tm_mday = day; + stamp = mktime(&tm); + } + else + { + /* only time given, move it to timearg */ + timearg = datearg; + } + + /* hh:mi[:ss] */ + memcpy(&tm, localtime(&stamp), sizeof(struct tm)); + tm.tm_sec = 0; + sscanf(timearg, "%d:%d:%d", &tm.tm_hour, &tm.tm_min, &tm.tm_sec); + stamp = mktime(&tm); + + if (stamp > now && timearg == datearg) { + /* we used /SB GOTO 23:59 or something, we want to jump to + previous day's 23:59 time instead of into future. */ + stamp -= 3600*24; + } + + if (stamp > now) { + /* we're still looking into future, don't bother checking */ + return; + } + + /* scroll to first line after timestamp */ + tmp = textbuffer_view_get_lines(WINDOW_GUI(active_win)->view); + for (; tmp != NULL; tmp = tmp->next) { + LINE_REC *rec = tmp->data; + + if (rec->info.time >= stamp) { + gui_window_scroll_line(active_win, rec); + break; + } + } +} + +/* SYNTAX: SCROLLBACK GOTO <+|-linecount>|<linenum>|<timestamp> */ +static void cmd_scrollback_goto(const char *data) +{ + char *datearg, *timearg; + void *free_arg; + int lines; + + if (!cmd_get_params(data, &free_arg, 2, &datearg, &timearg)) + return; + + if (*timearg == '\0' && (*datearg == '-' || *datearg == '+')) { + /* go forward/backward n lines */ + lines = atoi(datearg + (*datearg == '-' ? 0 : 1)); + gui_window_scroll(active_win, lines); + } else if (*timearg == '\0' && is_numeric(datearg, '\0')) { + /* go to n'th line. */ + scrollback_goto_line(atoi(datearg)); + } else { + /* should be timestamp */ + scrollback_goto_time(datearg, timearg); + } + + cmd_params_free(free_arg); +} + +/* SYNTAX: SCROLLBACK HOME */ +static void cmd_scrollback_home(const char *data) +{ + TEXT_BUFFER_REC *buffer; + + buffer = WINDOW_GUI(active_win)->view->buffer; + if (buffer->lines_count > 0) + gui_window_scroll_line(active_win, buffer->lines->data); +} + +/* SYNTAX: SCROLLBACK END */ +static void cmd_scrollback_end(const char *data) +{ + TEXT_BUFFER_VIEW_REC *view; + + view = WINDOW_GUI(active_win)->view; + if (view->bottom_startline == NULL) + return; + + textbuffer_view_scroll_line(view, view->bottom_startline->data); + gui_window_scroll(active_win, view->bottom_subline); +} + +/* SYNTAX: SCROLLBACK REDRAW */ +static void cmd_scrollback_redraw(void) +{ +#if 0 + GUI_WINDOW_REC *gui; + GList *tmp, *next; + + gui = WINDOW_GUI(active_win); + + screen_refresh_freeze(); + for (tmp = gui->lines; tmp != NULL; tmp = next) { + next = tmp->next; + gui_window_reformat_line(active_win, tmp->data); + } + + gui_window_redraw(active_win); + screen_refresh_thaw(); +#endif +} + +static void cmd_scrollback_status(void) +{ + GSList *tmp; + int window_kb, total_lines, total_kb; + + total_lines = 0; total_kb = 0; + for (tmp = windows; tmp != NULL; tmp = tmp->next) { + WINDOW_REC *window = tmp->data; + TEXT_BUFFER_VIEW_REC *view; + + view = WINDOW_GUI(window)->view; + + window_kb = g_slist_length(view->buffer->text_chunks)* + LINE_TEXT_CHUNK_SIZE/1024; + total_lines += view->buffer->lines_count; + total_kb += window_kb; + printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, + "Window %d: %d lines, %dkB of data", + window->refnum, view->buffer->lines_count, + window_kb); + } + + printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, + "Total: %d lines, %dkB of data", + total_lines, total_kb); +} + +static void sig_away_changed(SERVER_REC *server) +{ + GSList *tmp; + + if (!server->usermode_away) + return; + + for (tmp = windows; tmp != NULL; tmp = tmp->next) { + WINDOW_REC *rec = tmp->data; + + textbuffer_view_set_bookmark_bottom(WINDOW_GUI(rec)->view, + "lastlog_last_away"); + } +} + +void textbuffer_commands_init(void) +{ + command_bind("clear", NULL, (SIGNAL_FUNC) cmd_clear); + command_bind("scrollback", NULL, (SIGNAL_FUNC) cmd_scrollback); + command_bind("scrollback clear", NULL, (SIGNAL_FUNC) cmd_scrollback_clear); + command_bind("scrollback goto", NULL, (SIGNAL_FUNC) cmd_scrollback_goto); + command_bind("scrollback home", NULL, (SIGNAL_FUNC) cmd_scrollback_home); + command_bind("scrollback end", NULL, (SIGNAL_FUNC) cmd_scrollback_end); + command_bind("scrollback redraw", NULL, (SIGNAL_FUNC) cmd_scrollback_redraw); + command_bind("scrollback status", NULL, (SIGNAL_FUNC) cmd_scrollback_status); + + command_set_options("clear", "all"); + + signal_add("away mode changed", (SIGNAL_FUNC) sig_away_changed); +} + +void textbuffer_commands_deinit(void) +{ + command_unbind("clear", (SIGNAL_FUNC) cmd_clear); + command_unbind("scrollback", (SIGNAL_FUNC) cmd_scrollback); + command_unbind("scrollback clear", (SIGNAL_FUNC) cmd_scrollback_clear); + command_unbind("scrollback goto", (SIGNAL_FUNC) cmd_scrollback_goto); + command_unbind("scrollback home", (SIGNAL_FUNC) cmd_scrollback_home); + command_unbind("scrollback end", (SIGNAL_FUNC) cmd_scrollback_end); + command_unbind("scrollback redraw", (SIGNAL_FUNC) cmd_scrollback_redraw); + command_unbind("scrollback status", (SIGNAL_FUNC) cmd_scrollback_status); + + signal_remove("away mode changed", (SIGNAL_FUNC) sig_away_changed); +} |