summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/wee-command.c191
-rw-r--r--src/core/wee-config.c204
-rw-r--r--src/core/wee-config.h63
-rw-r--r--src/core/wee-debug.c2
-rw-r--r--src/core/weechat.c5
-rw-r--r--src/gui/CMakeLists.txt9
-rw-r--r--src/gui/Makefile.am2
-rw-r--r--src/gui/curses/CMakeLists.txt2
-rw-r--r--src/gui/curses/gui-curses-main.c84
-rw-r--r--src/gui/curses/gui-curses-nicklist.c21
-rw-r--r--src/gui/curses/gui-curses-window.c51
-rw-r--r--src/gui/curses/gui-curses.h3
-rw-r--r--src/gui/gtk/CMakeLists.txt2
-rw-r--r--src/gui/gtk/gui-gtk-main.c1
-rw-r--r--src/gui/gtk/gui-gtk-nicklist.c6
-rw-r--r--src/gui/gtk/gui-gtk-window.c34
-rw-r--r--src/gui/gtk/gui-gtk.h5
-rw-r--r--src/gui/gui-buffer.c102
-rw-r--r--src/gui/gui-buffer.h2
-rw-r--r--src/gui/gui-input.c11
-rw-r--r--src/gui/gui-layout.c624
-rw-r--r--src/gui/gui-layout.h84
-rw-r--r--src/gui/gui-nicklist.h2
-rw-r--r--src/gui/gui-window.c107
-rw-r--r--src/gui/gui-window.h28
25 files changed, 1418 insertions, 227 deletions
diff --git a/src/core/wee-command.c b/src/core/wee-command.c
index ca26a9039..26481da4d 100644
--- a/src/core/wee-command.c
+++ b/src/core/wee-command.c
@@ -51,6 +51,7 @@
#include "../gui/gui-hotlist.h"
#include "../gui/gui-input.h"
#include "../gui/gui-keyboard.h"
+#include "../gui/gui-layout.h"
#include "../gui/gui-main.h"
#include "../gui/gui-status.h"
#include "../gui/gui-window.h"
@@ -685,7 +686,7 @@ command_buffer (void *data, struct t_gui_buffer *buffer,
{
gui_window_switch_to_buffer (gui_current_window,
ptr_buffer);
- gui_window_redraw_buffer (ptr_buffer);
+ gui_status_refresh_needed = 1;
}
}
@@ -1502,6 +1503,175 @@ command_key (void *data, struct t_gui_buffer *buffer,
}
/*
+ * command_layout_display_tree: display tree of windows
+ */
+
+void
+command_layout_display_tree (struct t_gui_layout_window *layout_window,
+ int indent)
+{
+ char format[128];
+
+ if (layout_window)
+ {
+ if (layout_window->plugin_name)
+ {
+ /* leaf */
+ snprintf (format, sizeof (format), "%%-%ds%s",
+ indent * 2,
+ _("leaf: id: %d, parent: %d, plugin: '%s', buffer: '%s'"));
+ gui_chat_printf (NULL, format,
+ " ",
+ layout_window->internal_id,
+ (layout_window->parent_node) ?
+ layout_window->parent_node->internal_id : 0,
+ (layout_window->plugin_name) ?
+ layout_window->plugin_name : "-",
+ (layout_window->buffer_name) ?
+ layout_window->buffer_name : "-");
+ }
+ else
+ {
+ /* node */
+ snprintf (format, sizeof (format), "%%-%ds%s",
+ indent * 2,
+ _("node: id: %d, parent: %d, child1: %d, child2: %d, "
+ "size: %d%% (%s)"));
+ gui_chat_printf (NULL, format,
+ " ",
+ layout_window->internal_id,
+ (layout_window->parent_node) ?
+ layout_window->parent_node->internal_id : 0,
+ (layout_window->child1) ?
+ layout_window->child1->internal_id : 0,
+ (layout_window->child2) ?
+ layout_window->child2->internal_id : 0,
+ layout_window->split_pct,
+ (layout_window->split_horiz) ?
+ _("horizontal split") : _("vertical split"));
+ }
+
+ if (layout_window->child1)
+ command_layout_display_tree (layout_window->child1, indent + 1);
+
+ if (layout_window->child2)
+ command_layout_display_tree (layout_window->child2, indent + 1);
+ }
+}
+
+/*
+ * command_layout: save/apply buffers/windows layout
+ */
+
+int
+command_layout (void *data, struct t_gui_buffer *buffer,
+ int argc, char **argv, char **argv_eol)
+{
+ struct t_gui_layout_buffer *ptr_layout_buffer;
+ int flag_buffers, flag_windows;
+
+ /* make C compiler happy */
+ (void) data;
+ (void) buffer;
+ (void) argv_eol;
+
+ /* display all key bindings */
+ if (argc == 1)
+ {
+ if (gui_layout_buffers || gui_layout_windows)
+ {
+ if (gui_layout_buffers)
+ {
+ gui_chat_printf (NULL, "");
+ gui_chat_printf (NULL, _("Saved layout for buffers:"));
+ for (ptr_layout_buffer = gui_layout_buffers;
+ ptr_layout_buffer;
+ ptr_layout_buffer = ptr_layout_buffer->next_layout)
+ {
+ gui_chat_printf (NULL, " %d. %s / %s",
+ ptr_layout_buffer->number,
+ ptr_layout_buffer->plugin_name,
+ ptr_layout_buffer->buffer_name);
+ }
+ }
+ if (gui_layout_windows)
+ {
+ gui_chat_printf (NULL, "");
+ gui_chat_printf (NULL, _("Saved layout for windows:"));
+ command_layout_display_tree (gui_layout_windows, 1);
+ }
+ }
+ else
+ gui_chat_printf (NULL, _("No layout saved"));
+
+ return WEECHAT_RC_OK;
+ }
+
+ flag_buffers = 1;
+ flag_windows = 1;
+
+ if (argc > 2)
+ {
+ if (string_strcasecmp (argv[2], "buffers") == 0)
+ flag_windows = 0;
+ else if (string_strcasecmp (argv[2], "windows") == 0)
+ flag_buffers = 0;
+ }
+
+ /* save layout */
+ if (string_strcasecmp (argv[1], "save") == 0)
+ {
+ if (flag_buffers)
+ {
+ gui_layout_buffer_save ();
+ gui_chat_printf (NULL,
+ _("Layout saved for buffers (order of buffers)"));
+ }
+ if (flag_windows)
+ {
+ gui_layout_window_save ();
+ gui_chat_printf (NULL,
+ _("Layout saved for windows (buffer displayed by "
+ "each window)"));
+ }
+
+ return WEECHAT_RC_OK;
+ }
+
+ /* apply layout */
+ if (string_strcasecmp (argv[1], "apply") == 0)
+ {
+ if (flag_buffers)
+ gui_layout_buffer_apply ();
+ if (flag_windows)
+ gui_layout_window_apply ();
+
+ return WEECHAT_RC_OK;
+ }
+
+ /* reset layout */
+ if (string_strcasecmp (argv[1], "reset") == 0)
+ {
+ if (flag_buffers)
+ {
+ gui_layout_buffer_reset ();
+ gui_chat_printf (NULL,
+ _("Layout reset for buffers"));
+ }
+ if (flag_windows)
+ {
+ gui_layout_window_reset ();
+ gui_chat_printf (NULL,
+ _("Layout reset for windows"));
+ }
+
+ return WEECHAT_RC_OK;
+ }
+
+ return WEECHAT_RC_OK;
+}
+
+/*
* command_plugin_list: list loaded plugins
*/
@@ -2346,9 +2516,10 @@ command_upgrade (void *data, struct t_gui_buffer *buffer,
exec_args[0] = strdup (ptr_binary);
exec_args[3] = strdup (weechat_home);
- /* unload plugins, save config, then upgrade */
+ /* save layout, unload plugins, save config, then upgrade */
+ gui_layout_save_on_exit ();
plugin_end ();
- if (CONFIG_BOOLEAN(config_look_save_on_exit))
+ if (CONFIG_BOOLEAN(config_look_save_config_on_exit))
(void) config_weechat_write ();
gui_main_end (1);
log_close ();
@@ -2922,6 +3093,18 @@ command_init ()
"delete ALL personal bindings (use carefully!)"),
"unbind|reset",
&command_key, NULL);
+ hook_command (NULL, "layout",
+ N_("save/apply/reset layout for buffers and windows"),
+ N_("[[save | apply | reset] [buffers | windows]]"),
+ N_(" save: save current layout\n"
+ " apply: apply saved layout\n"
+ " reset: remove saved layout\n"
+ "buffers: save/apply only buffers (order of buffers)\n"
+ "windows: save/apply only windows (buffer displayed by "
+ "each window)\n\n"
+ "Without argument, this command displays saved layout."),
+ "save|apply|reset buffers|windows",
+ &command_layout, NULL);
hook_command (NULL, "plugin",
N_("list/load/unload plugins"),
N_("[list [name]] | [listfull [name]] | [load filename] | "
@@ -2933,7 +3116,7 @@ command_init ()
" reload: reload one plugin (if no name given, unload "
"all plugins, then autoload plugins)\n"
" unload: unload one or all plugins\n\n"
- "Without argument, /plugin command lists loaded plugins."),
+ "Without argument, this command lists loaded plugins."),
"list|listfull|load|autoload|reload|unload %f|%p",
&command_plugin, NULL);
hook_command (NULL, "quit",
diff --git a/src/core/wee-config.c b/src/core/wee-config.c
index cb664a53e..5053680e3 100644
--- a/src/core/wee-config.c
+++ b/src/core/wee-config.c
@@ -48,6 +48,7 @@
#include "../gui/gui-filter.h"
#include "../gui/gui-hotlist.h"
#include "../gui/gui-keyboard.h"
+#include "../gui/gui-layout.h"
#include "../gui/gui-nicklist.h"
#include "../gui/gui-status.h"
#include "../gui/gui-window.h"
@@ -94,7 +95,8 @@ struct t_config_option *config_look_prefix_align;
struct t_config_option *config_look_prefix_align_max;
struct t_config_option *config_look_prefix_suffix;
struct t_config_option *config_look_read_marker;
-struct t_config_option *config_look_save_on_exit;
+struct t_config_option *config_look_save_config_on_exit;
+struct t_config_option *config_look_save_layout_on_exit;
struct t_config_option *config_look_scroll_amount;
struct t_config_option *config_look_set_title;
@@ -195,21 +197,22 @@ struct t_hook *config_day_change_timer = NULL;
/*
- * config_change_save_on_exit: called when "save_on_exit" flag is changed
+ * config_change_save_config_on_exit: called when "save_config_on_exit" flag is changed
*/
void
-config_change_save_on_exit (void *data, struct t_config_option *option)
+config_change_save_config_on_exit (void *data, struct t_config_option *option)
{
/* make C compiler happy */
(void) data;
(void) option;
- if (!CONFIG_BOOLEAN(config_look_save_on_exit))
+ if (!CONFIG_BOOLEAN(config_look_save_config_on_exit))
{
gui_chat_printf (NULL,
_("Warning: you should now issue /save to write "
- "\"save_on_exit\" option in configuration file"));
+ "\"save_config_on_exit\" option in configuration "
+ "file"));
}
}
@@ -256,7 +259,7 @@ config_change_buffer_content (void *data, struct t_config_option *option)
(void) option;
if (gui_ok)
- gui_window_redraw_buffer (gui_current_window->buffer);
+ gui_current_window->refresh_needed = 1;
}
/*
@@ -273,7 +276,7 @@ config_change_buffer_time_format (void *data, struct t_config_option *option)
gui_chat_time_length = util_get_time_length (CONFIG_STRING(config_look_buffer_time_format));
gui_chat_change_time_format ();
if (gui_ok)
- gui_window_redraw_buffer (gui_current_window->buffer);
+ gui_window_refresh_needed = 1;
}
/*
@@ -302,7 +305,7 @@ config_change_read_marker (void *data, struct t_config_option *option)
(void) data;
(void) option;
- gui_window_redraw_all_buffers ();
+ gui_window_refresh_needed = 1;
}
/*
@@ -463,6 +466,10 @@ config_weechat_reload (void *data, struct t_config_file *config_file)
/* remove all bars */
gui_bar_free_all ();
+ /* remove layout */
+ gui_layout_buffer_reset ();
+ gui_layout_window_reset ();
+
/* remove all filters */
gui_filter_free_all ();
@@ -479,7 +486,6 @@ config_weechat_reload (void *data, struct t_config_file *config_file)
/*
* config_weechat_bar_read: read bar option in config file
- * return: 1 if ok, 0 if error
*/
int
@@ -544,46 +550,171 @@ config_weechat_bar_read (void *data, struct t_config_file *config_file,
}
}
- return 1;
+ return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE;
}
/*
- * config_weechat_filter_read: read filter option from config file
- * return 1 if ok, 0 if error
+ * config_weechat_layout_read: read layout option in config file
*/
int
-config_weechat_filter_read (void *data,
- struct t_config_file *config_file,
+config_weechat_layout_read (void *data, struct t_config_file *config_file,
struct t_config_section *section,
const char *option_name, const char *value)
{
- char **argv, **argv_eol;
int argc;
+ char **argv, *error1, *error2, *error3, *error4;
+ long number1, number2, number3, number4;
+ struct t_gui_layout_window *parent;
/* make C compiler happy */
(void) data;
(void) config_file;
(void) section;
- if (option_name)
+ if (option_name && value && value[0])
{
- if (value && value[0])
+ if (string_strcasecmp (option_name, "buffer") == 0)
{
argv = string_explode (value, ";", 0, 0, &argc);
- argv_eol = string_explode (value, ";", 1, 0, NULL);
- if (argv && argv_eol && (argc >= 3))
+ if (argv)
{
- gui_filter_new (argv[0], argv[1], argv_eol[2]);
+ if (argc >= 3)
+ {
+ error1 = NULL;
+ number1 = strtol (argv[2], &error1, 10);
+ if (error1 && !error1[0])
+ {
+ gui_layout_buffer_add (argv[0], argv[1], number1);
+ }
+ }
+ string_free_exploded (argv);
}
+ }
+ else if (string_strcasecmp (option_name, "window") == 0)
+ {
+ argv = string_explode (value, ";", 0, 0, &argc);
if (argv)
+ {
+ if (argc >= 6)
+ {
+ error1 = NULL;
+ number1 = strtol (argv[0], &error1, 10);
+ error2 = NULL;
+ number2 = strtol (argv[1], &error2, 10);
+ error3 = NULL;
+ number3 = strtol (argv[2], &error3, 10);
+ error4 = NULL;
+ number4 = strtol (argv[3], &error4, 10);
+ if (error1 && !error1[0] && error2 && !error2[0]
+ && error3 && !error3[0] && error4 && !error4[0])
+ {
+ parent = gui_layout_window_search_by_id (number2);
+ gui_layout_window_add (number1,
+ parent,
+ number3,
+ number4,
+ (strcmp (argv[4], "-") != 0) ?
+ argv[4] : NULL,
+ (strcmp (argv[4], "-") != 0) ?
+ argv[5] : NULL);
+ }
+ }
string_free_exploded (argv);
- if (argv_eol)
- string_free_exploded (argv_eol);
+ }
}
}
- return 1;
+ return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE;
+}
+
+/*
+ * config_weechat_layout_write: write windows layout in configuration file
+ */
+
+void
+config_weechat_layout_write_tree (struct t_config_file *config_file,
+ struct t_gui_layout_window *layout_window)
+{
+ config_file_write_line (config_file, "window", "\"%d;%d;%d;%d;%s;%s\"",
+ layout_window->internal_id,
+ (layout_window->parent_node) ?
+ layout_window->parent_node->internal_id : 0,
+ layout_window->split_pct,
+ layout_window->split_horiz,
+ (layout_window->plugin_name) ?
+ layout_window->plugin_name : "-",
+ (layout_window->buffer_name) ?
+ layout_window->buffer_name : "-");
+
+ if (layout_window->child1)
+ config_weechat_layout_write_tree (config_file, layout_window->child1);
+
+ if (layout_window->child2)
+ config_weechat_layout_write_tree (config_file, layout_window->child2);
+}
+
+/*
+ * config_weechat_layout_write: write layout section in configuration file
+ */
+
+void
+config_weechat_layout_write (void *data, struct t_config_file *config_file,
+ const char *section_name)
+{
+ struct t_gui_layout_buffer *ptr_layout_buffer;
+
+ /* make C compiler happy */
+ (void) data;
+
+ config_file_write_line (config_file, section_name, NULL);
+
+ for (ptr_layout_buffer = gui_layout_buffers; ptr_layout_buffer;
+ ptr_layout_buffer = ptr_layout_buffer->next_layout)
+ {
+ config_file_write_line (config_file, "buffer", "\"%s;%s;%d\"",
+ ptr_layout_buffer->plugin_name,
+ ptr_layout_buffer->buffer_name,
+ ptr_layout_buffer->number);
+ }
+
+ if (gui_layout_windows)
+ config_weechat_layout_write_tree (config_file, gui_layout_windows);
+}
+
+/*
+ * config_weechat_filter_read: read filter option from config file
+ */
+
+int
+config_weechat_filter_read (void *data,
+ struct t_config_file *config_file,
+ struct t_config_section *section,
+ const char *option_name, const char *value)
+{
+ char **argv, **argv_eol;
+ int argc;
+
+ /* make C compiler happy */
+ (void) data;
+ (void) config_file;
+ (void) section;
+
+ if (option_name && value && value[0])
+ {
+ argv = string_explode (value, ";", 0, 0, &argc);
+ argv_eol = string_explode (value, ";", 1, 0, NULL);
+ if (argv && argv_eol && (argc >= 3))
+ {
+ gui_filter_new (argv[0], argv[1], argv_eol[2]);
+ }
+ if (argv)
+ string_free_exploded (argv);
+ if (argv_eol)
+ string_free_exploded (argv_eol);
+ }
+
+ return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE;
}
/*
@@ -615,7 +746,6 @@ config_weechat_filter_write (void *data, struct t_config_file *config_file,
/*
* config_weechat_key_read: read key option in config file
- * return 1 if ok, 0 if error
*/
int
@@ -642,7 +772,7 @@ config_weechat_key_read (void *data, struct t_config_file *config_file,
}
}
- return 1;
+ return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE;
}
/*
@@ -915,11 +1045,16 @@ config_weechat_init ()
N_("use a marker (line or char) on buffers to show first unread line"),
"none|line|dotted-line|char",
0, 0, "dotted-line", NULL, NULL, &config_change_read_marker, NULL, NULL, NULL);
- config_look_save_on_exit = config_file_new_option (
+ config_look_save_config_on_exit = config_file_new_option (
weechat_config_file, ptr_section,
- "save_on_exit", "boolean",
+ "save_config_on_exit", "boolean",
N_("save configuration file on exit"),
- NULL, 0, 0, "on", NULL, NULL, &config_change_save_on_exit, NULL, NULL, NULL);
+ NULL, 0, 0, "on", NULL, NULL, &config_change_save_config_on_exit, NULL, NULL, NULL);
+ config_look_save_layout_on_exit = config_file_new_option (
+ weechat_config_file, ptr_section,
+ "save_layout_on_exit", "integer",
+ N_("save layout on exit (buffers, windows, or both)"),
+ "none|buffers|windows|all", 0, 0, "all", NULL, NULL, NULL, NULL, NULL, NULL);
config_look_scroll_amount = config_file_new_option (
weechat_config_file, ptr_section,
"scroll_amount", "integer",
@@ -1545,6 +1680,19 @@ config_weechat_init ()
weechat_config_section_bar = ptr_section;
+ /* layout */
+ ptr_section = config_file_new_section (weechat_config_file, "layout",
+ 0, 0,
+ &config_weechat_layout_read, NULL,
+ &config_weechat_layout_write, NULL,
+ NULL, NULL,
+ NULL, NULL);
+ if (!ptr_section)
+ {
+ config_file_free (weechat_config_file);
+ return 0;
+ }
+
/* filters */
ptr_section = config_file_new_section (weechat_config_file, "filter",
0, 0,
diff --git a/src/core/wee-config.h b/src/core/wee-config.h
index 7e49e1003..afa4c05fa 100644
--- a/src/core/wee-config.h
+++ b/src/core/wee-config.h
@@ -24,26 +24,46 @@
#define WEECHAT_CONFIG_NAME "weechat"
-#define CONFIG_LOOK_NICKLIST_LEFT 0
-#define CONFIG_LOOK_NICKLIST_RIGHT 1
-#define CONFIG_LOOK_NICKLIST_TOP 2
-#define CONFIG_LOOK_NICKLIST_BOTTOM 3
-
-#define CONFIG_LOOK_PREFIX_ALIGN_NONE 0
-#define CONFIG_LOOK_PREFIX_ALIGN_LEFT 1
-#define CONFIG_LOOK_PREFIX_ALIGN_RIGHT 2
-
-#define CONFIG_LOOK_HOTLIST_SORT_GROUP_TIME_ASC 0
-#define CONFIG_LOOK_HOTLIST_SORT_GROUP_TIME_DESC 1
-#define CONFIG_LOOK_HOTLIST_SORT_GROUP_NUMBER_ASC 2
-#define CONFIG_LOOK_HOTLIST_SORT_GROUP_NUMBER_DESC 3
-#define CONFIG_LOOK_HOTLIST_SORT_NUMBER_ASC 4
-#define CONFIG_LOOK_HOTLIST_SORT_NUMBER_DESC 5
-
-#define CONFIG_LOOK_READ_MARKER_NONE 0
-#define CONFIG_LOOK_READ_MARKER_LINE 1
-#define CONFIG_LOOK_READ_MARKER_DOTTED_LINE 2
-#define CONFIG_LOOK_READ_MARKER_CHAR 3
+enum t_config_look_nicklist
+{
+ CONFIG_LOOK_NICKLIST_LEFT = 0,
+ CONFIG_LOOK_NICKLIST_RIGHT,
+ CONFIG_LOOK_NICKLIST_TOP,
+ CONFIG_LOOK_NICKLIST_BOTTOM,
+};
+
+enum t_config_look_prefix_align
+{
+ CONFIG_LOOK_PREFIX_ALIGN_NONE = 0,
+ CONFIG_LOOK_PREFIX_ALIGN_LEFT,
+ CONFIG_LOOK_PREFIX_ALIGN_RIGHT,
+};
+
+enum t_config_look_hotlist_sort
+{
+ CONFIG_LOOK_HOTLIST_SORT_GROUP_TIME_ASC = 0,
+ CONFIG_LOOK_HOTLIST_SORT_GROUP_TIME_DESC,
+ CONFIG_LOOK_HOTLIST_SORT_GROUP_NUMBER_ASC,
+ CONFIG_LOOK_HOTLIST_SORT_GROUP_NUMBER_DESC,
+ CONFIG_LOOK_HOTLIST_SORT_NUMBER_ASC,
+ CONFIG_LOOK_HOTLIST_SORT_NUMBER_DESC,
+};
+
+enum t_config_look_read_marker
+{
+ CONFIG_LOOK_READ_MARKER_NONE = 0,
+ CONFIG_LOOK_READ_MARKER_LINE,
+ CONFIG_LOOK_READ_MARKER_DOTTED_LINE,
+ CONFIG_LOOK_READ_MARKER_CHAR,
+};
+
+enum t_config_look_save_layout_on_exit
+{
+ CONFIG_LOOK_SAVE_LAYOUT_ON_EXIT_NONE = 0,
+ CONFIG_LOOK_SAVE_LAYOUT_ON_EXIT_BUFFERS,
+ CONFIG_LOOK_SAVE_LAYOUT_ON_EXIT_WINDOWS,
+ CONFIG_LOOK_SAVE_LAYOUT_ON_EXIT_ALL,
+};
extern struct t_config_file *weechat_config_file;
extern struct t_config_section *weechat_config_section_bar;
@@ -81,7 +101,8 @@ extern struct t_config_option *config_look_prefix_align;
extern struct t_config_option *config_look_prefix_align_max;
extern struct t_config_option *config_look_prefix_suffix;
extern struct t_config_option *config_look_read_marker;
-extern struct t_config_option *config_look_save_on_exit;
+extern struct t_config_option *config_look_save_config_on_exit;
+extern struct t_config_option *config_look_save_layout_on_exit;
extern struct t_config_option *config_look_scroll_amount;
extern struct t_config_option *config_look_set_title;
diff --git a/src/core/wee-debug.c b/src/core/wee-debug.c
index 7bf5ef791..e7c2ec075 100644
--- a/src/core/wee-debug.c
+++ b/src/core/wee-debug.c
@@ -39,6 +39,7 @@
#include "../gui/gui-filter.h"
#include "../gui/gui-hotlist.h"
#include "../gui/gui-keyboard.h"
+#include "../gui/gui-layout.h"
#include "../gui/gui-main.h"
#include "../gui/gui-window.h"
#include "../plugins/plugin.h"
@@ -78,6 +79,7 @@ debug_dump (int crash)
gui_window_print_log ();
gui_buffer_print_log ();
+ gui_layout_print_log ();
gui_keyboard_print_log (NULL);
gui_filter_print_log ();
gui_bar_print_log ();
diff --git a/src/core/weechat.c b/src/core/weechat.c
index e28519a78..31181a0b4 100644
--- a/src/core/weechat.c
+++ b/src/core/weechat.c
@@ -63,6 +63,7 @@
#include "wee-util.h"
#include "../gui/gui-chat.h"
#include "../gui/gui-color.h"
+#include "../gui/gui-layout.h"
#include "../gui/gui-main.h"
#include "../gui/gui-keyboard.h"
#include "../plugins/plugin.h"
@@ -397,11 +398,13 @@ main (int argc, char *argv[])
plugin_init (weechat_auto_load_plugins, /* init plugin interface(s) */
argc, argv);
command_startup (1); /* command executed after plugins */
+ gui_layout_window_apply (); /* apply saved layout for windows */
gui_main_loop (); /* WeeChat main loop */
+ gui_layout_save_on_exit (); /* save layout */
plugin_end (); /* end plugin interface(s) */
- if (CONFIG_BOOLEAN(config_look_save_on_exit))
+ if (CONFIG_BOOLEAN(config_look_save_config_on_exit))
(void) config_weechat_write (NULL); /* save WeeChat config file */
gui_main_end (1); /* shut down WeeChat GUI */
config_file_free_all (); /* free all configuration files */
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt
index 4cceb09a5..b4e044a58 100644
--- a/src/gui/CMakeLists.txt
+++ b/src/gui/CMakeLists.txt
@@ -14,10 +14,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-IF(NOT DISABLE_NCURSES)
- SUBDIRS( curses )
-ENDIF(NOT DISABLE_NCURSES)
-
SET(LIB_GUI_COMMON_SRC
gui-bar.c gui-bar.h
gui-bar-item.c gui-bar-item.h
@@ -30,6 +26,7 @@ gui-history.c gui-history.h
gui-hotlist.c gui-hotlist.h
gui-input.c gui-input.h
gui-keyboard.c gui-keyboard.h
+gui-layout.c gui-layout.h
gui-main.h
gui-nicklist.c gui-nicklist.h
gui-status.c gui-status.h
@@ -38,6 +35,10 @@ gui-window.c gui-window.h)
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR})
ADD_LIBRARY(weechat_gui_common STATIC ${LIB_GUI_COMMON_SRC})
+IF(NOT DISABLE_NCURSES)
+ SUBDIRS( curses )
+ENDIF(NOT DISABLE_NCURSES)
+
IF(ENABLE_GTK)
ADD_SUBDIRECTORY( gtk )
ENDIF(ENABLE_GTK)
diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am
index 4d94bb221..707c0d5b6 100644
--- a/src/gui/Makefile.am
+++ b/src/gui/Makefile.am
@@ -40,6 +40,8 @@ lib_weechat_gui_common_a_SOURCES = gui-bar.c \
gui-input.h \
gui-keyboard.c \
gui-keyboard.h \
+ gui-layout.c \
+ gui-layout.h \
gui-main.h \
gui-status.c \
gui-status.h \
diff --git a/src/gui/curses/CMakeLists.txt b/src/gui/curses/CMakeLists.txt
index 7be285854..bdfd9d256 100644
--- a/src/gui/curses/CMakeLists.txt
+++ b/src/gui/curses/CMakeLists.txt
@@ -48,6 +48,6 @@ ADD_EXECUTABLE(${EXECUTABLE} ${WEECHAT_CURSES_SRC})
INCLUDE_DIRECTORIES(.. ../../core ../../plugins)
# Because of a linker bug, we have to link 2 times with libweechat_core.a
-TARGET_LINK_LIBRARIES(${EXECUTABLE} ${STATIC_LIBS} ${EXTRA_LIBS})
+TARGET_LINK_LIBRARIES(${EXECUTABLE} ${STATIC_LIBS} ${EXTRA_LIBS} ${STATIC_LIBS})
INSTALL(TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin)
diff --git a/src/gui/curses/gui-curses-main.c b/src/gui/curses/gui-curses-main.c
index 8c3a69da7..8226011f0 100644
--- a/src/gui/curses/gui-curses-main.c
+++ b/src/gui/curses/gui-curses-main.c
@@ -122,7 +122,6 @@ gui_main_init ()
gui_buffer_set_title (ptr_buffer,
"WeeChat " WEECHAT_COPYRIGHT_DATE
" - " WEECHAT_WEBSITE);
- gui_window_redraw_buffer (ptr_buffer);
}
else
gui_init_ok = 0;
@@ -246,57 +245,56 @@ gui_main_loop ()
/* execute hook timers */
hook_timer_exec ();
- /* refresh status bar if needed */
- if (gui_status_refresh_needed)
- gui_status_draw (1);
-
- for (ptr_bar = gui_bars; ptr_bar; ptr_bar = ptr_bar->next_bar)
+ /* refresh window if needed */
+ if (gui_window_refresh_needed)
{
- if (ptr_bar->bar_refresh_needed)
- {
- gui_bar_draw (ptr_bar);
- ptr_bar->bar_refresh_needed = 0;
- }
+ gui_window_refresh_screen ();
+ gui_window_refresh_needed = 0;
}
-
- for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window)
+ else
{
- if (ptr_win->refresh_needed)
+ /* refresh status bar if needed */
+ if (gui_status_refresh_needed)
+ gui_status_draw (1);
+
+ for (ptr_bar = gui_bars; ptr_bar; ptr_bar = ptr_bar->next_bar)
{
- gui_window_switch_to_buffer (ptr_win, ptr_win->buffer);
- gui_window_redraw_buffer (ptr_win->buffer);
- ptr_win->refresh_needed = 0;
+ if (ptr_bar->bar_refresh_needed)
+ gui_bar_draw (ptr_bar);
}
- }
-
- for (ptr_buffer = gui_buffers; ptr_buffer;
- ptr_buffer = ptr_buffer->next_buffer)
- {
- /* refresh title if needed */
- if (ptr_buffer->title_refresh_needed)
- gui_chat_draw_title (ptr_buffer, 1);
- /* refresh chat if needed */
- if (ptr_buffer->chat_refresh_needed)
+ for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window)
{
- gui_chat_draw (ptr_buffer,
- (ptr_buffer->chat_refresh_needed) > 1 ? 1 : 0);
+ if (ptr_win->refresh_needed)
+ {
+ gui_window_switch_to_buffer (ptr_win, ptr_win->buffer);
+ gui_window_redraw_buffer (ptr_win->buffer);
+ ptr_win->refresh_needed = 0;
+ }
}
- /* refresh nicklist if needed */
- if (ptr_buffer->nicklist_refresh_needed)
- gui_nicklist_draw (ptr_buffer, 1);
-
- /* refresh input if needed */
- if (ptr_buffer->input_refresh_needed)
- gui_input_draw (ptr_buffer, 1);
- }
-
- /* refresh window if needed */
- if (gui_window_refresh_needed)
- {
- gui_window_refresh_screen ();
- gui_window_refresh_needed = 0;
+ for (ptr_buffer = gui_buffers; ptr_buffer;
+ ptr_buffer = ptr_buffer->next_buffer)
+ {
+ /* refresh title if needed */
+ if (ptr_buffer->title_refresh_needed)
+ gui_chat_draw_title (ptr_buffer, 1);
+
+ /* refresh nicklist if needed */
+ if (ptr_buffer->nicklist_refresh_needed)
+ gui_nicklist_draw (ptr_buffer, 1);
+
+ /* refresh chat if needed */
+ if (ptr_buffer->chat_refresh_needed)
+ {
+ gui_chat_draw (ptr_buffer,
+ (ptr_buffer->chat_refresh_needed) > 1 ? 1 : 0);
+ }
+
+ /* refresh input if needed */
+ if (ptr_buffer->input_refresh_needed)
+ gui_input_draw (ptr_buffer, 1);
+ }
}
/* wait for keyboard or network activity */
diff --git a/src/gui/curses/gui-curses-nicklist.c b/src/gui/curses/gui-curses-nicklist.c
index 8b189099f..4882363a5 100644
--- a/src/gui/curses/gui-curses-nicklist.c
+++ b/src/gui/curses/gui-curses-nicklist.c
@@ -40,21 +40,31 @@
/*
* gui_nicklist_draw: draw nick window for a buffer
+ * return 1 if chat window has been refreshed, 0 if only
+ * nicklist has been refreshed
*/
-void
+int
gui_nicklist_draw (struct t_gui_buffer *buffer, int erase)
{
struct t_gui_window *ptr_win;
struct t_gui_nick_group *ptr_group, *save_ptr_group;
struct t_gui_nick *ptr_nick, *save_ptr_nick;
struct t_config_option *ptr_option;
- int i, j, k, x, y, x2, max_y, column, max_length, max_chars;
+ int rc, i, j, k, x, y, x2, max_y, column, max_length, max_chars;
int nicks_displayed, num_to_display, chars_left;
char format_empty[32], *buf, *ptr_buf, *ptr_next, saved_char;
- if (!gui_ok || (!buffer->nicklist))
- return;
+ rc = 0;
+
+ if (!gui_ok)
+ return 0;
+
+ if (!buffer->nicklist)
+ {
+ buffer->nicklist_refresh_needed = 0;
+ return 0;
+ }
for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window)
{
@@ -80,6 +90,7 @@ gui_nicklist_draw (struct t_gui_buffer *buffer, int erase)
ptr_win->win_nick_x);
gui_chat_draw (buffer, 1);
erase = 1;
+ rc = 1;
}
}
@@ -334,4 +345,6 @@ gui_nicklist_draw (struct t_gui_buffer *buffer, int erase)
}
buffer->nicklist_refresh_needed = 0;
+
+ return rc;
}
diff --git a/src/gui/curses/gui-curses-window.c b/src/gui/curses/gui-curses-window.c
index da177a941..dcdfe4a4f 100644
--- a/src/gui/curses/gui-curses-window.c
+++ b/src/gui/curses/gui-curses-window.c
@@ -585,9 +585,8 @@ gui_window_redraw_buffer (struct t_gui_buffer *buffer)
return;
gui_chat_draw_title (buffer, 1);
- gui_chat_draw (buffer, 1);
- if (buffer->nicklist)
- gui_nicklist_draw (buffer, 1);
+ if (!gui_nicklist_draw (buffer, 1))
+ gui_chat_draw (buffer, 1);
gui_status_draw (1);
gui_input_draw (buffer, 1);
}
@@ -714,9 +713,11 @@ gui_window_switch_to_buffer (struct t_gui_window *window,
for (ptr_bar_win = GUI_CURSES(window)->bar_windows; ptr_bar_win;
ptr_bar_win = ptr_bar_win->next_bar_window)
{
- gui_bar_draw (ptr_bar_win->bar);
+ ptr_bar_win->bar->bar_refresh_needed = 1;
}
+ window->refresh_needed = 1;
+
hook_signal_send ("buffer_switch",
WEECHAT_HOOK_SIGNAL_POINTER, buffer);
}
@@ -750,7 +751,7 @@ gui_window_switch (struct t_gui_window *window)
gui_window_switch_to_buffer (gui_current_window,
gui_current_window->buffer);
- gui_window_redraw_buffer (gui_current_window->buffer);
+ gui_current_window->refresh_needed = 1;
}
/*
@@ -1298,14 +1299,16 @@ gui_window_refresh_windows ()
* gui_window_split_horiz: split a window horizontally
*/
-void
+struct t_gui_window *
gui_window_split_horiz (struct t_gui_window *window, int percentage)
{
struct t_gui_window *new_window;
int height1, height2;
if (!gui_ok)
- return;
+ return NULL;
+
+ new_window = NULL;
height1 = (window->win_height * percentage) / 100;
height2 = window->win_height - height1;
@@ -1313,10 +1316,11 @@ gui_window_split_horiz (struct t_gui_window *window, int percentage)
if ((height1 >= GUI_WINDOW_MIN_HEIGHT) && (height2 >= GUI_WINDOW_MIN_HEIGHT)
&& (percentage > 0) && (percentage <= 100))
{
- if ((new_window = gui_window_new (window,
- window->win_x, window->win_y,
- window->win_width, height1,
- 100, percentage)))
+ new_window = gui_window_new (window,
+ window->win_x, window->win_y,
+ window->win_width, height1,
+ 100, percentage);
+ if (new_window)
{
/* reduce old window height (bottom window) */
window->win_y = new_window->win_y + new_window->win_height;
@@ -1332,20 +1336,24 @@ gui_window_split_horiz (struct t_gui_window *window, int percentage)
gui_window_switch (new_window);
}
}
+
+ return new_window;
}
/*
* gui_window_split_vertic: split a window vertically
*/
-void
+struct t_gui_window *
gui_window_split_vertic (struct t_gui_window *window, int percentage)
{
struct t_gui_window *new_window;
int width1, width2;
if (!gui_ok)
- return;
+ return NULL;
+
+ new_window = NULL;
width1 = (window->win_width * percentage) / 100;
width2 = window->win_width - width1 - 1;
@@ -1353,10 +1361,11 @@ gui_window_split_vertic (struct t_gui_window *window, int percentage)
if ((width1 >= GUI_WINDOW_MIN_WIDTH) && (width2 >= GUI_WINDOW_MIN_WIDTH)
&& (percentage > 0) && (percentage <= 100))
{
- if ((new_window = gui_window_new (window,
- window->win_x + width1 + 1, window->win_y,
- width2, window->win_height,
- percentage, 100)))
+ new_window = gui_window_new (window,
+ window->win_x + width1 + 1, window->win_y,
+ width2, window->win_height,
+ percentage, 100);
+ if (new_window)
{
/* reduce old window height (left window) */
window->win_width = width1;
@@ -1374,6 +1383,8 @@ gui_window_split_vertic (struct t_gui_window *window, int percentage)
gui_window_draw_separator (gui_current_window);
}
}
+
+ return new_window;
}
/*
@@ -1410,7 +1421,7 @@ gui_window_resize (struct t_gui_window *window, int percentage)
1) < 0)
parent->split_pct = old_split_pct;
else
- gui_window_refresh_windows ();
+ gui_window_refresh_needed = 1;
}
}
@@ -1456,7 +1467,7 @@ gui_window_merge (struct t_gui_window *window)
gui_window_tree_node_to_leaf (parent, window);
gui_window_switch_to_buffer (window, window->buffer);
- gui_window_redraw_buffer (window->buffer);
+ window->refresh_needed = 1;
return 1;
}
return 0;
@@ -1501,7 +1512,7 @@ gui_window_merge_all (struct t_gui_window *window)
gui_current_window = window;
gui_window_switch_to_buffer (window, window->buffer);
- gui_window_redraw_buffer (window->buffer);
+ window->refresh_needed = 1;
}
}
diff --git a/src/gui/curses/gui-curses.h b/src/gui/curses/gui-curses.h
index ac48ff02e..bd817c873 100644
--- a/src/gui/curses/gui-curses.h
+++ b/src/gui/curses/gui-curses.h
@@ -28,6 +28,8 @@
#include <curses.h>
#endif
+struct t_gui_buffer;
+
#define GUI_WINDOW_MIN_WIDTH 10
#define GUI_WINDOW_MIN_HEIGHT 5
@@ -92,6 +94,7 @@ extern void gui_keyboard_default_bindings ();
extern int gui_keyboard_read_cb (void *data);
/* window functions */
+extern void gui_window_redraw_buffer (struct t_gui_buffer *buffer);
extern int gui_window_utf_char_valid (const char *utf_char);
extern void gui_window_wprintw (WINDOW *window, const char *data, ...);
extern void gui_window_clear_weechat (WINDOW *window, int num_color);
diff --git a/src/gui/gtk/CMakeLists.txt b/src/gui/gtk/CMakeLists.txt
index 1045c4fa8..a95cb3376 100644
--- a/src/gui/gtk/CMakeLists.txt
+++ b/src/gui/gtk/CMakeLists.txt
@@ -36,6 +36,6 @@ ADD_EXECUTABLE(${EXECUTABLE} ${WEECHAT_GTK_SRC})
INCLUDE_DIRECTORIES(.. ../../core ../../plugins)
# Because of a linker bug, we have to link 2 times with libweechat_core.a
-TARGET_LINK_LIBRARIES(${EXECUTABLE} -lweechat_core ${STATIC_LIBS} ${EXTRA_LIBS})
+TARGET_LINK_LIBRARIES(${EXECUTABLE} ${STATIC_LIBS} ${EXTRA_LIBS} ${STATIC_LIBS})
INSTALL(TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin)
diff --git a/src/gui/gtk/gui-gtk-main.c b/src/gui/gtk/gui-gtk-main.c
index 1560c709c..4654434f9 100644
--- a/src/gui/gtk/gui-gtk-main.c
+++ b/src/gui/gtk/gui-gtk-main.c
@@ -180,7 +180,6 @@ gui_main_init ()
gui_buffer_set_title (ptr_buffer,
PACKAGE_STRING " " WEECHAT_COPYRIGHT_DATE
" - " WEECHAT_WEBSITE);
- gui_window_redraw_buffer (ptr_buffer);
}
else
gui_init_ok = 0;
diff --git a/src/gui/gtk/gui-gtk-nicklist.c b/src/gui/gtk/gui-gtk-nicklist.c
index 67b765ac7..16f4819d3 100644
--- a/src/gui/gtk/gui-gtk-nicklist.c
+++ b/src/gui/gtk/gui-gtk-nicklist.c
@@ -31,12 +31,16 @@
/*
* gui_nicklist_draw: draw nick window for a buffer
+ * return 1 if chat window has been refreshed, 0 if only
+ * nicklist has been refreshed
*/
-void
+int
gui_nicklist_draw (struct t_gui_buffer *buffer, int erase)
{
/* TODO: write this function for Gtk */
(void) buffer;
(void) erase;
+
+ return 0;
}
diff --git a/src/gui/gtk/gui-gtk-window.c b/src/gui/gtk/gui-gtk-window.c
index 9c7cbd564..ede8ccf33 100644
--- a/src/gui/gtk/gui-gtk-window.c
+++ b/src/gui/gtk/gui-gtk-window.c
@@ -610,24 +610,27 @@ gui_window_refresh_windows ()
* gui_window_split_horiz: split a window horizontally
*/
-void
+struct t_gui_window *
gui_window_split_horiz (struct t_gui_window *window, int percentage)
{
struct t_gui_window *new_window;
int height1, height2;
if (!gui_ok)
- return;
+ return NULL;
+
+ new_window = NULL;
height1 = (window->win_height * percentage) / 100;
height2 = window->win_height - height1;
if ((percentage > 0) && (percentage <= 100))
{
- if ((new_window = gui_window_new (window,
- window->win_x, window->win_y,
- window->win_width, height1,
- 100, percentage)))
+ new_window = gui_window_new (window,
+ window->win_x, window->win_y,
+ window->win_width, height1,
+ 100, percentage);
+ if (new_window)
{
/* reduce old window height (bottom window) */
window->win_y = new_window->win_y + new_window->win_height;
@@ -645,30 +648,35 @@ gui_window_split_horiz (struct t_gui_window *window, int percentage)
gui_window_redraw_buffer (gui_current_window->buffer);
}
}
+
+ return new_window;
}
/*
* gui_window_split_vertic: split a window vertically
*/
-void
+struct t_gui_window *
gui_window_split_vertic (struct t_gui_window *window, int percentage)
{
struct t_gui_window *new_window;
int width1, width2;
if (!gui_ok)
- return;
+ return NULL;
+
+ new_window = NULL;
width1 = (window->win_width * percentage) / 100;
width2 = window->win_width - width1 - 1;
if ((percentage > 0) && (percentage <= 100))
{
- if ((new_window = gui_window_new (window,
- window->win_x + width1 + 1, window->win_y,
- width2, window->win_height,
- percentage, 100)))
+ new_window = gui_window_new (window,
+ window->win_x + width1 + 1, window->win_y,
+ width2, window->win_height,
+ percentage, 100);
+ if (new_window)
{
/* reduce old window height (left window) */
window->win_width = width1;
@@ -688,6 +696,8 @@ gui_window_split_vertic (struct t_gui_window *window, int percentage)
gui_window_draw_separator (gui_current_window);
}
}
+
+ return new_window;
}
/*
diff --git a/src/gui/gtk/gui-gtk.h b/src/gui/gtk/gui-gtk.h
index 53428daac..5513f29a5 100644
--- a/src/gui/gtk/gui-gtk.h
+++ b/src/gui/gtk/gui-gtk.h
@@ -23,6 +23,7 @@
#include <gtk/gtk.h>
struct t_gui_window;
+struct t_gui_buffer;
struct t_gui_line;
/* TODO: remove these temporary defines */
@@ -82,9 +83,6 @@ struct t_gui_gtk_objects
int current_color_attr; /* attr sum of last color(s) used */
};
-//extern t_gui_color gui_weechat_colors[];
-//extern int gui_irc_colors[GUI_NUM_IRC_COLORS][2];
-
extern GtkWidget *gui_gtk_main_window;
extern GtkWidget *gui_gtk_vbox1;
extern GtkWidget *gui_gtk_entry_topic;
@@ -114,6 +112,7 @@ extern void gui_keyboard_read ();
extern void gui_keyboard_flush ();
/* window functions */
+extern void gui_window_redraw_buffer (struct t_gui_buffer *buffer);
extern void gui_window_title_set ();
extern void gui_window_title_reset ();
diff --git a/src/gui/gui-buffer.c b/src/gui/gui-buffer.c
index 7f4a1ec15..c8c78e4e5 100644
--- a/src/gui/gui-buffer.c
+++ b/src/gui/gui-buffer.c
@@ -48,6 +48,7 @@
#include "gui-hotlist.h"
#include "gui-input.h"
#include "gui-keyboard.h"
+#include "gui-layout.h"
#include "gui-main.h"
#include "gui-nicklist.h"
#include "gui-status.h"
@@ -63,6 +64,71 @@ char *gui_buffer_notify_string[GUI_BUFFER_NUM_NOTIFY] =
/*
+ * gui_buffer_find_pos: find position for buffer in list
+ */
+
+struct t_gui_buffer *
+gui_buffer_find_pos (struct t_gui_buffer *buffer)
+{
+ struct t_gui_buffer *ptr_buffer;
+
+ /* if no number is asked by layout, then add to the end by default */
+ if (buffer->layout_number < 1)
+ return NULL;
+
+ for (ptr_buffer = gui_buffers; ptr_buffer;
+ ptr_buffer = ptr_buffer->next_buffer)
+ {
+ if (buffer->layout_number <= ptr_buffer->number)
+ return ptr_buffer;
+ }
+
+ /* position not found, add to the end */
+ return NULL;
+}
+
+/*
+ * gui_buffer_insert: insert buffer in good position in list of buffers
+ */
+
+void
+gui_buffer_insert (struct t_gui_buffer *buffer)
+{
+ struct t_gui_buffer *pos, *ptr_buffer;
+
+ pos = gui_buffer_find_pos (buffer);
+ if (pos)
+ {
+ /* add buffer into the list (before position found) */
+ buffer->number = pos->number;
+ buffer->prev_buffer = pos->prev_buffer;
+ buffer->next_buffer = pos;
+ if (pos->prev_buffer)
+ (pos->prev_buffer)->next_buffer = buffer;
+ else
+ gui_buffers = buffer;
+ pos->prev_buffer = buffer;
+ for (ptr_buffer = pos; ptr_buffer;
+ ptr_buffer = ptr_buffer->next_buffer)
+ {
+ ptr_buffer->number++;
+ }
+ }
+ else
+ {
+ /* add buffer to the end */
+ buffer->number = (last_gui_buffer) ? last_gui_buffer->number + 1 : 1;
+ buffer->prev_buffer = last_gui_buffer;
+ if (gui_buffers)
+ last_gui_buffer->next_buffer = buffer;
+ else
+ gui_buffers = buffer;
+ last_gui_buffer = buffer;
+ buffer->next_buffer = NULL;
+ }
+}
+
+/*
* gui_buffer_new: create a new buffer in current window
*/
@@ -100,7 +166,9 @@ gui_buffer_new (struct t_weechat_plugin *plugin,
/* init buffer */
new_buffer->plugin = plugin;
new_buffer->plugin_name_for_upgrade = NULL;
- new_buffer->number = (last_gui_buffer) ? last_gui_buffer->number + 1 : 1;
+ /* number will be set later (when inserting buffer in list) */
+ new_buffer->layout_number = gui_layout_buffer_get_number ((plugin) ? plugin->name : "core",
+ name);
new_buffer->name = strdup (name);
new_buffer->type = GUI_BUFFER_TYPE_FORMATED;
new_buffer->notify = CONFIG_INTEGER(config_look_buffer_notify_default);
@@ -180,13 +248,7 @@ gui_buffer_new (struct t_weechat_plugin *plugin,
new_buffer->last_key = NULL;
/* add buffer to buffers list */
- new_buffer->prev_buffer = last_gui_buffer;
- if (gui_buffers)
- last_gui_buffer->next_buffer = new_buffer;
- else
- gui_buffers = new_buffer;
- last_gui_buffer = new_buffer;
- new_buffer->next_buffer = NULL;
+ gui_buffer_insert (new_buffer);
/* first buffer creation ? */
if (!gui_current_window->buffer)
@@ -197,9 +259,12 @@ gui_buffer_new (struct t_weechat_plugin *plugin,
gui_current_window->start_line_pos = 0;
gui_window_calculate_pos_size (gui_current_window, 1);
gui_window_switch_to_buffer (gui_current_window, new_buffer);
- gui_window_redraw_buffer (new_buffer);
}
+ /* check if this buffer should be assigned to a window,
+ according to windows layout saved */
+ gui_layout_window_check_buffer (new_buffer);
+
hook_signal_send ("buffer_open",
WEECHAT_HOOK_SIGNAL_POINTER, new_buffer);
}
@@ -576,7 +641,7 @@ gui_buffer_set (struct t_gui_buffer *buffer, const char *property,
else if (string_strcasecmp (property, "display") == 0)
{
gui_window_switch_to_buffer (gui_current_window, buffer);
- gui_window_redraw_buffer (buffer);
+ gui_status_refresh_needed = 1;
}
else if (string_strcasecmp (property, "name") == 0)
{
@@ -1010,7 +1075,7 @@ gui_buffer_switch_previous (struct t_gui_window *window)
else
gui_window_switch_to_buffer (window, last_gui_buffer);
- gui_window_redraw_buffer (window->buffer);
+ gui_status_refresh_needed = 1;
}
/*
@@ -1032,7 +1097,7 @@ gui_buffer_switch_next (struct t_gui_window *window)
else
gui_window_switch_to_buffer (window, gui_buffers);
- gui_window_redraw_buffer (window->buffer);
+ gui_status_refresh_needed = 1;
}
/*
@@ -1058,7 +1123,7 @@ gui_buffer_switch_by_number (struct t_gui_window *window, int number)
if ((ptr_buffer != window->buffer) && (number == ptr_buffer->number))
{
gui_window_switch_to_buffer (window, ptr_buffer);
- gui_window_redraw_buffer (window->buffer);
+ gui_status_refresh_needed = 1;
return;
}
}
@@ -1152,7 +1217,7 @@ gui_buffer_move_to_number (struct t_gui_buffer *buffer, int number)
ptr_buffer->number = i++;
}
- gui_window_redraw_buffer (buffer);
+ gui_status_refresh_needed = 1;
snprintf (buf1_str, sizeof (buf1_str) - 1, "%d", buffer->number);
argv[0] = buf1_str;
@@ -1388,12 +1453,17 @@ gui_buffer_print_log ()
log_printf ("");
log_printf ("[buffer (addr:0x%x)]", ptr_buffer);
log_printf (" plugin . . . . . . . . : 0x%x", ptr_buffer->plugin);
+ log_printf (" plugin_name_for_upgrade: '%s'", ptr_buffer->plugin_name_for_upgrade);
log_printf (" number . . . . . . . . : %d", ptr_buffer->number);
+ log_printf (" layout_number. . . . . : %d", ptr_buffer->layout_number);
log_printf (" name . . . . . . . . . : '%s'", ptr_buffer->name);
log_printf (" type . . . . . . . . . : %d", ptr_buffer->type);
log_printf (" notify . . . . . . . . : %d", ptr_buffer->notify);
log_printf (" num_displayed. . . . . : %d", ptr_buffer->num_displayed);
+ log_printf (" close_callback . . . . : 0x%x", ptr_buffer->close_callback);
+ log_printf (" close_callback_data. . : 0x%x", ptr_buffer->close_callback_data);
log_printf (" title. . . . . . . . . : '%s'", ptr_buffer->title);
+ log_printf (" title_refresh_needed . : %d", ptr_buffer->title_refresh_needed);
log_printf (" lines. . . . . . . . . : 0x%x", ptr_buffer->lines);
log_printf (" last_line. . . . . . . : 0x%x", ptr_buffer->last_line);
log_printf (" last_read_line . . . . : 0x%x", ptr_buffer->last_read_line);
@@ -1419,6 +1489,7 @@ gui_buffer_print_log ()
log_printf (" input_buffer_length. . : %d", ptr_buffer->input_buffer_length);
log_printf (" input_buffer_pos . . . : %d", ptr_buffer->input_buffer_pos);
log_printf (" input_buffer_1st_disp. : %d", ptr_buffer->input_buffer_1st_display);
+ log_printf (" input_refresh_needed . : %d", ptr_buffer->input_refresh_needed);
log_printf (" completion . . . . . . : 0x%x", ptr_buffer->completion);
log_printf (" history. . . . . . . . : 0x%x", ptr_buffer->history);
log_printf (" last_history . . . . . : 0x%x", ptr_buffer->last_history);
@@ -1429,8 +1500,11 @@ gui_buffer_print_log ()
log_printf (" text_search_found. . . : %d", ptr_buffer->text_search_found);
log_printf (" text_search_input. . . : '%s'", ptr_buffer->text_search_input);
log_printf (" highlight_words. . . . : '%s'", ptr_buffer->highlight_words);
+ log_printf (" highlight_tags . . . . : '%s'", ptr_buffer->highlight_tags);
log_printf (" highlight_tags_count . : %d", ptr_buffer->highlight_tags_count);
log_printf (" highlight_tags_array . : 0x%x", ptr_buffer->highlight_tags_array);
+ log_printf (" keys . . . . . . . . . : 0x%x", ptr_buffer->keys);
+ log_printf (" last_key . . . . . . . : 0x%x", ptr_buffer->last_key);
log_printf (" prev_buffer. . . . . . : 0x%x", ptr_buffer->prev_buffer);
log_printf (" next_buffer. . . . . . : 0x%x", ptr_buffer->next_buffer);
diff --git a/src/gui/gui-buffer.h b/src/gui/gui-buffer.h
index 3118aedb3..d293c8d44 100644
--- a/src/gui/gui-buffer.h
+++ b/src/gui/gui-buffer.h
@@ -76,6 +76,8 @@ struct t_gui_buffer
char *plugin_name_for_upgrade; /* plugin name when upgrading */
int number; /* buffer number (for jump/switch) */
+ int layout_number; /* the number of buffer saved in */
+ /* layout */
char *name; /* buffer name */
enum t_gui_buffer_type type; /* buffer type (formated, free, ..) */
int notify; /* 0 = never */
diff --git a/src/gui/gui-input.c b/src/gui/gui-input.c
index 359a1a1c4..7e99d6a73 100644
--- a/src/gui/gui-input.c
+++ b/src/gui/gui-input.c
@@ -1256,7 +1256,7 @@ gui_input_jump_smart ()
gui_window_switch_to_buffer (gui_current_window,
gui_hotlist->buffer);
gui_window_scroll_bottom (gui_current_window);
- gui_window_redraw_buffer (gui_current_window->buffer);
+ gui_status_refresh_needed = 1;
}
else
{
@@ -1265,7 +1265,7 @@ gui_input_jump_smart ()
gui_window_switch_to_buffer (gui_current_window,
gui_hotlist_initial_buffer);
gui_window_scroll_bottom (gui_current_window);
- gui_window_redraw_buffer (gui_current_window->buffer);
+ gui_status_refresh_needed = 1;
gui_hotlist_initial_buffer = NULL;
}
}
@@ -1315,7 +1315,7 @@ gui_input_hotlist_clear ()
if (gui_hotlist)
{
gui_hotlist_free_all (&gui_hotlist, &last_gui_hotlist);
- gui_window_redraw_buffer (gui_current_window->buffer);
+ gui_status_refresh_needed = 1;
}
gui_hotlist_initial_buffer = gui_current_window->buffer;
}
@@ -1377,7 +1377,7 @@ gui_input_set_unread ()
}
/* refresh all windows */
- gui_window_redraw_all_buffers ();
+ gui_window_refresh_needed = 1;
}
/*
@@ -1388,10 +1388,7 @@ void
gui_input_set_unread_current_buffer ()
{
if (gui_current_window)
- {
gui_buffer_set_unread (gui_current_window->buffer);
- gui_window_redraw_buffer (gui_current_window->buffer);
- }
}
/*
diff --git a/src/gui/gui-layout.c b/src/gui/gui-layout.c
new file mode 100644
index 000000000..33044f066
--- /dev/null
+++ b/src/gui/gui-layout.c
@@ -0,0 +1,624 @@
+/*
+ * Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
+ * See README for License detail, AUTHORS for developers list.
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/* gui-layout.c: layout functions, used by all GUI */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "../core/weechat.h"
+#include "../core/wee-log.h"
+#include "../core/wee-config.h"
+#include "../core/wee-string.h"
+#include "../plugins/plugin.h"
+#include "gui-layout.h"
+#include "gui-buffer.h"
+#include "gui-window.h"
+
+
+struct t_gui_layout_buffer *gui_layout_buffers = NULL;
+struct t_gui_layout_buffer *last_gui_layout_buffer = NULL;
+
+struct t_gui_layout_window *gui_layout_windows = NULL;
+
+int internal_id = 0;
+struct t_gui_window *window1 = NULL;
+struct t_gui_window *window2 = NULL;
+
+
+/*
+ * gui_layout_buffer_remove: remove a buffer layout
+ */
+
+void
+gui_layout_buffer_remove (struct t_gui_layout_buffer *layout_buffer)
+{
+ /* free data */
+ if (layout_buffer->plugin_name)
+ free (layout_buffer->plugin_name);
+ if (layout_buffer->buffer_name)
+ free (layout_buffer->buffer_name);
+
+ /* remove layout from list */
+ if (layout_buffer->prev_layout)
+ layout_buffer->prev_layout->next_layout = layout_buffer->next_layout;
+ if (layout_buffer->next_layout)
+ layout_buffer->next_layout->prev_layout = layout_buffer->prev_layout;
+ if (gui_layout_buffers == layout_buffer)
+ gui_layout_buffers = layout_buffer->next_layout;
+ if (last_gui_layout_buffer == layout_buffer)
+ last_gui_layout_buffer = layout_buffer->prev_layout;
+
+ free (layout_buffer);
+}
+
+/*
+ * gui_layout_buffer_remove_all: remove all buffer layouts
+ */
+
+void
+gui_layout_buffer_remove_all ()
+{
+ while (gui_layout_buffers)
+ {
+ gui_layout_buffer_remove (gui_layout_buffers);
+ }
+}
+
+/*
+ * gui_layout_buffer_reset: reset layout for buffers
+ */
+
+void
+gui_layout_buffer_reset ()
+{
+ struct t_gui_buffer *ptr_buffer;
+
+ gui_layout_buffer_remove_all ();
+
+ for (ptr_buffer = gui_buffers; ptr_buffer;
+ ptr_buffer = ptr_buffer->next_buffer)
+ {
+ ptr_buffer->layout_number = 0;
+ }
+}
+
+/*
+ * gui_layout_buffer_add: add a buffer layout
+ */
+
+struct t_gui_layout_buffer *
+gui_layout_buffer_add (const char *plugin_name, const char *buffer_name,
+ int number)
+{
+ struct t_gui_layout_buffer *new_layout_buffer;
+
+ new_layout_buffer = malloc (sizeof (*new_layout_buffer));
+ if (new_layout_buffer)
+ {
+ /* init layout buffer */
+ new_layout_buffer->plugin_name = strdup (plugin_name);
+ new_layout_buffer->buffer_name = strdup (buffer_name);
+ new_layout_buffer->number = number;
+
+ /* add layout buffer to list */
+ new_layout_buffer->prev_layout = last_gui_layout_buffer;
+ if (gui_layout_buffers)
+ last_gui_layout_buffer->next_layout = new_layout_buffer;
+ else
+ gui_layout_buffers = new_layout_buffer;
+ last_gui_layout_buffer = new_layout_buffer;
+ new_layout_buffer->next_layout = NULL;
+ }
+
+ return new_layout_buffer;
+}
+
+/*
+ * gui_layout_buffer_save: save current layout for buffers
+ */
+
+void
+gui_layout_buffer_save ()
+{
+ struct t_gui_buffer *ptr_buffer;
+
+ gui_layout_buffer_remove_all ();
+
+ for (ptr_buffer = gui_buffers; ptr_buffer;
+ ptr_buffer = ptr_buffer->next_buffer)
+ {
+ gui_layout_buffer_add ((ptr_buffer->plugin) ?
+ ptr_buffer->plugin->name : "core",
+ ptr_buffer->name,
+ ptr_buffer->number);
+ }
+}
+
+/*
+ * gui_layout_buffer_get_number: get number for a plugin/buffer
+ * return 0 if not found
+ */
+
+int
+gui_layout_buffer_get_number (const char *plugin_name, const char *buffer_name)
+{
+ struct t_gui_layout_buffer *ptr_layout_buffer;
+
+ for (ptr_layout_buffer = gui_layout_buffers; ptr_layout_buffer;
+ ptr_layout_buffer = ptr_layout_buffer->next_layout)
+ {
+ if ((string_strcasecmp (ptr_layout_buffer->plugin_name, plugin_name) == 0)
+ && (string_strcasecmp (ptr_layout_buffer->buffer_name, buffer_name) == 0))
+ {
+ return ptr_layout_buffer->number;
+ }
+ }
+
+ /* plugin/buffer not found */
+ return 0;
+}
+
+/*
+ * gui_layout_buffer_apply: apply current layout for buffers
+ */
+
+void
+gui_layout_buffer_apply ()
+{
+ struct t_gui_buffer *ptr_buffer;
+ char *plugin_core = "core", *plugin_name;
+
+ if (gui_layout_buffers)
+ {
+ for (ptr_buffer = gui_buffers; ptr_buffer;
+ ptr_buffer = ptr_buffer->next_buffer)
+ {
+ plugin_name = (ptr_buffer->plugin) ? ptr_buffer->plugin->name : plugin_core;
+ ptr_buffer->layout_number = gui_layout_buffer_get_number (plugin_name,
+ ptr_buffer->name);
+ if ((ptr_buffer->layout_number > 0)
+ && (ptr_buffer->layout_number != ptr_buffer->number))
+ {
+ gui_buffer_move_to_number (ptr_buffer,
+ ptr_buffer->layout_number);
+ }
+ }
+ }
+}
+
+/*
+ * gui_layout_window_remove: remove a window layout
+ */
+
+void
+gui_layout_window_remove (struct t_gui_layout_window *layout_window)
+{
+ /* first free childs */
+ if (layout_window->child1)
+ gui_layout_window_remove (layout_window->child1);
+ if (layout_window->child2)
+ gui_layout_window_remove (layout_window->child2);
+
+ /* free data */
+ if (layout_window->plugin_name)
+ free (layout_window->plugin_name);
+ if (layout_window->buffer_name)
+ free (layout_window->buffer_name);
+
+ free (layout_window);
+}
+
+/*
+ * gui_layout_window_remove_all: remove all window layouts
+ */
+
+void
+gui_layout_window_remove_all ()
+{
+ if (gui_layout_windows)
+ {
+ gui_layout_window_remove (gui_layout_windows);
+ gui_layout_windows = NULL;
+ }
+}
+
+/*
+ * gui_layout_window_reset: reset layout for windows
+ */
+
+void
+gui_layout_window_reset ()
+{
+ struct t_gui_window *ptr_win;
+
+ gui_layout_window_remove_all ();
+
+ for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window)
+ {
+ if (ptr_win->layout_plugin_name)
+ {
+ free (ptr_win->layout_plugin_name);
+ ptr_win->layout_plugin_name = NULL;
+ }
+ if (ptr_win->layout_buffer_name)
+ {
+ free (ptr_win->layout_buffer_name);
+ ptr_win->layout_buffer_name = NULL;
+ }
+ }
+}
+
+/*
+ * gui_layout_window_search_by_id_tree: search a layout window by internal id
+ * in a tree
+ */
+
+struct t_gui_layout_window *
+gui_layout_window_search_by_id_tree (struct t_gui_layout_window *tree, int id)
+{
+ struct t_gui_layout_window *res;
+
+ if (tree->internal_id == id)
+ return tree;
+
+ if (tree->child1)
+ {
+ res = gui_layout_window_search_by_id_tree (tree->child1, id);
+ if (res)
+ return res;
+ }
+
+ if (tree->child2)
+ {
+ res = gui_layout_window_search_by_id_tree (tree->child2, id);
+ if (res)
+ return res;
+ }
+
+ return NULL;
+}
+
+/*
+ * gui_layout_window_search_by_id: search a layout window by internal id
+ */
+
+struct t_gui_layout_window *
+gui_layout_window_search_by_id (int id)
+{
+ if (!gui_layout_windows)
+ return NULL;
+
+ return gui_layout_window_search_by_id_tree (gui_layout_windows, id);
+}
+
+/*
+ * gui_layout_window_add: add a window layout
+ */
+
+struct t_gui_layout_window *
+gui_layout_window_add (int internal_id,
+ struct t_gui_layout_window *parent,
+ int split_pct, int split_horiz,
+ const char *plugin_name, const char *buffer_name)
+{
+ struct t_gui_layout_window *new_layout_window;
+
+ new_layout_window = malloc (sizeof (*new_layout_window));
+ if (new_layout_window)
+ {
+ /* init layout window */
+ new_layout_window->internal_id = internal_id;
+ new_layout_window->parent_node = parent;
+ new_layout_window->split_pct = split_pct;
+ new_layout_window->split_horiz = split_horiz;
+ new_layout_window->child1 = NULL;
+ new_layout_window->child2 = NULL;
+ new_layout_window->plugin_name = (plugin_name) ? strdup (plugin_name) : NULL;
+ new_layout_window->buffer_name = (buffer_name) ? strdup (buffer_name) : NULL;
+
+ if (parent)
+ {
+ /* assign this window to child1 or child2 of parent */
+ if (!parent->child1)
+ parent->child1 = new_layout_window;
+ else if (!parent->child2)
+ parent->child2 = new_layout_window;
+ }
+ else
+ {
+ /* no parent? => it's root! */
+ gui_layout_windows = new_layout_window;
+ }
+ }
+
+ return new_layout_window;
+}
+
+/*
+ * gui_layout_window_save_tree: save tree of windows
+ */
+
+void
+gui_layout_window_save_tree (struct t_gui_layout_window *parent_layout,
+ struct t_gui_window_tree *tree)
+{
+ struct t_gui_layout_window *layout_window;
+
+ if (tree->window)
+ {
+ layout_window = gui_layout_window_add (internal_id++,
+ parent_layout,
+ 0, 0,
+ (tree->window->buffer->plugin) ?
+ tree->window->buffer->plugin->name : "core",
+ tree->window->buffer->name);
+ }
+ else
+ {
+ layout_window = gui_layout_window_add (internal_id++,
+ parent_layout,
+ tree->split_pct,
+ tree->split_horiz,
+ NULL,
+ NULL);
+ }
+
+ if (tree->child1)
+ gui_layout_window_save_tree (layout_window, tree->child1);
+
+ if (tree->child2)
+ gui_layout_window_save_tree (layout_window, tree->child2);
+}
+
+/*
+ * gui_layout_window_save: save current layout for windows
+ */
+
+void
+gui_layout_window_save ()
+{
+ gui_layout_window_remove_all ();
+
+ internal_id = 1;
+ gui_layout_window_save_tree (NULL, gui_windows_tree);
+}
+
+/*
+ * gui_layout_window_check_buffer: check if buffer can be assigned to one window
+ */
+
+void
+gui_layout_window_check_buffer (struct t_gui_buffer *buffer)
+{
+ struct t_gui_window *ptr_win;
+ char *plugin_core = "core", *plugin_name;
+
+ plugin_name = (buffer->plugin) ? buffer->plugin->name : plugin_core;
+
+ for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window)
+ {
+ if (ptr_win->layout_plugin_name && ptr_win->layout_buffer_name)
+ {
+ if ((strcmp (ptr_win->layout_plugin_name, plugin_name) == 0)
+ && (strcmp (ptr_win->layout_buffer_name, buffer->name) == 0))
+ {
+ gui_window_switch_to_buffer (ptr_win, buffer);
+ }
+ }
+ }
+}
+
+/*
+ * gui_layout_window_check_all_buffers: for each window, check if another
+ * buffer should be assigned, and if yes,
+ * assign it
+ */
+
+void
+gui_layout_window_check_all_buffers ()
+{
+ struct t_gui_window *ptr_win;
+ struct t_gui_buffer *ptr_buffer;
+ char *plugin_core = "core", *plugin_name;
+
+ for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window)
+ {
+ if (ptr_win->layout_plugin_name && ptr_win->layout_buffer_name)
+ {
+ for (ptr_buffer = gui_buffers; ptr_buffer;
+ ptr_buffer = ptr_buffer->next_buffer)
+ {
+ plugin_name = (ptr_buffer->plugin) ? ptr_buffer->plugin->name : plugin_core;
+
+ if ((strcmp (ptr_win->layout_plugin_name, plugin_name) == 0)
+ && (strcmp (ptr_win->layout_buffer_name, ptr_buffer->name) == 0))
+ {
+ gui_window_switch_to_buffer (ptr_win, ptr_buffer);
+ break;
+ }
+ }
+ }
+ }
+}
+
+/*
+ * gui_layout_window_apply_tree: apply tree windows (resplit screen according
+ * to windows tree and assing buffer to windows)
+ */
+
+void
+gui_layout_window_apply_tree (struct t_gui_layout_window *layout_window)
+{
+ struct t_gui_window *new_window;
+
+ if (layout_window->split_pct != 0)
+ {
+ /* node */
+ if (layout_window->split_horiz)
+ {
+ new_window = gui_window_split_horiz (gui_current_window,
+ layout_window->split_pct);
+ }
+ else
+ {
+ new_window = gui_window_split_vertic (gui_current_window,
+ layout_window->split_pct);
+ }
+
+ if (new_window)
+ {
+ if (window2)
+ window1 = window2;
+ window2 = new_window;
+ }
+ }
+ else
+ {
+ /* leaf */
+ if (window1)
+ {
+ gui_window_set_layout_plugin_name (window1,
+ layout_window->plugin_name);
+ gui_window_set_layout_buffer_name (window1,
+ layout_window->buffer_name);
+ window1 = window2;
+ window2 = NULL;
+ }
+ }
+
+ if (layout_window->child1)
+ gui_layout_window_apply_tree (layout_window->child1);
+
+ if (layout_window->child2)
+ gui_layout_window_apply_tree (layout_window->child2);
+}
+
+/*
+ * gui_layout_window_apply: apply current layout for windows
+ */
+
+void
+gui_layout_window_apply ()
+{
+ struct t_gui_window *old_window;
+
+ if (gui_layout_windows)
+ {
+ gui_window_merge_all (gui_current_window);
+
+ old_window = gui_current_window;
+ window1 = gui_current_window;
+ window2 = NULL;
+
+ gui_layout_window_apply_tree (gui_layout_windows);
+
+ gui_layout_window_check_all_buffers ();
+
+ gui_window_switch (old_window);
+ }
+}
+
+/*
+ * gui_layout_save_on_exit: save layout according to option
+ * "save_layout_on_exit"
+ */
+
+void
+gui_layout_save_on_exit ()
+{
+ /* save layout on exit */
+ switch (CONFIG_BOOLEAN(config_look_save_layout_on_exit))
+ {
+ case CONFIG_LOOK_SAVE_LAYOUT_ON_EXIT_NONE:
+ break;
+ case CONFIG_LOOK_SAVE_LAYOUT_ON_EXIT_BUFFERS:
+ gui_layout_buffer_save ();
+ break;
+ case CONFIG_LOOK_SAVE_LAYOUT_ON_EXIT_WINDOWS:
+ gui_layout_window_save ();
+ break;
+ case CONFIG_LOOK_SAVE_LAYOUT_ON_EXIT_ALL:
+ gui_layout_buffer_save ();
+ gui_layout_window_save ();
+ break;
+ }
+}
+
+/*
+ * gui_layout_print_log_window: print windows layout infos in log (usually for
+ * crash dump)
+ */
+
+void
+gui_layout_print_log_window (struct t_gui_layout_window *layout_window,
+ int level)
+{
+ log_printf ("");
+ log_printf ("[layout window (addr:0x%x) (%s) (level %d)]",
+ layout_window,
+ (layout_window->plugin_name) ? "leaf" : "node",
+ level);
+
+ log_printf (" internal_id. . . . . . : %d", layout_window->internal_id);
+ log_printf (" parent_node. . . . . . : 0x%x", layout_window->parent_node);
+ log_printf (" split_pct. . . . . . . : %d", layout_window->split_pct);
+ log_printf (" split_horiz. . . . . . : %d", layout_window->split_horiz);
+ log_printf (" child1 . . . . . . . . : 0x%x", layout_window->child1);
+ log_printf (" child2 . . . . . . . . : 0x%x", layout_window->child2);
+ log_printf (" plugin_name. . . . . . : '%s'", layout_window->plugin_name);
+ log_printf (" buffer_name. . . . . . : '%s'", layout_window->buffer_name);
+
+ if (layout_window->child1)
+ gui_layout_print_log_window (layout_window->child1, level + 1);
+
+ if (layout_window->child2)
+ gui_layout_print_log_window (layout_window->child2, level + 1);
+}
+
+/*
+ * gui_layout_print_log: print layout infos in log (usually for crash dump)
+ */
+
+void
+gui_layout_print_log ()
+{
+ struct t_gui_layout_buffer *ptr_layout_buffer;
+
+ log_printf ("");
+
+ for (ptr_layout_buffer = gui_layout_buffers; ptr_layout_buffer;
+ ptr_layout_buffer = ptr_layout_buffer->next_layout)
+ {
+ log_printf ("");
+ log_printf ("[layout buffer (addr:0x%x)]", ptr_layout_buffer);
+ log_printf (" plugin_name. . . . . . : '%s'", ptr_layout_buffer->plugin_name);
+ log_printf (" buffer_name. . . . . . : '%s'", ptr_layout_buffer->buffer_name);
+ log_printf (" number . . . . . . . . : %d", ptr_layout_buffer->number);
+ log_printf (" prev_layout. . . . . . : 0x%x", ptr_layout_buffer->prev_layout);
+ log_printf (" next_layout. . . . . . : 0x%x", ptr_layout_buffer->next_layout);
+ }
+
+ if (gui_layout_windows)
+ gui_layout_print_log_window (gui_layout_windows, 0);
+}
diff --git a/src/gui/gui-layout.h b/src/gui/gui-layout.h
new file mode 100644
index 000000000..d4cf705ff
--- /dev/null
+++ b/src/gui/gui-layout.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
+ * See README for License detail, AUTHORS for developers list.
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __WEECHAT_GUI_LAYOUT_H
+#define __WEECHAT_GUI_LAYOUT_H 1
+
+/* layout structures */
+
+struct t_gui_layout_buffer
+{
+ char *plugin_name;
+ char *buffer_name;
+ int number;
+ struct t_gui_layout_buffer *prev_layout; /* link to previous layout */
+ struct t_gui_layout_buffer *next_layout; /* link to next layout */
+};
+
+struct t_gui_layout_window
+{
+ int internal_id; /* used to save/read layout from */
+ /* config (to find parent) */
+ struct t_gui_layout_window *parent_node; /* pointer to parent node */
+
+ /* node info */
+ int split_pct; /* % of split size (child1) */
+ int split_horiz; /* 1 if horizontal, 0 if vertical */
+ struct t_gui_layout_window *child1; /* first child, NULL if a leaf */
+ struct t_gui_layout_window *child2; /* second child, NULL if leaf */
+
+ /* leaf info */
+ char *plugin_name;
+ char *buffer_name;
+};
+
+/* layout variables */
+
+extern struct t_gui_layout_buffer *gui_layout_buffers;
+extern struct t_gui_layout_buffer *gui_layout_last_buffer;
+extern struct t_gui_layout_window *gui_layout_windows;
+
+/* layout functions */
+
+extern void gui_layout_buffer_reset ();
+extern struct t_gui_layout_buffer *gui_layout_buffer_add (const char *plugin_name,
+ const char *buffer_name,
+ int number);
+extern void gui_layout_buffer_save ();
+extern int gui_layout_buffer_get_number (const char *plugin_name,
+ const char *buffer_name);
+extern void gui_layout_buffer_apply ();
+
+extern void gui_layout_window_reset ();
+extern struct t_gui_layout_window *gui_layout_window_search_by_id (int id);
+extern struct t_gui_layout_window *gui_layout_window_add (int internal_id,
+ struct t_gui_layout_window *parent,
+ int split_pct,
+ int split_horiz,
+ const char *plugin_name,
+ const char *buffer_name);
+extern void gui_layout_window_save ();
+extern void gui_layout_window_apply ();
+extern void gui_layout_window_check_buffer (struct t_gui_buffer *buffer);
+
+extern void gui_layout_save_on_exit ();
+
+extern void gui_layout_print_log ();
+
+#endif /* gui-layout.h */
diff --git a/src/gui/gui-nicklist.h b/src/gui/gui-nicklist.h
index 687109731..23c441e90 100644
--- a/src/gui/gui-nicklist.h
+++ b/src/gui/gui-nicklist.h
@@ -86,6 +86,6 @@ extern void gui_nicklist_print_log (struct t_gui_nick_group *group, int indent);
/* nicklist functions (GUI dependent) */
-extern void gui_nicklist_draw (struct t_gui_buffer *buffer, int erase);
+extern int gui_nicklist_draw (struct t_gui_buffer *buffer, int erase);
#endif /* gui-nicklist.h */
diff --git a/src/gui/gui-window.c b/src/gui/gui-window.c
index 6907d337f..b7dbbfead 100644
--- a/src/gui/gui-window.c
+++ b/src/gui/gui-window.c
@@ -73,8 +73,8 @@ gui_window_tree_init (struct t_gui_window *window)
if (!gui_windows_tree)
return 0;
gui_windows_tree->parent_node = NULL;
- gui_windows_tree->split_horiz = 0;
gui_windows_tree->split_pct = 0;
+ gui_windows_tree->split_horiz = 0;
gui_windows_tree->child1 = NULL;
gui_windows_tree->child2 = NULL;
gui_windows_tree->window = window;
@@ -90,8 +90,8 @@ void
gui_window_tree_node_to_leaf (struct t_gui_window_tree *node,
struct t_gui_window *window)
{
- node->split_horiz = 0;
node->split_pct = 0;
+ node->split_horiz = 0;
if (node->child1)
{
free (node->child1);
@@ -201,6 +201,7 @@ gui_window_new (struct t_gui_window *parent, int x, int y, int width, int height
return NULL;
}
+ /* position & size */
new_window->win_x = x;
new_window->win_y = y;
new_window->win_width = width;
@@ -212,42 +213,52 @@ gui_window_new (struct t_gui_window *parent, int x, int y, int width, int height
new_window->new_y = -1;
new_window->new_width = -1;
new_window->new_height = -1;
-
+
+ /* chat window */
new_window->win_chat_x = 0;
new_window->win_chat_y = 0;
new_window->win_chat_width = 0;
new_window->win_chat_height = 0;
new_window->win_chat_cursor_x = 0;
new_window->win_chat_cursor_y = 0;
-
+
+ /* nicklist */
new_window->win_nick_x = 0;
new_window->win_nick_y = 0;
new_window->win_nick_width = 0;
new_window->win_nick_height = 0;
new_window->win_nick_num_max = 0;
new_window->win_nick_start = 0;
-
+
+ /* title */
new_window->win_title_x = 0;
new_window->win_title_y = 0;
new_window->win_title_width = 0;
new_window->win_title_height = 0;
new_window->win_title_start = 0;
-
+
+ /* status */
new_window->win_status_x = 0;
new_window->win_status_y = 0;
new_window->win_status_width = 0;
new_window->win_status_height = 0;
-
+
+ /* input */
new_window->win_input_x = 0;
new_window->win_input_y = 0;
new_window->win_input_width = 0;
new_window->win_input_height = 0;
new_window->win_input_cursor_x = 0;
+ /* refresh */
new_window->refresh_needed = 0;
+ /* buffer and layout infos */
new_window->buffer = NULL;
+ new_window->layout_plugin_name = NULL;
+ new_window->layout_buffer_name = NULL;
+ /* scroll */
new_window->first_line_displayed = 0;
new_window->start_line = NULL;
new_window->start_line_pos = 0;
@@ -355,6 +366,42 @@ gui_window_get_pointer (struct t_gui_window *window, const char *property)
}
/*
+ * gui_window_set_layout_plugin_name: set layout plugin name for window
+ */
+
+void
+gui_window_set_layout_plugin_name (struct t_gui_window *window,
+ const char *plugin_name)
+{
+ if (window->layout_plugin_name)
+ {
+ free (window->layout_plugin_name);
+ window->layout_plugin_name = NULL;
+ }
+
+ if (plugin_name)
+ window->layout_plugin_name = strdup (plugin_name);
+}
+
+/*
+ * gui_window_set_layout_buffer_name: set layout buffer name for window
+ */
+
+void
+gui_window_set_layout_buffer_name (struct t_gui_window *window,
+ const char *buffer_name)
+{
+ if (window->layout_buffer_name)
+ {
+ free (window->layout_buffer_name);
+ window->layout_buffer_name = NULL;
+ }
+
+ if (buffer_name)
+ window->layout_buffer_name = strdup (buffer_name);
+}
+
+/*
* gui_window_free: delete a window
*/
@@ -412,50 +459,6 @@ gui_window_search_by_buffer (struct t_gui_buffer *buffer)
}
/*
- * gui_window_switch_server: switch server on servers buffer
- * (if same buffer is used for all buffers)
- */
-
-void
-gui_window_switch_server (struct t_gui_window *window)
-{
- (void) window;
- /*struct t_gui_buffer *ptr_buffer;
- t_irc_server *ptr_server;
-
- ptr_buffer = gui_buffer_servers_search ();
-
- if (ptr_buffer)
- {
- ptr_server = (GUI_SERVER(ptr_buffer)
- && GUI_SERVER(ptr_buffer)->next_server) ?
- GUI_SERVER(ptr_buffer)->next_server : irc_servers;
- while (ptr_server != GUI_SERVER(window->buffer))
- {
- if (ptr_server->buffer)
- break;
- if (ptr_server->next_server)
- ptr_server = ptr_server->next_server;
- else
- {
- if (GUI_SERVER(ptr_buffer) == NULL)
- {
- ptr_server = NULL;
- break;
- }
- ptr_server = irc_servers;
- }
- }
- if (ptr_server && (ptr_server != GUI_SERVER(ptr_buffer)))
- {
- ptr_buffer->server = ptr_server;
- gui_status_draw (window->buffer, 1);
- gui_input_draw (window->buffer, 1);
- }
- }*/
-}
-
-/*
* gui_window_switch_previous: switch to previous window
*/
@@ -1067,6 +1070,8 @@ gui_window_print_log ()
log_printf (" win_input_height. . : %d", ptr_window->win_input_height);
log_printf (" win_input_cursor_x. : %d", ptr_window->win_input_cursor_x);
log_printf (" buffer. . . . . . . : 0x%x", ptr_window->buffer);
+ log_printf (" layout_plugin_name. : '%s'", ptr_window->layout_plugin_name);
+ log_printf (" layout_buffer_name. : '%s'", ptr_window->layout_buffer_name);
log_printf (" first_line_displayed: %d", ptr_window->first_line_displayed);
log_printf (" start_line. . . . . : 0x%x", ptr_window->start_line);
log_printf (" start_line_pos. . . : %d", ptr_window->start_line_pos);
diff --git a/src/gui/gui-window.h b/src/gui/gui-window.h
index 441a54a1e..4f4fc7ea5 100644
--- a/src/gui/gui-window.h
+++ b/src/gui/gui-window.h
@@ -78,9 +78,15 @@ struct t_gui_window
/* GUI specific objects */
void *gui_objects; /* pointer to a GUI specific struct */
-
+
+ /* buffer and layout infos */
struct t_gui_buffer *buffer; /* buffer currently displayed */
+ char *layout_plugin_name; /* plugin and buffer that should be */
+ char *layout_buffer_name; /* displayed in this window (even if */
+ /* buffer does not exist yet, it will*/
+ /* be assigned later) */
+ /* scroll */
int first_line_displayed; /* = 1 if first line is displayed */
struct t_gui_line *start_line; /* pointer to line if scrolling */
int start_line_pos; /* position in first line displayed */
@@ -98,10 +104,10 @@ struct t_gui_window_tree
struct t_gui_window_tree *parent_node; /* pointer to parent node */
/* node info */
- int split_horiz; /* 1 if horizontal, 0 if vertical */
int split_pct; /* % of split size (child1) */
- struct t_gui_window_tree *child1; /* first child, NULL if a leaf */
- struct t_gui_window_tree *child2; /* second child, NULL if a leaf */
+ int split_horiz; /* 1 if horizontal, 0 if vertical */
+ struct t_gui_window_tree *child1; /* first child, NULL if a leaf */
+ struct t_gui_window_tree *child2; /* second child, NULL if a leaf */
/* leaf info */
struct t_gui_window *window; /* pointer to window, NULL if a node */
@@ -129,6 +135,10 @@ extern char *gui_window_get_string (struct t_gui_window *window,
const char *property);
extern void *gui_window_get_pointer (struct t_gui_window *window,
const char *property);
+extern void gui_window_set_layout_plugin_name (struct t_gui_window *window,
+ const char *plugin_name);
+extern void gui_window_set_layout_buffer_name (struct t_gui_window *window,
+ const char *buffer_name);
extern void gui_window_free (struct t_gui_window *window);
extern struct t_gui_window *gui_window_search_by_buffer (struct t_gui_buffer *buffer);
extern void gui_window_switch_server (struct t_gui_window *window);
@@ -157,8 +167,6 @@ extern void gui_window_objects_free (struct t_gui_window *window,
int free_bar_windows);
extern int gui_window_calculate_pos_size (struct t_gui_window *window,
int force_calculate);
-extern void gui_window_redraw_buffer (struct t_gui_buffer *buffer);
-extern void gui_window_redraw_all_buffers ();
extern void gui_window_switch_to_buffer (struct t_gui_window *window,
struct t_gui_buffer *buffer);
extern void gui_window_switch (struct t_gui_window *window);
@@ -176,10 +184,10 @@ extern void gui_window_nicklist_beginning (struct t_gui_window *window);
extern void gui_window_nicklist_end (struct t_gui_window *window);
extern void gui_window_init_subwindows (struct t_gui_window *window);
extern void gui_window_refresh_windows ();
-extern void gui_window_split_horiz (struct t_gui_window *window,
- int percentage);
-extern void gui_window_split_vertic (struct t_gui_window *window,
- int percentage);
+extern struct t_gui_window *gui_window_split_horiz (struct t_gui_window *window,
+ int percentage);
+extern struct t_gui_window *gui_window_split_vertic (struct t_gui_window *window,
+ int percentage);
extern void gui_window_resize (struct t_gui_window *window, int percentage);
extern int gui_window_merge (struct t_gui_window *window);
extern void gui_window_merge_all (struct t_gui_window *window);