diff options
Diffstat (limited to 'src/fe-common')
-rw-r--r-- | src/fe-common/core/Makefile.am | 1 | ||||
-rw-r--r-- | src/fe-common/core/command-history.c | 233 | ||||
-rw-r--r-- | src/fe-common/core/command-history.h | 19 | ||||
-rw-r--r-- | src/fe-common/core/fe-settings.c | 7 | ||||
-rw-r--r-- | src/fe-common/core/fe-settings.h | 6 | ||||
-rw-r--r-- | src/fe-common/core/fe-windows.c | 4 | ||||
-rw-r--r-- | src/fe-common/core/formats.c | 30 | ||||
-rw-r--r-- | src/fe-common/core/hilight-text.c | 7 |
8 files changed, 261 insertions, 46 deletions
diff --git a/src/fe-common/core/Makefile.am b/src/fe-common/core/Makefile.am index 29cc941a..cf4e8ee3 100644 --- a/src/fe-common/core/Makefile.am +++ b/src/fe-common/core/Makefile.am @@ -55,6 +55,7 @@ pkginc_fe_common_core_HEADERS = \ fe-exec.h \ fe-messages.h \ fe-queries.h \ + fe-settings.h \ fe-tls.h \ formats.h \ hilight-text.h \ diff --git a/src/fe-common/core/command-history.c b/src/fe-common/core/command-history.c index 55474b1b..32d7adaa 100644 --- a/src/fe-common/core/command-history.c +++ b/src/fe-common/core/command-history.c @@ -30,10 +30,93 @@ #include "command-history.h" /* command history */ +static GList *history_entries; static HISTORY_REC *global_history; static int window_history; static GSList *histories; +static HISTORY_ENTRY_REC *history_entry_new(HISTORY_REC *history, const char *text) +{ + HISTORY_ENTRY_REC *entry; + + entry = g_new0(HISTORY_ENTRY_REC, 1); + entry->text = g_strdup(text); + entry->history = history; + entry->time = time(NULL); + + return entry; +} + +static void history_entry_destroy(HISTORY_ENTRY_REC *entry) +{ + g_free((char *)entry->text); + g_free(entry); +} + +GList *command_history_list_last(HISTORY_REC *history) +{ + GList *link; + + link = g_list_last(history_entries); + while (link != NULL && history != NULL && ((HISTORY_ENTRY_REC *)link->data)->history != history) { + link = link->prev; + } + + return link; +} + +GList *command_history_list_first(HISTORY_REC *history) +{ + GList *link; + + link = history_entries; + while (link != NULL && history != NULL && ((HISTORY_ENTRY_REC *)link->data)->history != history) { + link = link->next; + } + + return link; +} + +GList *command_history_list_prev(HISTORY_REC *history, GList *pos) +{ + GList *link; + + link = pos != NULL ? pos->prev : NULL; + while (link != NULL && history != NULL && ((HISTORY_ENTRY_REC *)link->data)->history != history) { + link = link->prev; + } + + return link; +} + +GList *command_history_list_next(HISTORY_REC *history, GList *pos) +{ + GList *link; + + link = pos != NULL ? pos->next : NULL; + while (link != NULL && history != NULL && ((HISTORY_ENTRY_REC *)link->data)->history != history) { + link = link->next; + } + + return link; +} + +static void command_history_clear_pos_for_unlink_func(HISTORY_REC *history, GList* link) +{ + if (history->pos == link) { + history->pos = command_history_list_next(history, link); + history->redo = 1; + } +} + +static void history_list_delete_link_and_destroy(GList *link) +{ + g_slist_foreach(histories, + (GFunc) command_history_clear_pos_for_unlink_func, link); + history_entry_destroy(link->data); + history_entries = g_list_delete_link(history_entries, link); +} + void command_history_add(HISTORY_REC *history, const char *text) { GList *link; @@ -41,21 +124,19 @@ void command_history_add(HISTORY_REC *history, const char *text) g_return_if_fail(history != NULL); g_return_if_fail(text != NULL); - link = g_list_last(history->list); - if (link != NULL && g_strcmp0(link->data, text) == 0) - return; /* same as previous entry */ + link = command_history_list_last(history); + if (link != NULL && g_strcmp0(((HISTORY_ENTRY_REC *)link->data)->text, text) == 0) + return; /* same as previous entry */ if (settings_get_int("max_command_history") < 1 || history->lines < settings_get_int("max_command_history")) history->lines++; else { - link = history->list; - g_free(link->data); - history->list = g_list_remove_link(history->list, link); - g_list_free_1(link); + link = command_history_list_first(history); + history_list_delete_link_and_destroy(link); } - history->list = g_list_append(history->list, g_strdup(text)); + history_entries = g_list_append(history_entries, history_entry_new(history, text)); } HISTORY_REC *command_history_find(HISTORY_REC *history) @@ -87,6 +168,61 @@ HISTORY_REC *command_history_find_name(const char *name) return NULL; } +static int history_entry_after_time_sort(const HISTORY_ENTRY_REC *a, const HISTORY_ENTRY_REC *b) +{ + return a->time == b->time ? 1 : a->time - b->time; +} + +void command_history_load_entry(time_t history_time, HISTORY_REC *history, const char *text) +{ + HISTORY_ENTRY_REC *entry; + + g_return_if_fail(history != NULL); + g_return_if_fail(text != NULL); + + entry = g_new0(HISTORY_ENTRY_REC, 1); + entry->text = g_strdup(text); + entry->history = history; + entry->time = history_time; + + history->lines++; + + history_entries = g_list_insert_sorted(history_entries, entry, (GCompareFunc)history_entry_after_time_sort); +} + +static int history_entry_find_func(const HISTORY_ENTRY_REC *data, const HISTORY_ENTRY_REC *user_data) +{ + if ((user_data->time == -1 || (data->time == user_data->time)) && + (user_data->history == NULL || (data->history == user_data->history)) && + g_strcmp0(data->text, user_data->text) == 0) { + return 0; + } else { + return -1; + } +} + +gboolean command_history_delete_entry(time_t history_time, HISTORY_REC *history, const char *text) +{ + GList *link; + HISTORY_ENTRY_REC entry; + + g_return_val_if_fail(history != NULL, FALSE); + g_return_val_if_fail(text != NULL, FALSE); + + entry.text = text; + entry.history = history; + entry.time = history_time; + + link = g_list_find_custom(history_entries, &entry, (GCompareFunc)history_entry_find_func); + if (link != NULL) { + ((HISTORY_ENTRY_REC *)link->data)->history->lines--; + history_list_delete_link_and_destroy(link); + return TRUE; + } else { + return FALSE; + } +} + HISTORY_REC *command_history_current(WINDOW_REC *window) { HISTORY_REC *rec; @@ -104,32 +240,44 @@ HISTORY_REC *command_history_current(WINDOW_REC *window) return global_history; } -const char *command_history_prev(WINDOW_REC *window, const char *text) +static const char *command_history_prev_int(WINDOW_REC *window, const char *text, gboolean global) { HISTORY_REC *history; GList *pos; history = command_history_current(window); pos = history->pos; + history->redo = 0; if (pos != NULL) { /* don't go past the first entry (no wrap around) */ - if (history->pos->prev != NULL) - history->pos = history->pos->prev; + GList *prev = command_history_list_prev(global ? NULL : history, history->pos); + if (prev != NULL) + history->pos = prev; } else { - history->pos = g_list_last(history->list); + history->pos = command_history_list_last(global ? NULL : history); } if (*text != '\0' && - (pos == NULL || g_strcmp0(pos->data, text) != 0)) { + (pos == NULL || g_strcmp0(((HISTORY_ENTRY_REC *)pos->data)->text, text) != 0)) { /* save the old entry to history */ command_history_add(history, text); } - return history->pos == NULL ? text : history->pos->data; + return history->pos == NULL ? text : ((HISTORY_ENTRY_REC *)history->pos->data)->text; } -const char *command_history_next(WINDOW_REC *window, const char *text) +const char *command_history_prev(WINDOW_REC *window, const char *text) +{ + return command_history_prev_int(window, text, FALSE); +} + +const char *command_global_history_prev(WINDOW_REC *window, const char *text) +{ + return command_history_prev_int(window, text, TRUE); +} + +static const char *command_history_next_int(WINDOW_REC *window, const char *text, gboolean global) { HISTORY_REC *history; GList *pos; @@ -137,15 +285,43 @@ const char *command_history_next(WINDOW_REC *window, const char *text) history = command_history_current(window); pos = history->pos; - if (pos != NULL) - history->pos = history->pos->next; + if (!(history->redo) && pos != NULL) + history->pos = command_history_list_next(global ? NULL : history, history->pos); + history->redo = 0; if (*text != '\0' && - (pos == NULL || g_strcmp0(pos->data, text) != 0)) { + (pos == NULL || g_strcmp0(((HISTORY_ENTRY_REC *)pos->data)->text, text) != 0)) { /* save the old entry to history */ command_history_add(history, text); } - return history->pos == NULL ? "" : history->pos->data; + return history->pos == NULL ? "" : ((HISTORY_ENTRY_REC *)history->pos->data)->text; +} + +const char *command_history_next(WINDOW_REC *window, const char *text) +{ + return command_history_next_int(window, text, FALSE); +} + +const char *command_global_history_next(WINDOW_REC *window, const char *text) +{ + return command_history_next_int(window, text, TRUE); +} + +const char *command_history_delete_current(WINDOW_REC *window, const char *text) +{ + HISTORY_REC *history; + GList *pos; + + history = command_history_current(window); + pos = history->pos; + + if (pos != NULL && g_strcmp0(((HISTORY_ENTRY_REC *)pos->data)->text, text) == 0) { + ((HISTORY_ENTRY_REC *)pos->data)->history->lines--; + history_list_delete_link_and_destroy(pos); + } + + history->redo = 0; + return history->pos == NULL ? "" : ((HISTORY_ENTRY_REC *)history->pos->data)->text; } void command_history_clear_pos_func(HISTORY_REC *history, gpointer user_data) @@ -175,12 +351,17 @@ HISTORY_REC *command_history_create(const char *name) void command_history_clear(HISTORY_REC *history) { + GList *link, *next; + g_return_if_fail(history != NULL); command_history_clear_pos_func(history, NULL); - g_list_foreach(history->list, (GFunc) g_free, NULL); - g_list_free(history->list); - history->list = NULL; + link = command_history_list_first(history); + while (link != NULL) { + next = command_history_list_next(history, link); + history_list_delete_link_and_destroy(link); + link = next; + } history->lines = 0; } @@ -264,8 +445,8 @@ static char *special_history_func(const char *text, void *item, int *free_ret) ret = NULL; history = command_history_current(window); - for (tmp = history->list; tmp != NULL; tmp = tmp->next) { - const char *line = tmp->data; + for (tmp = command_history_list_first(history); tmp != NULL; tmp = command_history_list_next(history, tmp)) { + const char *line = ((HISTORY_ENTRY_REC *)tmp->data)->text; if (match_wildcards(findtext, line)) { *free_ret = TRUE; @@ -289,6 +470,8 @@ void command_history_init(void) special_history_func_set(special_history_func); + history_entries = NULL; + global_history = command_history_create(NULL); read_settings(); @@ -308,4 +491,6 @@ void command_history_deinit(void) signal_remove("setup changed", (SIGNAL_FUNC) read_settings); command_history_destroy(global_history); + + g_list_free_full(history_entries, (GDestroyNotify) history_entry_destroy); } diff --git a/src/fe-common/core/command-history.h b/src/fe-common/core/command-history.h index 45126092..ed093415 100644 --- a/src/fe-common/core/command-history.h +++ b/src/fe-common/core/command-history.h @@ -6,12 +6,19 @@ typedef struct { char *name; - GList *list, *pos; + GList *pos; int lines; int refcount; + int redo:1; } HISTORY_REC; +typedef struct { + const char *text; + HISTORY_REC *history; + time_t time; +} HISTORY_ENTRY_REC; + HISTORY_REC *command_history_find(HISTORY_REC *history); HISTORY_REC *command_history_find_name(const char *name); @@ -21,9 +28,19 @@ void command_history_init(void); void command_history_deinit(void); void command_history_add(HISTORY_REC *history, const char *text); +void command_history_load_entry(time_t time, HISTORY_REC *history, const char *text); +gboolean command_history_delete_entry(time_t history_time, HISTORY_REC *history, const char *text); + +GList *command_history_list_last(HISTORY_REC *history); +GList *command_history_list_first(HISTORY_REC *history); +GList *command_history_list_prev(HISTORY_REC *history, GList *pos); +GList *command_history_list_next(HISTORY_REC *history, GList *pos); const char *command_history_prev(WINDOW_REC *window, const char *text); const char *command_history_next(WINDOW_REC *window, const char *text); +const char *command_global_history_prev(WINDOW_REC *window, const char *text); +const char *command_global_history_next(WINDOW_REC *window, const char *text); +const char *command_history_delete_current(WINDOW_REC *window, const char *text); void command_history_clear_pos(WINDOW_REC *window); diff --git a/src/fe-common/core/fe-settings.c b/src/fe-common/core/fe-settings.c index abbd45a8..de9f67a1 100644 --- a/src/fe-common/core/fe-settings.c +++ b/src/fe-common/core/fe-settings.c @@ -26,7 +26,7 @@ #include "misc.h" #include "lib-config/iconfig.h" #include "settings.h" - +#include "fe-settings.h" #include "levels.h" #include "printtext.h" #include "keyboard.h" @@ -41,6 +41,11 @@ static void set_print(SETTINGS_REC *rec) g_free(value); } +void fe_settings_set_print(const char *key) +{ + set_print(settings_get_record(key)); +} + static void set_print_pattern(const char *pattern) { GSList *sets, *tmp; diff --git a/src/fe-common/core/fe-settings.h b/src/fe-common/core/fe-settings.h new file mode 100644 index 00000000..dd33f223 --- /dev/null +++ b/src/fe-common/core/fe-settings.h @@ -0,0 +1,6 @@ +#ifndef __FE_CHANNELS_H +#define __FE_CHANNELS_H + +void fe_settings_set_print(const char *key); + +#endif diff --git a/src/fe-common/core/fe-windows.c b/src/fe-common/core/fe-windows.c index 0afa2914..93f2e3f3 100644 --- a/src/fe-common/core/fe-windows.c +++ b/src/fe-common/core/fe-windows.c @@ -563,8 +563,10 @@ GSList *windows_get_sorted(void) begin = windows_seq_begin(); while (iter != begin) { + WINDOW_REC *rec; + iter = g_sequence_iter_prev(iter); - WINDOW_REC *rec = g_sequence_get(iter); + rec = g_sequence_get(iter); sorted = g_slist_prepend(sorted, rec); } diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index 005e6fb7..37db6f7c 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -1072,31 +1072,27 @@ static void get_mirc_color(const char **str, int *fg_ret, int *bg_ret) fg = fg_ret == NULL ? -1 : *fg_ret; bg = bg_ret == NULL ? -1 : *bg_ret; - if (!i_isdigit(**str) && **str != ',') { + if (!i_isdigit(**str)) { + /* turn off color */ fg = -1; bg = -1; } else { /* foreground color */ - if (**str != ',') { - fg = **str-'0'; + fg = **str-'0'; + (*str)++; + if (i_isdigit(**str)) { + fg = fg*10 + (**str-'0'); (*str)++; - if (i_isdigit(**str)) { - fg = fg*10 + (**str-'0'); - (*str)++; - } } - if (**str == ',') { + + if ((*str)[0] == ',' && i_isdigit((*str)[1])) { /* background color */ - if (!i_isdigit((*str)[1])) - bg = -1; - else { - (*str)++; - bg = **str-'0'; + (*str)++; + bg = **str-'0'; + (*str)++; + if (i_isdigit(**str)) { + bg = bg*10 + (**str-'0'); (*str)++; - if (i_isdigit(**str)) { - bg = bg*10 + (**str-'0'); - (*str)++; - } } } } diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index 62e6f0de..b9912457 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -106,6 +106,7 @@ static void hilight_destroy(HILIGHT_REC *rec) if (rec->channels != NULL) g_strfreev(rec->channels); g_free_not_null(rec->color); g_free_not_null(rec->act_color); + g_free_not_null(rec->servertag); g_free(rec->text); g_free(rec); } @@ -424,7 +425,7 @@ static void read_hilight_config(void) CONFIG_NODE *node; HILIGHT_REC *rec; GSList *tmp; - char *text, *color; + char *text, *color, *servertag; hilights_destroy_all(); @@ -467,7 +468,9 @@ static void read_hilight_config(void) rec->nickmask = config_node_get_bool(node, "mask", FALSE); rec->fullword = config_node_get_bool(node, "fullword", FALSE); rec->regexp = config_node_get_bool(node, "regexp", FALSE); - rec->servertag = config_node_get_str(node, "servertag", NULL); + servertag = config_node_get_str(node, "servertag", NULL); + rec->servertag = servertag == NULL || *servertag == '\0' ? NULL : + g_strdup(servertag); hilight_init_rec(rec); node = iconfig_node_section(node, "channels", -1); |