mirror of
https://github.com/irssi/irssi.git
synced 2026-08-09 20:00:23 +02:00
Lots of changes again. Biggest ones:
- window's text buffer should work better - themes are almost working, you can change the text formats with /format - automatically try to rejoin the channel after 5 minutes if the join there failed because it was "temporarily unavailable" (netsplits) - generally cleaning code.. git-svn-id: http://svn.irssi.org/repos/irssi/trunk@216 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
parent
969cfe8abc
commit
cbdaf7d06d
63 changed files with 2471 additions and 1912 deletions
|
|
@ -17,10 +17,11 @@ libfe_common_core_la_SOURCES = \
|
|||
hilight-text.c \
|
||||
keyboard.c \
|
||||
module-formats.c \
|
||||
window-activity.c \
|
||||
printtext.c \
|
||||
themes.c \
|
||||
translation.c \
|
||||
window-activity.c \
|
||||
window-commands.c \
|
||||
window-items.c \
|
||||
windows.c
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "module.h"
|
||||
#include "module-formats.h"
|
||||
#include "levels.h"
|
||||
#include "settings.h"
|
||||
|
||||
|
|
@ -50,6 +51,9 @@ void fe_settings_deinit(void);
|
|||
void window_activity_init(void);
|
||||
void window_activity_deinit(void);
|
||||
|
||||
void window_commands_init(void);
|
||||
void window_commands_deinit(void);
|
||||
|
||||
void fe_core_commands_init(void);
|
||||
void fe_core_commands_deinit(void);
|
||||
|
||||
|
|
@ -73,8 +77,10 @@ void fe_common_core_init(void)
|
|||
settings_add_int("lookandfeel", "tab_orientation", 3);*/
|
||||
settings_add_str("lookandfeel", "current_theme", "default");
|
||||
|
||||
themes_init();
|
||||
theme_register(fecommon_core_formats);
|
||||
|
||||
autorun_init();
|
||||
window_activity_init();
|
||||
hilight_text_init();
|
||||
command_history_init();
|
||||
keyboard_init();
|
||||
|
|
@ -82,9 +88,10 @@ void fe_common_core_init(void)
|
|||
fe_log_init();
|
||||
fe_server_init();
|
||||
fe_settings_init();
|
||||
themes_init();
|
||||
translation_init();
|
||||
windows_init();
|
||||
window_activity_init();
|
||||
window_commands_init();
|
||||
window_items_init();
|
||||
fe_core_commands_init();
|
||||
}
|
||||
|
|
@ -92,7 +99,6 @@ void fe_common_core_init(void)
|
|||
void fe_common_core_deinit(void)
|
||||
{
|
||||
autorun_deinit();
|
||||
window_activity_deinit();
|
||||
hilight_text_deinit();
|
||||
command_history_deinit();
|
||||
keyboard_deinit();
|
||||
|
|
@ -100,11 +106,15 @@ void fe_common_core_deinit(void)
|
|||
fe_log_deinit();
|
||||
fe_server_deinit();
|
||||
fe_settings_deinit();
|
||||
themes_deinit();
|
||||
translation_deinit();
|
||||
windows_deinit();
|
||||
window_activity_deinit();
|
||||
window_commands_deinit();
|
||||
window_items_deinit();
|
||||
fe_core_commands_deinit();
|
||||
|
||||
theme_unregister();
|
||||
themes_deinit();
|
||||
}
|
||||
|
||||
void fe_common_core_finish_init(void)
|
||||
|
|
|
|||
|
|
@ -30,16 +30,11 @@
|
|||
#include "windows.h"
|
||||
|
||||
static const char *ret_texts[] = {
|
||||
"Invalid parameter",
|
||||
NULL,
|
||||
"Not enough parameters given",
|
||||
"Not connected to IRC server yet",
|
||||
"Not joined to any channels yet",
|
||||
"Error: getsockname() failed",
|
||||
"Error: listen() failed",
|
||||
"Multiple matches found, be more specific",
|
||||
"Nick not found",
|
||||
"Not joined to such channel",
|
||||
"Server not found",
|
||||
"Channel not fully synchronized yet, try again after a while",
|
||||
"Doing this is not a good idea. Add -YES if you really mean it",
|
||||
};
|
||||
|
|
@ -269,9 +264,15 @@ static void cmd_unknown(const char *data, void *server, WI_ITEM_REC *item)
|
|||
signal_stop();
|
||||
}
|
||||
|
||||
static void event_cmderror(gpointer error)
|
||||
static void event_cmderror(gpointer errorp)
|
||||
{
|
||||
printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, ret_texts[GPOINTER_TO_INT(error)]);
|
||||
int error;
|
||||
|
||||
error = GPOINTER_TO_INT(errorp);
|
||||
if (error == CMDERR_ERRNO)
|
||||
printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, g_strerror(errno));
|
||||
else
|
||||
printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, ret_texts[error]);
|
||||
}
|
||||
|
||||
void fe_core_commands_init(void)
|
||||
|
|
|
|||
|
|
@ -297,25 +297,27 @@ static void autolog_log(void *server, const char *target)
|
|||
g_free(fname);
|
||||
}
|
||||
|
||||
/* write to logs created with /WINDOW LOG */
|
||||
static void sig_printtext_stripped(void *server, const char *target, gpointer levelp, const char *text)
|
||||
static void sig_printtext_stripped(WINDOW_REC *window, void *server, const char *target, gpointer levelp, const char *text)
|
||||
{
|
||||
char windownum[MAX_INT_STRLEN];
|
||||
WINDOW_REC *window;
|
||||
LOG_REC *log;
|
||||
int level;
|
||||
|
||||
level = GPOINTER_TO_INT(levelp);
|
||||
if (level == MSGLEVEL_NEVER) return;
|
||||
|
||||
/* let autolog create the log records */
|
||||
if ((autolog_level & level) && target != NULL && *target != '\0')
|
||||
autolog_log(server, target);
|
||||
|
||||
window = window_find_closest(server, target, level);
|
||||
if (window != NULL) {
|
||||
ltoa(windownum, window->refnum);
|
||||
/* save to log created with /WINDOW LOG */
|
||||
ltoa(windownum, window->refnum);
|
||||
log = log_find_item(windownum);
|
||||
if (log != NULL) log_write_rec(log, text);
|
||||
|
||||
log = log_find_item(windownum);
|
||||
if (log != NULL) log_write_rec(log, text);
|
||||
}
|
||||
/* save line to logs */
|
||||
if (logs != NULL)
|
||||
log_write(target, level, text);
|
||||
}
|
||||
|
||||
static int sig_autoremove(void)
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ static HILIGHT_REC *hilight_find(const char *text, char **channels)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void sig_print_text(SERVER_REC *server, const char *channel, gpointer level, const char *str)
|
||||
static void sig_print_text(WINDOW_REC *window, SERVER_REC *server, const char *channel, gpointer level, const char *str)
|
||||
{
|
||||
if (hilight_next) {
|
||||
hilight_next = FALSE;
|
||||
|
|
@ -140,7 +140,7 @@ static void sig_print_text(SERVER_REC *server, const char *channel, gpointer lev
|
|||
}
|
||||
}
|
||||
|
||||
static void sig_print_text_stripped(SERVER_REC *server, const char *channel, gpointer plevel, const char *str)
|
||||
static void sig_print_text_stripped(WINDOW_REC *window, SERVER_REC *server, const char *channel, gpointer plevel, const char *str)
|
||||
{
|
||||
GSList *tmp;
|
||||
char *color, *newstr;
|
||||
|
|
@ -184,7 +184,7 @@ static void sig_print_text_stripped(SERVER_REC *server, const char *channel, gpo
|
|||
|
||||
if (color == NULL) color = "\00316";
|
||||
newstr = g_strconcat(isdigit(*color) ? "\003" : "", color, str, NULL);
|
||||
signal_emit("print text", 4, server, channel, GINT_TO_POINTER(level | MSGLEVEL_HILIGHT), newstr);
|
||||
signal_emit("print text", 5, window, server, channel, GINT_TO_POINTER(level | MSGLEVEL_HILIGHT), newstr);
|
||||
g_free(newstr);
|
||||
|
||||
hilight_next = TRUE;
|
||||
|
|
|
|||
|
|
@ -258,12 +258,6 @@ static void read_keyboard_config(void)
|
|||
CONFIG_NODE *node;
|
||||
GSList *tmp;
|
||||
|
||||
while (keyinfos != NULL)
|
||||
keyinfo_remove(keyinfos->data);
|
||||
if (keys != NULL) g_hash_table_destroy(keys);
|
||||
|
||||
keys = g_hash_table_new((GHashFunc) g_str_hash, (GCompareFunc) g_str_equal);
|
||||
|
||||
node = iconfig_node_traverse("keyboard", FALSE);
|
||||
if (node == NULL) return;
|
||||
|
||||
|
|
@ -280,7 +274,9 @@ static void read_keyboard_config(void)
|
|||
|
||||
void keyboard_init(void)
|
||||
{
|
||||
keyinfos = NULL; keys = NULL;
|
||||
keys = g_hash_table_new((GHashFunc) g_str_hash, (GCompareFunc) g_str_equal);
|
||||
keyinfos = NULL;
|
||||
|
||||
key_bind("command", NULL, "Run any IRC command", NULL, (SIGNAL_FUNC) sig_command);
|
||||
|
||||
read_keyboard_config();
|
||||
|
|
|
|||
|
|
@ -21,73 +21,75 @@
|
|||
#include "module.h"
|
||||
#include "printtext.h"
|
||||
|
||||
FORMAT_REC fecommon_core_formats[] =
|
||||
{
|
||||
{ MODULE_NAME, "Core", 0 },
|
||||
FORMAT_REC fecommon_core_formats[] = {
|
||||
{ MODULE_NAME, "Core", 0 },
|
||||
|
||||
/* ---- */
|
||||
{ NULL, "Windows", 0 },
|
||||
/* ---- */
|
||||
{ NULL, "Windows", 0 },
|
||||
|
||||
{ "line_start", "%B-%W!%B-%n ", 0 },
|
||||
{ "line_start_irssi", "%B-%W!%B- %WIrssi:%n ", 0 },
|
||||
{ "timestamp", "[$[-2.0]3:$[-2.0]4] ", 6, { 1, 1, 1, 1, 1, 1 } },
|
||||
{ "daychange", "Day changed to ${[-2.0]1}-$[-2.0]0 $2", 3, { 1, 1, 1 } },
|
||||
{ "talking_with", "You are now talking with %_$0%_", 1, { 0 } },
|
||||
{ "refnum_too_low", "Window number must be greater than 1", 0 },
|
||||
{ "windowlist_header", "Ref Name Active item Server Level", 0 },
|
||||
{ "windowlist_line", "$[3]0 %|$[20]1 $[15]2 $[15]3 $4", 5, { 1, 0, 0, 0, 0 } },
|
||||
{ "windowlist_footer", "", 0 },
|
||||
{ "line_start", "%B-%W!%B-%n ", 0 },
|
||||
{ "line_start_irssi", "%B-%W!%B- %WIrssi:%n ", 0 },
|
||||
{ "timestamp", "[$[-2.0]3:$[-2.0]4] ", 6, { 1, 1, 1, 1, 1, 1 } },
|
||||
{ "daychange", "Day changed to $[-2.0]{0}-$[-2.0]1 $2", 3, { 1, 1, 1 } },
|
||||
{ "talking_with", "You are now talking with %_$0%_", 1, { 0 } },
|
||||
{ "refnum_too_low", "Window number must be greater than 1", 0 },
|
||||
{ "refnum_not_found", "No such window: $0", 1, { 0 } }, /*REMOVE!!!!!!!!*/
|
||||
{ "windowlist_header", "Ref Name Active item Server Level", 0 },
|
||||
{ "windowlist_line", "$[3]0 %|$[20]1 $[15]2 $[15]3 $4", 5, { 1, 0, 0, 0, 0 } },
|
||||
{ "windowlist_footer", "", 0 },
|
||||
|
||||
/* ---- */
|
||||
{ NULL, "Server", 0 },
|
||||
/* ---- */
|
||||
{ NULL, "Server", 0 },
|
||||
|
||||
{ "looking_up", "Looking up %_$0%_", 1, { 0 } },
|
||||
{ "connecting", "Connecting to %_$0%_ %K[%n$1%K]%n port %_$2%_", 3, { 0, 0, 1 } },
|
||||
{ "connection_established", "Connection to %_$0%_ established", 1, { 0 } },
|
||||
{ "cant_connect", "Unable to connect server %_$0%_ port %_$1%_ %K[%n$2%K]", 3, { 0, 1, 0 } },
|
||||
{ "connection_lost", "Connection lost to %_$0%_", 1, { 0 } },
|
||||
{ "server_quit", "Disconnecting from server $0: %K[%n$1%K]", 2, { 0, 0 } },
|
||||
{ "server_changed", "Changed to %_$2%_ server %_$1%_", 3, { 0, 0, 0 } },
|
||||
{ "unknown_server_tag", "Unknown server tag %_$0%_", 1, { 0 } },
|
||||
{ "looking_up", "Looking up %_$0%_", 1, { 0 } },
|
||||
{ "connecting", "Connecting to %_$0%_ %K[%n$1%K]%n port %_$2%_", 3, { 0, 0, 1 } },
|
||||
{ "connection_established", "Connection to %_$0%_ established", 1, { 0 } },
|
||||
{ "cant_connect", "Unable to connect server %_$0%_ port %_$1%_ %K[%n$2%K]", 3, { 0, 1, 0 } },
|
||||
{ "connection_lost", "Connection lost to %_$0%_", 1, { 0 } },
|
||||
{ "server_quit", "Disconnecting from server $0: %K[%n$1%K]", 2, { 0, 0 } },
|
||||
{ "server_changed", "Changed to %_$2%_ server %_$1%_", 3, { 0, 0, 0 } },
|
||||
{ "unknown_server_tag", "Unknown server tag %_$0%_", 1, { 0 } },
|
||||
|
||||
/* ---- */
|
||||
{ NULL, "Highlighting", 0 },
|
||||
/* ---- */
|
||||
{ NULL, "Highlighting", 0 },
|
||||
|
||||
{ "hilight_header", "Highlights:", 0 },
|
||||
{ "hilight_line", "$[-4]0 $1 $2 $3$3$4$5", 7, { 1, 0, 0, 0, 0, 0, 0 } },
|
||||
{ "hilight_footer", "", 0 },
|
||||
{ "hilight_not_found", "Highlight not found: $0", 1, { 0 } },
|
||||
{ "hilight_removed", "Highlight removed: $0", 1, { 0 } },
|
||||
{ "hilight_header", "Highlights:", 0 },
|
||||
{ "hilight_line", "$[-4]0 $1 $2 $3$3$4$5", 7, { 1, 0, 0, 0, 0, 0, 0 } },
|
||||
{ "hilight_footer", "", 0 },
|
||||
{ "hilight_not_found", "Highlight not found: $0", 1, { 0 } },
|
||||
{ "hilight_removed", "Highlight removed: $0", 1, { 0 } },
|
||||
|
||||
/* ---- */
|
||||
{ NULL, "Aliases", 0 },
|
||||
/* ---- */
|
||||
{ NULL, "Aliases", 0 },
|
||||
|
||||
{ "alias_added", "Alias $0 added", 1, { 0 } },
|
||||
{ "alias_removed", "Alias $0 removed", 1, { 0 } },
|
||||
{ "alias_not_found", "No such alias: $0", 1, { 0 } },
|
||||
{ "aliaslist_header", "Aliases:", 0 },
|
||||
{ "aliaslist_line", "$[10]0 $1", 2, { 0, 0 } },
|
||||
{ "aliaslist_footer", "", 0 },
|
||||
{ "alias_added", "Alias $0 added", 1, { 0 } },
|
||||
{ "alias_removed", "Alias $0 removed", 1, { 0 } },
|
||||
{ "alias_not_found", "No such alias: $0", 1, { 0 } },
|
||||
{ "aliaslist_header", "Aliases:", 0 },
|
||||
{ "aliaslist_line", "$[10]0 $1", 2, { 0, 0 } },
|
||||
{ "aliaslist_footer", "", 0 },
|
||||
|
||||
/* ---- */
|
||||
{ NULL, "Logging", 0 },
|
||||
/* ---- */
|
||||
{ NULL, "Logging", 0 },
|
||||
|
||||
{ "log_opened", "Log file %W$0%n opened", 1, { 0 } },
|
||||
{ "log_closed", "Log file %W$0%n closed", 1, { 0 } },
|
||||
{ "log_create_failed", "Couldn't create log file %W$0", 1, { 0 } },
|
||||
{ "log_locked", "Log file %W$0%n is locked, probably by another running Irssi", 1, { 0 } },
|
||||
{ "log_not_open", "Log file %W$0%n not open", 1, { 0 } },
|
||||
{ "log_started", "Started logging to file %W$0", 1, { 0 } },
|
||||
{ "log_stopped", "Stopped logging to file %W$0", 1, { 0 } },
|
||||
{ "log_list_header", "Logs:", 0 },
|
||||
{ "log_list", "$0: $1 $2$3$4", 5, { 0, 0, 0, 0, 0 } },
|
||||
{ "log_list_footer", "", 0 },
|
||||
{ "windowlog_file", "Window LOGFILE set to $0", 1, { 0 } },
|
||||
{ "windowlog_file_logging", "Can't change window's logfile while log is on", 0 },
|
||||
{ "log_opened", "Log file %W$0%n opened", 1, { 0 } },
|
||||
{ "log_closed", "Log file %W$0%n closed", 1, { 0 } },
|
||||
{ "log_create_failed", "Couldn't create log file %W$0", 1, { 0 } },
|
||||
{ "log_locked", "Log file %W$0%n is locked, probably by another running Irssi", 1, { 0 } },
|
||||
{ "log_not_open", "Log file %W$0%n not open", 1, { 0 } },
|
||||
{ "log_started", "Started logging to file %W$0", 1, { 0 } },
|
||||
{ "log_stopped", "Stopped logging to file %W$0", 1, { 0 } },
|
||||
{ "log_list_header", "Logs:", 0 },
|
||||
{ "log_list", "$0: $1 $2$3$4", 5, { 0, 0, 0, 0, 0 } },
|
||||
{ "log_list_footer", "", 0 },
|
||||
{ "windowlog_file", "Window LOGFILE set to $0", 1, { 0 } },
|
||||
{ "windowlog_file_logging", "Can't change window's logfile while log is on", 0 },
|
||||
|
||||
/* ---- */
|
||||
{ NULL, "Misc", 0 },
|
||||
/* ---- */
|
||||
{ NULL, "Misc", 0 },
|
||||
|
||||
{ "not_toggle", "Value must be either ON, OFF or TOGGLE", 0 },
|
||||
{ "perl_error", "Perl error: $0", 1, { 0 } }
|
||||
{ "not_toggle", "Value must be either ON, OFF or TOGGLE", 0 },
|
||||
{ "perl_error", "Perl error: $0", 1, { 0 } },
|
||||
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -65,6 +65,3 @@ enum {
|
|||
};
|
||||
|
||||
extern FORMAT_REC fecommon_core_formats[];
|
||||
#define MODULE_FORMATS fecommon_core_formats
|
||||
|
||||
#include "printformat.h"
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
/* printformat(...) = printformat_format(module_formats, ...)
|
||||
|
||||
Could this be any harder? :) With GNU C compiler and C99 compilers,
|
||||
use #define. With others use either inline functions if they are
|
||||
supported or static functions if they are not..
|
||||
*/
|
||||
#if defined (__GNUC__) && !defined (__STRICT_ANSI__)
|
||||
/* GCC */
|
||||
# define printformat(server, channel, level, formatnum...) \
|
||||
printformat_format(MODULE_FORMATS, server, channel, level, ##formatnum)
|
||||
#elif defined (_ISOC99_SOURCE)
|
||||
/* C99 */
|
||||
# define printformat(server, channel, level, formatnum, ...) \
|
||||
printformat_format(MODULE_FORMATS, server, channel, level, formatnum, __VA_ARGS__)
|
||||
#else
|
||||
/* inline/static */
|
||||
static
|
||||
#ifdef G_CAN_INLINE
|
||||
inline
|
||||
#endif
|
||||
void printformat(void *server, const char *channel, int level, int formatnum, ...)
|
||||
{
|
||||
printformat_format(MODULE_FORMATS, server, channel, level, formatnum);
|
||||
}
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef __PRINTTEXT_H
|
||||
#define __PRINTTEXT_H
|
||||
|
||||
#include "windows.h"
|
||||
|
||||
enum {
|
||||
FORMAT_STRING,
|
||||
FORMAT_INT,
|
||||
|
|
@ -24,9 +26,14 @@ typedef struct {
|
|||
#define PRINTFLAG_MIRC_COLOR 0x20
|
||||
#define PRINTFLAG_INDENT 0x40
|
||||
|
||||
void printformat_format(FORMAT_REC *formats, void *server, const char *channel, int level, int formatnum, ...);
|
||||
void printformat_module(const char *module, void *server, const char *channel, int level, int formatnum, ...);
|
||||
void printformat_module_window(const char *module, WINDOW_REC *window, int level, int formatnum, ...);
|
||||
|
||||
void printtext(void *server, const char *channel, int level, const char *str, ...);
|
||||
void printformat_module_args(const char *module, void *server, const char *channel, int level, int formatnum, va_list va);
|
||||
void printformat_module_window_args(const char *module, WINDOW_REC *window, int level, int formatnum, va_list va);
|
||||
|
||||
void printtext(void *server, const char *channel, int level, const char *text, ...);
|
||||
void printtext_window(WINDOW_REC *window, int level, const char *text, ...);
|
||||
void printtext_multiline(void *server, const char *channel, int level, const char *format, const char *text);
|
||||
void printbeep(void);
|
||||
|
||||
|
|
@ -36,4 +43,51 @@ char *strip_codes(const char *input);
|
|||
void printtext_init(void);
|
||||
void printtext_deinit(void);
|
||||
|
||||
/* printformat(...) = printformat_format(MODULE_NAME, ...)
|
||||
|
||||
Could this be any harder? :) With GNU C compiler and C99 compilers,
|
||||
use #define. With others use either inline functions if they are
|
||||
supported or static functions if they are not..
|
||||
*/
|
||||
#if defined (__GNUC__) && !defined (__STRICT_ANSI__)
|
||||
/* GCC */
|
||||
# define printformat(server, channel, level, formatnum...) \
|
||||
printformat_module(MODULE_NAME, server, channel, level, ##formatnum)
|
||||
# define printformat_window(window, level, formatnum...) \
|
||||
printformat_module_window(MODULE_NAME, window, level, ##formatnum)
|
||||
#elif defined (_ISOC99_SOURCE)
|
||||
/* C99 */
|
||||
# define printformat(server, channel, level, formatnum, ...) \
|
||||
printformat_module(MODULE_NAME, server, channel, level, formatnum, __VA_ARGS__)
|
||||
# define printformat_window(window, level, formatnum, ...) \
|
||||
printformat_module_window(MODULE_NAME, window, level, formatnum, __VA_ARGS__)
|
||||
#else
|
||||
/* inline/static */
|
||||
static
|
||||
#ifdef G_CAN_INLINE
|
||||
inline
|
||||
#endif
|
||||
void printformat(void *server, const char *channel, int level, int formatnum, ...)
|
||||
{
|
||||
va_list va;
|
||||
|
||||
va_start(va, formatnum);
|
||||
printformat_module_args(MODULE_NAME, server, channel, level, formatnum, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
static
|
||||
#ifdef G_CAN_INLINE
|
||||
inline
|
||||
#endif
|
||||
void printformat_window(WINDOW_REC *window, int level, int formatnum, ...)
|
||||
{
|
||||
va_list va;
|
||||
|
||||
va_start(va, formatnum);
|
||||
printformat_module_window_args(MODULE_NAME, window, level, formatnum, va);
|
||||
va_end(va);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#include "module.h"
|
||||
#include "signals.h"
|
||||
#include "commands.h"
|
||||
#include "levels.h"
|
||||
#include "misc.h"
|
||||
#include "lib-config/iconfig.h"
|
||||
#include "settings.h"
|
||||
|
|
@ -29,6 +31,7 @@
|
|||
|
||||
GSList *themes;
|
||||
THEME_REC *current_theme;
|
||||
GHashTable *default_formats;
|
||||
|
||||
THEME_REC *theme_create(const char *path, const char *name)
|
||||
{
|
||||
|
|
@ -46,17 +49,15 @@ THEME_REC *theme_create(const char *path, const char *name)
|
|||
return rec;
|
||||
}
|
||||
|
||||
static void theme_destroy_hash(const char *key, MODULE_THEME_REC *rec)
|
||||
static void theme_module_destroy(const char *key, MODULE_THEME_REC *rec)
|
||||
{
|
||||
int n, max;
|
||||
int n;
|
||||
|
||||
max = strarray_length(rec->formatlist);
|
||||
for (n = 0; n < max; n++)
|
||||
if (rec->format[n] != NULL)
|
||||
g_free(rec->format[n]);
|
||||
g_free(rec->format);
|
||||
for (n = 0; n < rec->count; n++)
|
||||
if (rec->formats[n] != NULL)
|
||||
g_free(rec->formats[n]);
|
||||
g_free(rec->formats);
|
||||
|
||||
g_strfreev(rec->formatlist);
|
||||
g_free(rec->name);
|
||||
g_free(rec);
|
||||
}
|
||||
|
|
@ -64,7 +65,7 @@ static void theme_destroy_hash(const char *key, MODULE_THEME_REC *rec)
|
|||
void theme_destroy(THEME_REC *rec)
|
||||
{
|
||||
signal_emit("theme destroyed", 1, rec);
|
||||
g_hash_table_foreach(rec->modules, (GHFunc) theme_destroy_hash, NULL);
|
||||
g_hash_table_foreach(rec->modules, (GHFunc) theme_module_destroy, NULL);
|
||||
g_hash_table_destroy(rec->modules);
|
||||
|
||||
if (rec->bg_pixmap != NULL) g_free(rec->bg_pixmap);
|
||||
|
|
@ -74,6 +75,119 @@ void theme_destroy(THEME_REC *rec)
|
|||
g_free(rec);
|
||||
}
|
||||
|
||||
static MODULE_THEME_REC *theme_module_create(THEME_REC *theme, const char *module)
|
||||
{
|
||||
MODULE_THEME_REC *rec;
|
||||
FORMAT_REC *formats;
|
||||
|
||||
rec = g_hash_table_lookup(theme->modules, module);
|
||||
if (rec != NULL) return rec;
|
||||
|
||||
formats = g_hash_table_lookup(default_formats, module);
|
||||
g_return_val_if_fail(formats != NULL, NULL);
|
||||
|
||||
rec = g_new0(MODULE_THEME_REC, 1);
|
||||
rec->name = g_strdup(module);
|
||||
|
||||
for (rec->count = 0; formats[rec->count].def != NULL; rec->count++) ;
|
||||
rec->formats = g_new0(char *, rec->count);
|
||||
|
||||
g_hash_table_insert(theme->modules, rec->name, rec);
|
||||
return rec;
|
||||
}
|
||||
|
||||
static void theme_read_formats(CONFIG_REC *config, THEME_REC *theme, const char *module)
|
||||
{
|
||||
MODULE_THEME_REC *rec;
|
||||
FORMAT_REC *formats;
|
||||
CONFIG_NODE *node;
|
||||
GSList *tmp;
|
||||
int n;
|
||||
|
||||
formats = g_hash_table_lookup(default_formats, module);
|
||||
if (formats == NULL) return;
|
||||
|
||||
node = config_node_traverse(config, "formats", FALSE);
|
||||
if (node == NULL) return;
|
||||
node = config_node_section(node, module, -1);
|
||||
if (node == NULL) return;
|
||||
|
||||
rec = theme_module_create(theme, module);
|
||||
|
||||
for (tmp = node->value; tmp != NULL; tmp = tmp->next) {
|
||||
node = tmp->data;
|
||||
|
||||
if (node->key == NULL || node->value == NULL)
|
||||
continue;
|
||||
|
||||
for (n = 0; formats[n].def != NULL; n++) {
|
||||
if (formats[n].tag != NULL &&
|
||||
g_strcasecmp(formats[n].tag, node->key) == 0) {
|
||||
rec->formats[n] = g_strdup(node->value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void theme_read_module(THEME_REC *theme, const char *module)
|
||||
{
|
||||
CONFIG_REC *config;
|
||||
char *msg;
|
||||
|
||||
config = config_open(theme->path, -1);
|
||||
if (config == NULL) return;
|
||||
|
||||
config_parse(config);
|
||||
|
||||
if (config_last_error(mainconfig) != NULL) {
|
||||
msg = g_strdup_printf(_("Ignored errors in theme:\n%s"),
|
||||
config_last_error(mainconfig));
|
||||
signal_emit("gui dialog", 2, "error", msg);
|
||||
g_free(msg);
|
||||
}
|
||||
|
||||
theme_read_formats(config, theme, module);
|
||||
|
||||
config_close(config);
|
||||
}
|
||||
|
||||
static void theme_remove_module(THEME_REC *theme, const char *module)
|
||||
{
|
||||
MODULE_THEME_REC *rec;
|
||||
|
||||
rec = g_hash_table_lookup(theme->modules, module);
|
||||
if (rec == NULL) return;
|
||||
|
||||
g_hash_table_remove(theme->modules, module);
|
||||
theme_module_destroy(module, rec);
|
||||
}
|
||||
|
||||
void theme_register_module(const char *module, FORMAT_REC *formats)
|
||||
{
|
||||
if (g_hash_table_lookup(default_formats, module) != NULL)
|
||||
return;
|
||||
|
||||
g_hash_table_insert(default_formats, g_strdup(module), formats);
|
||||
|
||||
if (current_theme != NULL)
|
||||
theme_read_module(current_theme, module);
|
||||
}
|
||||
|
||||
void theme_unregister_module(const char *module)
|
||||
{
|
||||
gpointer key, value;
|
||||
|
||||
if (!g_hash_table_lookup_extended(default_formats, module, &key, &value))
|
||||
return;
|
||||
|
||||
g_hash_table_remove(default_formats, key);
|
||||
g_free(key);
|
||||
|
||||
if (current_theme != NULL)
|
||||
theme_remove_module(current_theme, module);
|
||||
}
|
||||
|
||||
static THEME_REC *theme_find(const char *name)
|
||||
{
|
||||
GSList *tmp;
|
||||
|
|
@ -115,49 +229,19 @@ static void find_themes(gchar *path)
|
|||
closedir(dirp);
|
||||
}
|
||||
|
||||
/* Read module texts into theme */
|
||||
static void theme_read_module_texts(const char *hashkey, MODULE_THEME_REC *rec, CONFIG_REC *config)
|
||||
static void theme_read(THEME_REC *theme, const char *path)
|
||||
{
|
||||
CONFIG_NODE *formats;
|
||||
GSList *tmp;
|
||||
char **flist;
|
||||
int n;
|
||||
|
||||
formats = config_node_traverse(config, "moduleformats", FALSE);
|
||||
if (formats == NULL) return;
|
||||
|
||||
for (tmp = formats->value; tmp != NULL; tmp = tmp->next) {
|
||||
CONFIG_NODE *node = tmp->data;
|
||||
|
||||
if (node->key == NULL || node->value == NULL)
|
||||
continue;
|
||||
|
||||
for (n = 0, flist = rec->formatlist; *flist != NULL; flist++, n++) {
|
||||
if (g_strcasecmp(*flist, node->key) == 0) {
|
||||
rec->format[n] = g_strdup(node->value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int theme_read(THEME_REC *theme, const char *path)
|
||||
{
|
||||
MODULE_THEME_REC *mrec;
|
||||
CONFIG_REC *config;
|
||||
CONFIG_NODE *formats;
|
||||
GSList *tmp;
|
||||
char *value;
|
||||
int errors;
|
||||
|
||||
config = config_open(path, -1);
|
||||
if (config == NULL) {
|
||||
/* didn't exist or no access? */
|
||||
theme->default_color = 15;
|
||||
return FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
errors = config_parse(config) == -1;
|
||||
config_parse(config);
|
||||
|
||||
/* default color */
|
||||
theme->default_color = config_get_int(config, NULL, "default_color", 15);
|
||||
|
|
@ -175,58 +259,172 @@ static int theme_read(THEME_REC *theme, const char *path)
|
|||
theme->flags |= THEME_FLAG_BG_SCALED;
|
||||
if (config_get_bool(config, NULL, "bg_shaded", FALSE))
|
||||
theme->flags |= THEME_FLAG_BG_SHADED;
|
||||
|
||||
/* Read modules that are defined in this theme. */
|
||||
formats = config_node_traverse(config, "modules", FALSE);
|
||||
if (formats != NULL) {
|
||||
for (tmp = formats->value; tmp != NULL; tmp = tmp->next) {
|
||||
CONFIG_NODE *node = tmp->data;
|
||||
|
||||
if (node->key == NULL || node->value == NULL)
|
||||
continue;
|
||||
|
||||
mrec = g_new0(MODULE_THEME_REC, 1);
|
||||
mrec->name = g_strdup(node->key);
|
||||
mrec->formatlist = g_strsplit(node->value, " ", -1);
|
||||
mrec->format = g_new0(char*, strarray_length(mrec->formatlist));
|
||||
g_hash_table_insert(theme->modules, mrec->name, mrec);
|
||||
}
|
||||
}
|
||||
|
||||
/* Read the texts inside the plugin */
|
||||
g_hash_table_foreach(theme->modules, (GHFunc) theme_read_module_texts, config);
|
||||
|
||||
if (errors) {
|
||||
/* errors fixed - save the theme */
|
||||
if (config_write(config, NULL, 0660) == -1) {
|
||||
/* we probably tried to save to global directory
|
||||
where we didn't have access.. try saving it to
|
||||
home dir instead. */
|
||||
char *str;
|
||||
|
||||
/* check that we really didn't try to save
|
||||
it to home dir.. */
|
||||
str = g_strdup_printf("%s/.irssi/", g_get_home_dir());
|
||||
if (strncmp(path, str, strlen(str)) != 0) {
|
||||
g_free(str);
|
||||
str = g_strdup_printf("%s/.irssi/%s", g_get_home_dir(), g_basename(path));
|
||||
|
||||
config_write(config, str, 0660);
|
||||
}
|
||||
g_free(str);
|
||||
}
|
||||
}
|
||||
config_close(config);
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
static void sig_formats_error(void)
|
||||
typedef struct {
|
||||
char *name;
|
||||
char *short_name;
|
||||
} THEME_SEARCH_REC;
|
||||
|
||||
static int theme_search_equal(THEME_SEARCH_REC *r1, THEME_SEARCH_REC *r2)
|
||||
{
|
||||
signal_emit("gui dialog", 2, "warning",
|
||||
"Your theme(s) had some old format strings, "
|
||||
"these have been changed back to their default values.");
|
||||
signal_remove("irssi init finished", (SIGNAL_FUNC) sig_formats_error);
|
||||
return g_strcasecmp(r1->short_name, r2->short_name);
|
||||
}
|
||||
|
||||
static void theme_get_modules(char *module, FORMAT_REC *formats, GSList **list)
|
||||
{
|
||||
THEME_SEARCH_REC *rec;
|
||||
|
||||
rec = g_new(THEME_SEARCH_REC, 1);
|
||||
rec->name = module;
|
||||
rec->short_name = strrchr(module, '/');
|
||||
if (rec->short_name != NULL)
|
||||
rec->short_name++; else rec->short_name = module;
|
||||
*list = g_slist_insert_sorted(*list, rec, (GCompareFunc) theme_search_equal);
|
||||
}
|
||||
|
||||
static GSList *get_sorted_modules(void)
|
||||
{
|
||||
GSList *list;
|
||||
|
||||
list = NULL;
|
||||
g_hash_table_foreach(default_formats, (GHFunc) theme_get_modules, &list);
|
||||
return list;
|
||||
}
|
||||
|
||||
static THEME_SEARCH_REC *theme_search(GSList *list, const char *module)
|
||||
{
|
||||
THEME_SEARCH_REC *rec;
|
||||
|
||||
while (list != NULL) {
|
||||
rec = list->data;
|
||||
|
||||
if (g_strcasecmp(rec->short_name, module) == 0)
|
||||
return rec;
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void theme_show(THEME_SEARCH_REC *rec, const char *key, const char *value)
|
||||
{
|
||||
MODULE_THEME_REC *theme;
|
||||
FORMAT_REC *formats;
|
||||
const char *text, *last_title;
|
||||
int n, first;
|
||||
|
||||
formats = g_hash_table_lookup(default_formats, rec->name);
|
||||
theme = g_hash_table_lookup(current_theme->modules, rec->name);
|
||||
|
||||
last_title = NULL; first = TRUE;
|
||||
for (n = 1; formats[n].def != NULL; n++) {
|
||||
text = theme != NULL && theme->formats[n] != NULL ?
|
||||
theme->formats[n] : formats[n].def;
|
||||
|
||||
if (formats[n].tag == NULL)
|
||||
last_title = text;
|
||||
else if ((value != NULL && key != NULL && g_strcasecmp(formats[n].tag, key) == 0) ||
|
||||
(value == NULL && (key == NULL || stristr(formats[n].tag, key) != NULL))) {
|
||||
if (first) {
|
||||
printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "");
|
||||
printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "%K[%W%s%K] - [%W%s%K]", rec->short_name, formats[0].def);
|
||||
printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "");
|
||||
first = FALSE;
|
||||
}
|
||||
if (last_title != NULL)
|
||||
printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "%K[%W%s%K]", last_title);
|
||||
if (value != NULL) {
|
||||
theme = theme_module_create(current_theme, rec->name);
|
||||
theme->formats[n] = g_strdup(value);
|
||||
text = value;
|
||||
}
|
||||
printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "%s %K=%n %s", formats[n].tag, text);
|
||||
last_title = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_format(const char *data)
|
||||
{
|
||||
char *params, *module, *key, *value;
|
||||
GSList *tmp, *modules;
|
||||
|
||||
/* /FORMAT [<module>] [<key> [<value>]] */
|
||||
params = cmd_get_params(data, 3 | PARAM_FLAG_GETREST, &module, &key, &value);
|
||||
|
||||
modules = get_sorted_modules();
|
||||
if (*module != '\0' && theme_search(modules, module) == NULL) {
|
||||
/* first argument isn't module.. */
|
||||
g_free(params);
|
||||
params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &key, &value);
|
||||
module = "";
|
||||
}
|
||||
|
||||
if (*key == '\0') key = NULL;
|
||||
if (*value == '\0') value = NULL;
|
||||
|
||||
for (tmp = modules; tmp != NULL; tmp = tmp->next) {
|
||||
THEME_SEARCH_REC *rec = tmp->data;
|
||||
|
||||
if (*module == '\0' || g_strcasecmp(rec->short_name, module) == 0)
|
||||
theme_show(rec, key, value);
|
||||
}
|
||||
g_slist_foreach(modules, (GFunc) g_free, NULL);
|
||||
g_slist_free(modules);
|
||||
|
||||
g_free(params);
|
||||
}
|
||||
|
||||
static void module_save(const char *module, MODULE_THEME_REC *rec, CONFIG_NODE *fnode)
|
||||
{
|
||||
CONFIG_NODE *node;
|
||||
FORMAT_REC *formats;
|
||||
int n;
|
||||
|
||||
formats = g_hash_table_lookup(default_formats, rec->name);
|
||||
if (formats == NULL) return;
|
||||
|
||||
node = config_node_section(fnode, rec->name, NODE_TYPE_BLOCK);
|
||||
for (n = 0; formats[n].def != NULL; n++) {
|
||||
if (rec->formats[n] != NULL)
|
||||
iconfig_node_set_str(node, formats[n].tag, rec->formats[n]);
|
||||
}
|
||||
}
|
||||
|
||||
/* save changed formats */
|
||||
static void cmd_save(void)
|
||||
{
|
||||
CONFIG_REC *config;
|
||||
CONFIG_NODE *fnode;
|
||||
|
||||
config = config_open(current_theme->path, 0660);
|
||||
if (config == NULL) return;
|
||||
|
||||
config_parse(config);
|
||||
|
||||
fnode = config_node_traverse(config, "formats", TRUE);
|
||||
g_hash_table_foreach(current_theme->modules, (GHFunc) module_save, fnode);
|
||||
|
||||
if (config_write(config, NULL, 0660) == -1) {
|
||||
/* we probably tried to save to global directory
|
||||
where we didn't have access.. try saving it to
|
||||
home dir instead. */
|
||||
char *str;
|
||||
|
||||
/* check that we really didn't try to save
|
||||
it to home dir.. */
|
||||
str = g_strdup_printf("%s/.irssi/", g_get_home_dir());
|
||||
if (strncmp(current_theme->path, str, strlen(str)) != 0) {
|
||||
g_free(str);
|
||||
str = g_strdup_printf("%s/.irssi/%s", g_get_home_dir(), g_basename(current_theme->path));
|
||||
|
||||
config_write(config, str, 0660);
|
||||
}
|
||||
g_free(str);
|
||||
}
|
||||
config_close(config);
|
||||
}
|
||||
|
||||
void themes_init(void)
|
||||
|
|
@ -235,7 +433,8 @@ void themes_init(void)
|
|||
GSList *tmp;
|
||||
const char *value;
|
||||
char *str;
|
||||
int errors;
|
||||
|
||||
default_formats = g_hash_table_new((GHashFunc) g_str_hash, (GCompareFunc) g_str_equal);
|
||||
|
||||
/* first there's default theme.. */
|
||||
str = g_strdup_printf("%s/.irssi/default.theme", g_get_home_dir());
|
||||
|
|
@ -251,22 +450,20 @@ void themes_init(void)
|
|||
find_themes(SYSCONFDIR"/irssi");
|
||||
|
||||
/* read formats for all themes */
|
||||
errors = FALSE;
|
||||
for (tmp = themes; tmp != NULL; tmp = tmp->next) {
|
||||
rec = tmp->data;
|
||||
|
||||
if (theme_read(rec, rec->path))
|
||||
errors = TRUE;
|
||||
theme_read(rec, rec->path);
|
||||
}
|
||||
|
||||
if (errors)
|
||||
signal_add("irssi init finished", (SIGNAL_FUNC) sig_formats_error);
|
||||
|
||||
/* find the current theme to use */
|
||||
value = settings_get_str("current_theme");
|
||||
|
||||
rec = theme_find(value);
|
||||
if (rec != NULL) current_theme = rec;
|
||||
|
||||
command_bind("format", NULL, (SIGNAL_FUNC) cmd_format);
|
||||
command_bind("save", NULL, (SIGNAL_FUNC) cmd_save);
|
||||
}
|
||||
|
||||
void themes_deinit(void)
|
||||
|
|
@ -275,4 +472,9 @@ void themes_deinit(void)
|
|||
g_slist_foreach(themes, (GFunc) theme_destroy, NULL);
|
||||
g_slist_free(themes);
|
||||
themes = NULL;
|
||||
|
||||
g_hash_table_destroy(default_formats);
|
||||
|
||||
command_unbind("format", (SIGNAL_FUNC) cmd_format);
|
||||
command_unbind("save", (SIGNAL_FUNC) cmd_save);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
#ifndef __THEMES_H
|
||||
#define __THEMES_H
|
||||
|
||||
#include "printtext.h"
|
||||
|
||||
#define THEME_FLAG_BG_SCROLLABLE 0x0001
|
||||
#define THEME_FLAG_BG_SCALED 0x0002
|
||||
#define THEME_FLAG_BG_SHADED 0x0004
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
char *name;
|
||||
|
||||
char **formatlist;
|
||||
char **format;
|
||||
}
|
||||
MODULE_THEME_REC;
|
||||
int count;
|
||||
char **formats; /* in same order as in module's default formats */
|
||||
} MODULE_THEME_REC;
|
||||
|
||||
typedef struct {
|
||||
char *path;
|
||||
|
|
@ -30,10 +30,16 @@ typedef struct {
|
|||
|
||||
extern GSList *themes;
|
||||
extern THEME_REC *current_theme;
|
||||
extern GHashTable *default_formats;
|
||||
|
||||
THEME_REC *theme_create(const char *path, const char *name);
|
||||
void theme_destroy(THEME_REC *rec);
|
||||
|
||||
#define theme_register(formats) theme_register_module(MODULE_NAME, formats)
|
||||
#define theme_unregister() theme_unregister_module(MODULE_NAME)
|
||||
void theme_register_module(const char *module, FORMAT_REC *formats);
|
||||
void theme_unregister_module(const char *module);
|
||||
|
||||
void themes_init(void);
|
||||
void themes_deinit(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -26,13 +26,11 @@
|
|||
#include "windows.h"
|
||||
#include "window-items.h"
|
||||
|
||||
static void sig_hilight_text(SERVER_REC *server, const char *channel, gpointer levelptr, const char *msg)
|
||||
static void sig_hilight_text(WINDOW_REC *window, SERVER_REC *server, const char *channel, gpointer levelptr, const char *msg)
|
||||
{
|
||||
WINDOW_REC *window;
|
||||
int level, oldlevel;
|
||||
|
||||
level = GPOINTER_TO_INT(levelptr);
|
||||
window = window_find_closest(server, channel, level);
|
||||
if (window == active_win || (level & (MSGLEVEL_NEVER|MSGLEVEL_NO_ACT|MSGLEVEL_MSGS)))
|
||||
return;
|
||||
|
||||
|
|
|
|||
370
src/fe-common/core/window-commands.c
Normal file
370
src/fe-common/core/window-commands.c
Normal file
|
|
@ -0,0 +1,370 @@
|
|||
/*
|
||||
window-commands.c : irssi
|
||||
|
||||
Copyright (C) 2000 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 "module-formats.h"
|
||||
#include "signals.h"
|
||||
#include "commands.h"
|
||||
#include "misc.h"
|
||||
#include "server.h"
|
||||
|
||||
#include "levels.h"
|
||||
|
||||
#include "windows.h"
|
||||
#include "window-items.h"
|
||||
|
||||
static void cmd_window(const char *data, void *server, WI_ITEM_REC *item)
|
||||
{
|
||||
command_runsub("window", data, server, item);
|
||||
}
|
||||
|
||||
static void cmd_window_new(const char *data, void *server, WI_ITEM_REC *item)
|
||||
{
|
||||
WINDOW_REC *window;
|
||||
int type;
|
||||
|
||||
g_return_if_fail(data != NULL);
|
||||
|
||||
type = (g_strncasecmp(data, "hid", 3) == 0 || g_strcasecmp(data, "tab") == 0) ? 1 :
|
||||
(g_strcasecmp(data, "split") == 0 ? 2 : 0);
|
||||
signal_emit("gui window create override", 1, GINT_TO_POINTER(type));
|
||||
|
||||
window = window_create(NULL, FALSE);
|
||||
window_change_server(window, server);
|
||||
}
|
||||
|
||||
static void cmd_window_close(const char *data)
|
||||
{
|
||||
/* destroy window unless it's the last one */
|
||||
if (windows->next != NULL)
|
||||
window_destroy(active_win);
|
||||
}
|
||||
|
||||
static void cmd_window_refnum(const char *data)
|
||||
{
|
||||
WINDOW_REC *window;
|
||||
|
||||
if (!is_numeric(data, 0))
|
||||
return;
|
||||
|
||||
window = window_find_refnum(atoi(data));
|
||||
if (window != NULL)
|
||||
window_set_active(window);
|
||||
}
|
||||
|
||||
/* return the first window number with the highest activity */
|
||||
static WINDOW_REC *window_highest_activity(WINDOW_REC *window)
|
||||
{
|
||||
WINDOW_REC *rec, *max_win;
|
||||
GSList *tmp;
|
||||
int max_act, through;
|
||||
|
||||
g_return_val_if_fail(window != NULL, NULL);
|
||||
|
||||
max_win = NULL; max_act = 0; through = FALSE;
|
||||
|
||||
tmp = g_slist_find(windows, window);
|
||||
for (;; tmp = tmp->next) {
|
||||
if (tmp == NULL) {
|
||||
tmp = windows;
|
||||
through = TRUE;
|
||||
}
|
||||
|
||||
if (through && tmp->data == window)
|
||||
break;
|
||||
|
||||
rec = tmp->data;
|
||||
|
||||
if (rec->new_data && max_act < rec->new_data) {
|
||||
max_act = rec->new_data;
|
||||
max_win = rec;
|
||||
}
|
||||
}
|
||||
|
||||
return max_win;
|
||||
}
|
||||
|
||||
static void cmd_window_goto(const char *data)
|
||||
{
|
||||
WINDOW_REC *window;
|
||||
|
||||
g_return_if_fail(data != NULL);
|
||||
|
||||
if (is_numeric(data, 0)) {
|
||||
cmd_window_refnum(data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_strcasecmp(data, "active") == 0)
|
||||
window = window_highest_activity(active_win);
|
||||
else
|
||||
window = window_find_item(active_win, data);
|
||||
|
||||
if (window != NULL)
|
||||
window_set_active(window);
|
||||
}
|
||||
|
||||
static void cmd_window_next(void)
|
||||
{
|
||||
int num;
|
||||
|
||||
num = window_refnum_next(active_win->refnum);
|
||||
if (num < 1) num = windows_refnum_last();
|
||||
|
||||
window_set_active(window_find_refnum(num));
|
||||
}
|
||||
|
||||
static void cmd_window_prev(void)
|
||||
{
|
||||
int num;
|
||||
|
||||
num = window_refnum_prev(active_win->refnum);
|
||||
if (num < 1) num = window_refnum_next(0);
|
||||
|
||||
window_set_active(window_find_refnum(num));
|
||||
}
|
||||
|
||||
static void cmd_window_level(const char *data)
|
||||
{
|
||||
g_return_if_fail(data != NULL);
|
||||
|
||||
window_set_level(active_win, combine_level(active_win->level, data));
|
||||
printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE, "Window level is now %s",
|
||||
bits2level(active_win->level));
|
||||
}
|
||||
|
||||
static void cmd_window_server(const char *data)
|
||||
{
|
||||
SERVER_REC *server;
|
||||
|
||||
g_return_if_fail(data != NULL);
|
||||
|
||||
server = server_find_tag(data);
|
||||
if (server == NULL)
|
||||
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_UNKNOWN_SERVER_TAG, data);
|
||||
else if (active_win->active == NULL) {
|
||||
window_change_server(active_win, server);
|
||||
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_SERVER_CHANGED, server->tag, server->connrec->address,
|
||||
server->connrec->ircnet == NULL ? "" : server->connrec->ircnet);
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_window_item_prev(void)
|
||||
{
|
||||
window_item_prev(active_win);
|
||||
}
|
||||
|
||||
static void cmd_window_item_next(void)
|
||||
{
|
||||
window_item_next(active_win);
|
||||
}
|
||||
|
||||
static void cmd_window_number(const char *data)
|
||||
{
|
||||
int num;
|
||||
|
||||
num = atoi(data);
|
||||
if (num < 1)
|
||||
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_REFNUM_TOO_LOW);
|
||||
else
|
||||
window_set_refnum(active_win, num);
|
||||
}
|
||||
|
||||
static void cmd_window_name(const char *data)
|
||||
{
|
||||
window_set_name(active_win, data);
|
||||
}
|
||||
|
||||
/* we're moving the first window to last - move the first contiguous block
|
||||
of refnums to left. Like if there's windows 1..5 and 7..10, move 1 to
|
||||
11, 2..5 to 1..4 and leave 7..10 alone */
|
||||
static void windows_move_left(WINDOW_REC *move_window)
|
||||
{
|
||||
WINDOW_REC *window;
|
||||
int refnum;
|
||||
|
||||
window_set_refnum(move_window, windows_refnum_last()+1);
|
||||
for (refnum = 2;; refnum++) {
|
||||
window = window_find_refnum(refnum);
|
||||
if (window == NULL) break;
|
||||
|
||||
window_set_refnum(window, refnum-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* we're moving the last window to first - make some space so we can use the
|
||||
refnum 1 */
|
||||
static void windows_move_right(WINDOW_REC *move_window)
|
||||
{
|
||||
WINDOW_REC *window;
|
||||
int refnum;
|
||||
|
||||
/* find the first unused refnum, like if there's windows
|
||||
1..5 and 7..10, we only need to move 1..5 to 2..6 */
|
||||
refnum = 1;
|
||||
while (window_find_refnum(refnum) != NULL) refnum++;
|
||||
|
||||
refnum--;
|
||||
while (refnum > 0) {
|
||||
window = window_find_refnum(refnum);
|
||||
g_return_if_fail(window != NULL);
|
||||
window_set_refnum(window, window == move_window ? 1 : refnum+1);
|
||||
|
||||
refnum--;
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_window_move_left(void)
|
||||
{
|
||||
int refnum;
|
||||
|
||||
refnum = window_refnum_prev(active_win->refnum);
|
||||
if (refnum != -1) {
|
||||
window_set_refnum(active_win, active_win->refnum-1);
|
||||
return;
|
||||
}
|
||||
|
||||
windows_move_left(active_win);
|
||||
}
|
||||
|
||||
static void cmd_window_move_right(void)
|
||||
{
|
||||
int refnum;
|
||||
|
||||
refnum = window_refnum_next(active_win->refnum);
|
||||
if (refnum != -1) {
|
||||
window_set_refnum(active_win, active_win->refnum+1);
|
||||
return;
|
||||
}
|
||||
|
||||
windows_move_right(active_win);
|
||||
}
|
||||
|
||||
static void cmd_window_move(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
|
||||
{
|
||||
int new_refnum, refnum;
|
||||
|
||||
if (!is_numeric(data, 0)) {
|
||||
command_runsub("window move", data, server, item);
|
||||
return;
|
||||
}
|
||||
|
||||
new_refnum = atoi(data);
|
||||
if (new_refnum > active_win->refnum) {
|
||||
for (;;) {
|
||||
refnum = window_refnum_next(active_win->refnum);
|
||||
if (refnum == -1 || refnum > new_refnum)
|
||||
break;
|
||||
|
||||
window_set_refnum(active_win, refnum);
|
||||
}
|
||||
} else {
|
||||
for (;;) {
|
||||
refnum = window_refnum_prev(active_win->refnum);
|
||||
if (refnum == -1 || refnum < new_refnum)
|
||||
break;
|
||||
|
||||
window_set_refnum(active_win, refnum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int windows_compare(WINDOW_REC *w1, WINDOW_REC *w2)
|
||||
{
|
||||
return w1->refnum < w2->refnum ? -1 : 1;
|
||||
}
|
||||
|
||||
static GSList *windows_get_sorted(void)
|
||||
{
|
||||
GSList *tmp, *list;
|
||||
|
||||
list = NULL;
|
||||
for (tmp = windows; tmp != NULL; tmp = tmp->next) {
|
||||
list = g_slist_insert_sorted(list, tmp->data, (GCompareFunc) windows_compare);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static void cmd_window_list(void)
|
||||
{
|
||||
GSList *tmp, *sorted;
|
||||
char *levelstr;
|
||||
|
||||
sorted = windows_get_sorted();
|
||||
printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_WINDOWLIST_HEADER);
|
||||
for (tmp = sorted; tmp != NULL; tmp = tmp->next) {
|
||||
WINDOW_REC *rec = tmp->data;
|
||||
|
||||
levelstr = bits2level(rec->level);
|
||||
printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_WINDOWLIST_LINE,
|
||||
rec->refnum, rec->name == NULL ? "" : rec->name,
|
||||
rec->active == NULL ? "" : rec->active->name,
|
||||
rec->active_server == NULL ? "" : ((SERVER_REC *) rec->active_server)->tag,
|
||||
levelstr);
|
||||
g_free(levelstr);
|
||||
}
|
||||
g_slist_free(sorted);
|
||||
printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_WINDOWLIST_FOOTER);
|
||||
}
|
||||
|
||||
void window_commands_init(void)
|
||||
{
|
||||
command_bind("window", NULL, (SIGNAL_FUNC) cmd_window);
|
||||
command_bind("window new", NULL, (SIGNAL_FUNC) cmd_window_new);
|
||||
command_bind("window close", NULL, (SIGNAL_FUNC) cmd_window_close);
|
||||
command_bind("window kill", NULL, (SIGNAL_FUNC) cmd_window_close);
|
||||
command_bind("window server", NULL, (SIGNAL_FUNC) cmd_window_server);
|
||||
command_bind("window refnum", NULL, (SIGNAL_FUNC) cmd_window_refnum);
|
||||
command_bind("window goto", NULL, (SIGNAL_FUNC) cmd_window_goto);
|
||||
command_bind("window prev", NULL, (SIGNAL_FUNC) cmd_window_prev);
|
||||
command_bind("window next", NULL, (SIGNAL_FUNC) cmd_window_next);
|
||||
command_bind("window level", NULL, (SIGNAL_FUNC) cmd_window_level);
|
||||
command_bind("window item prev", NULL, (SIGNAL_FUNC) cmd_window_item_prev);
|
||||
command_bind("window item next", NULL, (SIGNAL_FUNC) cmd_window_item_next);
|
||||
command_bind("window number", NULL, (SIGNAL_FUNC) cmd_window_number);
|
||||
command_bind("window name", NULL, (SIGNAL_FUNC) cmd_window_name);
|
||||
command_bind("window move", NULL, (SIGNAL_FUNC) cmd_window_move);
|
||||
command_bind("window move left", NULL, (SIGNAL_FUNC) cmd_window_move_left);
|
||||
command_bind("window move right", NULL, (SIGNAL_FUNC) cmd_window_move_right);
|
||||
command_bind("window list", NULL, (SIGNAL_FUNC) cmd_window_list);
|
||||
}
|
||||
|
||||
void window_commands_deinit(void)
|
||||
{
|
||||
command_unbind("window", (SIGNAL_FUNC) cmd_window);
|
||||
command_unbind("window new", (SIGNAL_FUNC) cmd_window_new);
|
||||
command_unbind("window close", (SIGNAL_FUNC) cmd_window_close);
|
||||
command_unbind("window kill", (SIGNAL_FUNC) cmd_window_close);
|
||||
command_unbind("window server", (SIGNAL_FUNC) cmd_window_server);
|
||||
command_unbind("window refnum", (SIGNAL_FUNC) cmd_window_refnum);
|
||||
command_unbind("window goto", (SIGNAL_FUNC) cmd_window_goto);
|
||||
command_unbind("window prev", (SIGNAL_FUNC) cmd_window_prev);
|
||||
command_unbind("window next", (SIGNAL_FUNC) cmd_window_next);
|
||||
command_unbind("window level", (SIGNAL_FUNC) cmd_window_level);
|
||||
command_unbind("window item prev", (SIGNAL_FUNC) cmd_window_item_prev);
|
||||
command_unbind("window item next", (SIGNAL_FUNC) cmd_window_item_next);
|
||||
command_unbind("window number", (SIGNAL_FUNC) cmd_window_number);
|
||||
command_unbind("window name", (SIGNAL_FUNC) cmd_window_name);
|
||||
command_unbind("window move", (SIGNAL_FUNC) cmd_window_move);
|
||||
command_unbind("window move left", (SIGNAL_FUNC) cmd_window_move_left);
|
||||
command_unbind("window move right", (SIGNAL_FUNC) cmd_window_move_right);
|
||||
command_unbind("window list", (SIGNAL_FUNC) cmd_window_list);
|
||||
}
|
||||
|
|
@ -27,7 +27,6 @@
|
|||
|
||||
#include "levels.h"
|
||||
|
||||
#include "printtext.h"
|
||||
#include "windows.h"
|
||||
#include "window-items.h"
|
||||
|
||||
|
|
@ -86,17 +85,6 @@ WINDOW_REC *window_item_window(WI_ITEM_REC *item)
|
|||
return MODULE_DATA(item);
|
||||
}
|
||||
|
||||
void window_item_set_active(WINDOW_REC *window, WI_ITEM_REC *item)
|
||||
{
|
||||
g_return_if_fail(window != NULL);
|
||||
|
||||
if (window->active != item) {
|
||||
window->active = item;
|
||||
if (item != NULL) window_change_server(window, window->active_server);
|
||||
signal_emit("window item changed", 2, window, item);
|
||||
}
|
||||
}
|
||||
|
||||
void window_item_change_server(WI_ITEM_REC *item, void *server)
|
||||
{
|
||||
WINDOW_REC *window;
|
||||
|
|
@ -110,6 +98,71 @@ void window_item_change_server(WI_ITEM_REC *item, void *server)
|
|||
if (window->active == item) window_change_server(window, item->server);
|
||||
}
|
||||
|
||||
void window_item_set_active(WINDOW_REC *window, WI_ITEM_REC *item)
|
||||
{
|
||||
g_return_if_fail(window != NULL);
|
||||
|
||||
if (window->active != item) {
|
||||
window->active = item;
|
||||
if (item != NULL) window_change_server(window, window->active_server);
|
||||
signal_emit("window item changed", 2, window, item);
|
||||
}
|
||||
}
|
||||
|
||||
void window_item_prev(WINDOW_REC *window)
|
||||
{
|
||||
WI_ITEM_REC *last;
|
||||
GSList *tmp;
|
||||
|
||||
g_return_if_fail(window != NULL);
|
||||
|
||||
last = NULL;
|
||||
for (tmp = window->items; tmp != NULL; tmp = tmp->next) {
|
||||
WI_ITEM_REC *rec = tmp->data;
|
||||
|
||||
if (rec != window->active)
|
||||
last = rec;
|
||||
else {
|
||||
/* current channel. did we find anything?
|
||||
if not, go to the last channel */
|
||||
if (last != NULL) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (last != NULL)
|
||||
window_item_set_active(window, last);
|
||||
}
|
||||
|
||||
void window_item_next(WINDOW_REC *window)
|
||||
{
|
||||
WI_ITEM_REC *next;
|
||||
GSList *tmp;
|
||||
int gone;
|
||||
|
||||
g_return_if_fail(window != NULL);
|
||||
|
||||
next = NULL; gone = FALSE;
|
||||
for (tmp = window->items; tmp != NULL; tmp = tmp->next) {
|
||||
WI_ITEM_REC *rec = tmp->data;
|
||||
|
||||
if (rec == window->active)
|
||||
gone = TRUE;
|
||||
else {
|
||||
if (gone) {
|
||||
/* found the next channel */
|
||||
next = rec;
|
||||
break;
|
||||
}
|
||||
|
||||
if (next == NULL)
|
||||
next = rec; /* fallback to first channel */
|
||||
}
|
||||
}
|
||||
|
||||
if (next != NULL)
|
||||
window_item_set_active(window, next);
|
||||
}
|
||||
|
||||
static WI_ITEM_REC *window_item_find_window(WINDOW_REC *window, void *server, const char *name)
|
||||
{
|
||||
GSList *tmp;
|
||||
|
|
|
|||
|
|
@ -10,9 +10,12 @@ void window_remove_item(WINDOW_REC *window, WI_ITEM_REC *item);
|
|||
void window_item_create(WI_ITEM_REC *item, int automatic);
|
||||
|
||||
WINDOW_REC *window_item_window(WI_ITEM_REC *item);
|
||||
void window_item_set_active(WINDOW_REC *window, WI_ITEM_REC *item);
|
||||
void window_item_change_server(WI_ITEM_REC *item, void *server);
|
||||
|
||||
void window_item_set_active(WINDOW_REC *window, WI_ITEM_REC *item);
|
||||
void window_item_prev(WINDOW_REC *window);
|
||||
void window_item_next(WINDOW_REC *window);
|
||||
|
||||
/* Find wanted window item by name. `server' can be NULL. */
|
||||
WI_ITEM_REC *window_item_find(void *server, const char *name);
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ GSList *windows; /* first in the list is the active window,
|
|||
next is the last active, etc. */
|
||||
WINDOW_REC *active_win;
|
||||
|
||||
static int daytag;
|
||||
|
||||
static int window_get_new_refnum(void)
|
||||
{
|
||||
WINDOW_REC *win;
|
||||
|
|
@ -247,117 +249,6 @@ WINDOW_REC *window_find_refnum(int refnum)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int windows_refnum_last(void)
|
||||
{
|
||||
GSList *tmp;
|
||||
int max;
|
||||
|
||||
max = -1;
|
||||
for (tmp = windows; tmp != NULL; tmp = tmp->next) {
|
||||
WINDOW_REC *rec = tmp->data;
|
||||
|
||||
if (rec->refnum > max)
|
||||
max = rec->refnum;
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
static int window_refnum_prev(int refnum)
|
||||
{
|
||||
GSList *tmp;
|
||||
int prev, max;
|
||||
|
||||
max = prev = -1;
|
||||
for (tmp = windows; tmp != NULL; tmp = tmp->next) {
|
||||
WINDOW_REC *rec = tmp->data;
|
||||
|
||||
if (rec->refnum < refnum && (prev == -1 || rec->refnum > prev))
|
||||
prev = rec->refnum;
|
||||
if (max == -1 || rec->refnum > max)
|
||||
max = rec->refnum;
|
||||
}
|
||||
|
||||
return prev != -1 ? prev : max;
|
||||
}
|
||||
|
||||
static int window_refnum_next(int refnum)
|
||||
{
|
||||
GSList *tmp;
|
||||
int min, next;
|
||||
|
||||
min = next = -1;
|
||||
for (tmp = windows; tmp != NULL; tmp = tmp->next) {
|
||||
WINDOW_REC *rec = tmp->data;
|
||||
|
||||
if (rec->refnum > refnum && (next == -1 || rec->refnum < next))
|
||||
next = rec->refnum;
|
||||
if (min == -1 || rec->refnum < min)
|
||||
min = rec->refnum;
|
||||
}
|
||||
|
||||
return next != -1 ? next : min;
|
||||
}
|
||||
|
||||
static void cmd_window(const char *data, void *server, WI_ITEM_REC *item)
|
||||
{
|
||||
command_runsub("window", data, server, item);
|
||||
}
|
||||
|
||||
static void cmd_window_new(const char *data, void *server, WI_ITEM_REC *item)
|
||||
{
|
||||
WINDOW_REC *window;
|
||||
int type;
|
||||
|
||||
g_return_if_fail(data != NULL);
|
||||
|
||||
type = (g_strncasecmp(data, "hid", 3) == 0 || g_strcasecmp(data, "tab") == 0) ? 1 :
|
||||
(g_strcasecmp(data, "split") == 0 ? 2 : 0);
|
||||
signal_emit("gui window create override", 1, GINT_TO_POINTER(type));
|
||||
|
||||
window = window_create(NULL, FALSE);
|
||||
window_change_server(window, server);
|
||||
}
|
||||
|
||||
static void cmd_window_close(const char *data)
|
||||
{
|
||||
/* destroy window unless it's the last one */
|
||||
if (windows->next != NULL)
|
||||
window_destroy(active_win);
|
||||
}
|
||||
|
||||
/* return the first window number with the highest activity */
|
||||
static WINDOW_REC *window_highest_activity(WINDOW_REC *window)
|
||||
{
|
||||
WINDOW_REC *rec, *max_win;
|
||||
GSList *tmp;
|
||||
int max_act, through;
|
||||
|
||||
g_return_val_if_fail(window != NULL, NULL);
|
||||
|
||||
max_win = NULL; max_act = 0; through = FALSE;
|
||||
|
||||
tmp = g_slist_find(windows, window);
|
||||
for (;; tmp = tmp->next) {
|
||||
if (tmp == NULL) {
|
||||
tmp = windows;
|
||||
through = TRUE;
|
||||
}
|
||||
|
||||
if (through && tmp->data == window)
|
||||
break;
|
||||
|
||||
rec = tmp->data;
|
||||
|
||||
if (rec->new_data && max_act < rec->new_data) {
|
||||
max_act = rec->new_data;
|
||||
max_win = rec;
|
||||
}
|
||||
}
|
||||
|
||||
return max_win;
|
||||
}
|
||||
|
||||
WINDOW_REC *window_find_name(const char *name)
|
||||
{
|
||||
GSList *tmp;
|
||||
|
|
@ -409,288 +300,56 @@ WINDOW_REC *window_find_item(WINDOW_REC *window, const char *name)
|
|||
return MODULE_DATA(item);
|
||||
}
|
||||
|
||||
static void cmd_window_refnum(const char *data)
|
||||
int window_refnum_prev(int refnum)
|
||||
{
|
||||
WINDOW_REC *window;
|
||||
|
||||
if (!is_numeric(data, 0))
|
||||
return;
|
||||
|
||||
window = window_find_refnum(atoi(data));
|
||||
if (window != NULL)
|
||||
window_set_active(window);
|
||||
}
|
||||
|
||||
static void cmd_window_goto(const char *data)
|
||||
{
|
||||
WINDOW_REC *window;
|
||||
|
||||
g_return_if_fail(data != NULL);
|
||||
|
||||
if (is_numeric(data, 0)) {
|
||||
cmd_window_refnum(data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_strcasecmp(data, "active") == 0)
|
||||
window = window_highest_activity(active_win);
|
||||
else
|
||||
window = window_find_item(active_win, data);
|
||||
|
||||
if (window != NULL)
|
||||
window_set_active(window);
|
||||
}
|
||||
|
||||
static void cmd_window_next(void)
|
||||
{
|
||||
int num;
|
||||
|
||||
num = window_refnum_next(active_win->refnum);
|
||||
if (num < 1) num = windows_refnum_last();
|
||||
|
||||
window_set_active(window_find_refnum(num));
|
||||
}
|
||||
|
||||
static void cmd_window_prev(void)
|
||||
{
|
||||
int num;
|
||||
|
||||
num = window_refnum_prev(active_win->refnum);
|
||||
if (num < 1) num = window_refnum_next(0);
|
||||
|
||||
window_set_active(window_find_refnum(num));
|
||||
}
|
||||
|
||||
static void cmd_window_level(const char *data)
|
||||
{
|
||||
g_return_if_fail(data != NULL);
|
||||
|
||||
window_set_level(active_win, combine_level(active_win->level, data));
|
||||
printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE, "Window level is now %s",
|
||||
bits2level(active_win->level));
|
||||
}
|
||||
|
||||
static void cmd_window_server(const char *data)
|
||||
{
|
||||
SERVER_REC *server;
|
||||
|
||||
g_return_if_fail(data != NULL);
|
||||
|
||||
server = server_find_tag(data);
|
||||
if (server == NULL)
|
||||
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_UNKNOWN_SERVER_TAG, data);
|
||||
else if (active_win->active == NULL) {
|
||||
window_change_server(active_win, server);
|
||||
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_SERVER_CHANGED, server->tag, server->connrec->address,
|
||||
server->connrec->ircnet == NULL ? "" : server->connrec->ircnet);
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_window_item_prev(const char *data, void *server, WI_ITEM_REC *item)
|
||||
{
|
||||
WINDOW_REC *window;
|
||||
WI_ITEM_REC *last;
|
||||
GSList *tmp;
|
||||
int prev, max;
|
||||
|
||||
window = item == NULL ? NULL : MODULE_DATA(item);
|
||||
if (window == NULL) return;
|
||||
|
||||
last = NULL;
|
||||
for (tmp = window->items; tmp != NULL; tmp = tmp->next) {
|
||||
WI_ITEM_REC *rec = tmp->data;
|
||||
|
||||
if (rec != item)
|
||||
last = rec;
|
||||
else {
|
||||
/* current channel. did we find anything?
|
||||
if not, go to the last channel */
|
||||
if (last != NULL) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (last != NULL)
|
||||
window_item_set_active(window, last);
|
||||
}
|
||||
|
||||
static void cmd_window_item_next(const char *data, void *server, WI_ITEM_REC *item)
|
||||
{
|
||||
WINDOW_REC *window;
|
||||
WI_ITEM_REC *next;
|
||||
GSList *tmp;
|
||||
int gone;
|
||||
|
||||
window = item == NULL ? NULL : MODULE_DATA(item);
|
||||
if (window == NULL) return;
|
||||
|
||||
next = NULL; gone = FALSE;
|
||||
for (tmp = window->items; tmp != NULL; tmp = tmp->next) {
|
||||
WI_ITEM_REC *rec = tmp->data;
|
||||
|
||||
if (rec == item)
|
||||
gone = TRUE;
|
||||
else {
|
||||
if (gone) {
|
||||
/* found the next channel */
|
||||
next = rec;
|
||||
break;
|
||||
}
|
||||
|
||||
if (next == NULL)
|
||||
next = rec; /* fallback to first channel */
|
||||
}
|
||||
}
|
||||
|
||||
if (next != NULL)
|
||||
window_item_set_active(window, next);
|
||||
}
|
||||
|
||||
static void cmd_window_number(const char *data)
|
||||
{
|
||||
int num;
|
||||
|
||||
num = atoi(data);
|
||||
if (num < 1)
|
||||
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_REFNUM_TOO_LOW);
|
||||
else
|
||||
window_set_refnum(active_win, num);
|
||||
}
|
||||
|
||||
static void cmd_window_name(const char *data)
|
||||
{
|
||||
window_set_name(active_win, data);
|
||||
}
|
||||
|
||||
/* we're moving the first window to last - move the first contiguous block
|
||||
of refnums to left. Like if there's windows 1..5 and 7..10, move 1 to
|
||||
11, 2..5 to 1..4 and leave 7..10 alone */
|
||||
static void windows_move_left(WINDOW_REC *move_window)
|
||||
{
|
||||
WINDOW_REC *window;
|
||||
int refnum;
|
||||
|
||||
window_set_refnum(move_window, windows_refnum_last()+1);
|
||||
for (refnum = 2;; refnum++) {
|
||||
window = window_find_refnum(refnum);
|
||||
if (window == NULL) break;
|
||||
|
||||
window_set_refnum(window, refnum-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* we're moving the last window to first - make some space so we can use the
|
||||
refnum 1 */
|
||||
static void windows_move_right(WINDOW_REC *move_window)
|
||||
{
|
||||
WINDOW_REC *window;
|
||||
int refnum;
|
||||
|
||||
/* find the first unused refnum, like if there's windows
|
||||
1..5 and 7..10, we only need to move 1..5 to 2..6 */
|
||||
refnum = 1;
|
||||
while (window_find_refnum(refnum) != NULL) refnum++;
|
||||
|
||||
refnum--;
|
||||
while (refnum > 0) {
|
||||
window = window_find_refnum(refnum);
|
||||
g_return_if_fail(window != NULL);
|
||||
window_set_refnum(window, window == move_window ? 1 : refnum+1);
|
||||
|
||||
refnum--;
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_window_move_left(void)
|
||||
{
|
||||
int refnum;
|
||||
|
||||
refnum = window_refnum_prev(active_win->refnum);
|
||||
if (refnum != -1) {
|
||||
window_set_refnum(active_win, active_win->refnum-1);
|
||||
return;
|
||||
}
|
||||
|
||||
windows_move_left(active_win);
|
||||
}
|
||||
|
||||
static void cmd_window_move_right(void)
|
||||
{
|
||||
int refnum;
|
||||
|
||||
refnum = window_refnum_next(active_win->refnum);
|
||||
if (refnum != -1) {
|
||||
window_set_refnum(active_win, active_win->refnum+1);
|
||||
return;
|
||||
}
|
||||
|
||||
windows_move_right(active_win);
|
||||
}
|
||||
|
||||
static void cmd_window_move(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
|
||||
{
|
||||
int new_refnum, refnum;
|
||||
|
||||
if (!is_numeric(data, 0)) {
|
||||
command_runsub("window move", data, server, item);
|
||||
return;
|
||||
}
|
||||
|
||||
new_refnum = atoi(data);
|
||||
if (new_refnum > active_win->refnum) {
|
||||
for (;;) {
|
||||
refnum = window_refnum_next(active_win->refnum);
|
||||
if (refnum == -1 || refnum > new_refnum)
|
||||
break;
|
||||
|
||||
window_set_refnum(active_win, refnum);
|
||||
}
|
||||
} else {
|
||||
for (;;) {
|
||||
refnum = window_refnum_prev(active_win->refnum);
|
||||
if (refnum == -1 || refnum < new_refnum)
|
||||
break;
|
||||
|
||||
window_set_refnum(active_win, refnum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int windows_compare(WINDOW_REC *w1, WINDOW_REC *w2)
|
||||
{
|
||||
return w1->refnum < w2->refnum ? -1 : 1;
|
||||
}
|
||||
|
||||
GSList *windows_get_sorted(void)
|
||||
{
|
||||
GSList *tmp, *list;
|
||||
|
||||
list = NULL;
|
||||
max = prev = -1;
|
||||
for (tmp = windows; tmp != NULL; tmp = tmp->next) {
|
||||
list = g_slist_insert_sorted(list, tmp->data, (GCompareFunc) windows_compare);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static void cmd_window_list(void)
|
||||
{
|
||||
GSList *tmp, *sorted;
|
||||
char *levelstr;
|
||||
|
||||
sorted = windows_get_sorted();
|
||||
printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_WINDOWLIST_HEADER);
|
||||
for (tmp = sorted; tmp != NULL; tmp = tmp->next) {
|
||||
WINDOW_REC *rec = tmp->data;
|
||||
|
||||
levelstr = bits2level(rec->level);
|
||||
printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_WINDOWLIST_LINE,
|
||||
rec->refnum, rec->name == NULL ? "" : rec->name,
|
||||
rec->active == NULL ? "" : rec->active->name,
|
||||
rec->active_server == NULL ? "" : ((SERVER_REC *) rec->active_server)->tag,
|
||||
levelstr);
|
||||
g_free(levelstr);
|
||||
if (rec->refnum < refnum && (prev == -1 || rec->refnum > prev))
|
||||
prev = rec->refnum;
|
||||
if (max == -1 || rec->refnum > max)
|
||||
max = rec->refnum;
|
||||
}
|
||||
g_slist_free(sorted);
|
||||
printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_WINDOWLIST_FOOTER);
|
||||
|
||||
return prev != -1 ? prev : max;
|
||||
}
|
||||
|
||||
int window_refnum_next(int refnum)
|
||||
{
|
||||
GSList *tmp;
|
||||
int min, next;
|
||||
|
||||
min = next = -1;
|
||||
for (tmp = windows; tmp != NULL; tmp = tmp->next) {
|
||||
WINDOW_REC *rec = tmp->data;
|
||||
|
||||
if (rec->refnum > refnum && (next == -1 || rec->refnum < next))
|
||||
next = rec->refnum;
|
||||
if (min == -1 || rec->refnum < min)
|
||||
min = rec->refnum;
|
||||
}
|
||||
|
||||
return next != -1 ? next : min;
|
||||
}
|
||||
|
||||
int windows_refnum_last(void)
|
||||
{
|
||||
GSList *tmp;
|
||||
int max;
|
||||
|
||||
max = -1;
|
||||
for (tmp = windows; tmp != NULL; tmp = tmp->next) {
|
||||
WINDOW_REC *rec = tmp->data;
|
||||
|
||||
if (rec->refnum > max)
|
||||
max = rec->refnum;
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
static void sig_server_looking(void *server)
|
||||
|
|
@ -722,29 +381,46 @@ static void sig_server_disconnected(void *server)
|
|||
}
|
||||
}
|
||||
|
||||
static int sig_check_daychange(void)
|
||||
{
|
||||
static int lastday = -1;
|
||||
GSList *tmp;
|
||||
time_t t;
|
||||
struct tm *tm;
|
||||
|
||||
if (!settings_get_bool("timestamps")) {
|
||||
/* display day change notice only when using timestamps */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
t = time(NULL);
|
||||
tm = localtime(&t);
|
||||
|
||||
if (lastday == -1) {
|
||||
/* First check, don't display. */
|
||||
lastday = tm->tm_mday;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (tm->tm_mday == lastday)
|
||||
return TRUE;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
lastday = tm->tm_mday;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void windows_init(void)
|
||||
{
|
||||
active_win = NULL;
|
||||
settings_add_bool("lookandfeel", "window_auto_change", FALSE);
|
||||
|
||||
command_bind("window", NULL, (SIGNAL_FUNC) cmd_window);
|
||||
command_bind("window new", NULL, (SIGNAL_FUNC) cmd_window_new);
|
||||
command_bind("window close", NULL, (SIGNAL_FUNC) cmd_window_close);
|
||||
command_bind("window kill", NULL, (SIGNAL_FUNC) cmd_window_close);
|
||||
command_bind("window server", NULL, (SIGNAL_FUNC) cmd_window_server);
|
||||
command_bind("window refnum", NULL, (SIGNAL_FUNC) cmd_window_refnum);
|
||||
command_bind("window goto", NULL, (SIGNAL_FUNC) cmd_window_goto);
|
||||
command_bind("window prev", NULL, (SIGNAL_FUNC) cmd_window_prev);
|
||||
command_bind("window next", NULL, (SIGNAL_FUNC) cmd_window_next);
|
||||
command_bind("window level", NULL, (SIGNAL_FUNC) cmd_window_level);
|
||||
command_bind("window item prev", NULL, (SIGNAL_FUNC) cmd_window_item_prev);
|
||||
command_bind("window item next", NULL, (SIGNAL_FUNC) cmd_window_item_next);
|
||||
command_bind("window number", NULL, (SIGNAL_FUNC) cmd_window_number);
|
||||
command_bind("window name", NULL, (SIGNAL_FUNC) cmd_window_name);
|
||||
command_bind("window move", NULL, (SIGNAL_FUNC) cmd_window_move);
|
||||
command_bind("window move left", NULL, (SIGNAL_FUNC) cmd_window_move_left);
|
||||
command_bind("window move right", NULL, (SIGNAL_FUNC) cmd_window_move_right);
|
||||
command_bind("window list", NULL, (SIGNAL_FUNC) cmd_window_list);
|
||||
daytag = g_timeout_add(30000, (GSourceFunc) sig_check_daychange, NULL);
|
||||
signal_add("server looking", (SIGNAL_FUNC) sig_server_looking);
|
||||
signal_add("server disconnected", (SIGNAL_FUNC) sig_server_disconnected);
|
||||
signal_add("server connect failed", (SIGNAL_FUNC) sig_server_disconnected);
|
||||
|
|
@ -752,24 +428,8 @@ void windows_init(void)
|
|||
|
||||
void windows_deinit(void)
|
||||
{
|
||||
command_unbind("window", (SIGNAL_FUNC) cmd_window);
|
||||
command_unbind("window new", (SIGNAL_FUNC) cmd_window_new);
|
||||
command_unbind("window close", (SIGNAL_FUNC) cmd_window_close);
|
||||
command_unbind("window kill", (SIGNAL_FUNC) cmd_window_close);
|
||||
command_unbind("window server", (SIGNAL_FUNC) cmd_window_server);
|
||||
command_unbind("window refnum", (SIGNAL_FUNC) cmd_window_refnum);
|
||||
command_unbind("window goto", (SIGNAL_FUNC) cmd_window_goto);
|
||||
command_unbind("window prev", (SIGNAL_FUNC) cmd_window_prev);
|
||||
command_unbind("window next", (SIGNAL_FUNC) cmd_window_next);
|
||||
command_unbind("window level", (SIGNAL_FUNC) cmd_window_level);
|
||||
command_unbind("window item prev", (SIGNAL_FUNC) cmd_window_item_prev);
|
||||
command_unbind("window item next", (SIGNAL_FUNC) cmd_window_item_next);
|
||||
command_unbind("window number", (SIGNAL_FUNC) cmd_window_number);
|
||||
command_unbind("window name", (SIGNAL_FUNC) cmd_window_name);
|
||||
command_unbind("window move", (SIGNAL_FUNC) cmd_window_move);
|
||||
command_unbind("window move left", (SIGNAL_FUNC) cmd_window_move_left);
|
||||
command_unbind("window move right", (SIGNAL_FUNC) cmd_window_move_right);
|
||||
command_unbind("window list", (SIGNAL_FUNC) cmd_window_list);
|
||||
g_source_remove(daytag);
|
||||
|
||||
signal_remove("server looking", (SIGNAL_FUNC) sig_server_looking);
|
||||
signal_remove("server disconnected", (SIGNAL_FUNC) sig_server_disconnected);
|
||||
signal_remove("server connect failed", (SIGNAL_FUNC) sig_server_disconnected);
|
||||
|
|
|
|||
|
|
@ -69,6 +69,10 @@ WINDOW_REC *window_find_refnum(int refnum);
|
|||
WINDOW_REC *window_find_name(const char *name);
|
||||
WINDOW_REC *window_find_item(WINDOW_REC *window, const char *name);
|
||||
|
||||
int window_refnum_prev(int refnum);
|
||||
int window_refnum_next(int refnum);
|
||||
int windows_refnum_last(void);
|
||||
|
||||
void windows_init(void);
|
||||
void windows_deinit(void);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue