2000-04-26 08:03:38 +00:00
|
|
|
/*
|
|
|
|
|
window-items.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 "modules.h"
|
|
|
|
|
#include "signals.h"
|
2000-08-26 15:39:44 +00:00
|
|
|
#include "servers.h"
|
2000-04-26 08:03:38 +00:00
|
|
|
#include "settings.h"
|
|
|
|
|
|
|
|
|
|
#include "levels.h"
|
|
|
|
|
|
2000-11-17 16:27:14 +00:00
|
|
|
#include "fe-windows.h"
|
2000-04-26 08:03:38 +00:00
|
|
|
#include "window-items.h"
|
2000-10-28 20:14:19 +00:00
|
|
|
#include "printtext.h"
|
2000-04-26 08:03:38 +00:00
|
|
|
|
2000-12-02 19:08:21 +00:00
|
|
|
void window_item_add(WINDOW_REC *window, WI_ITEM_REC *item, int automatic)
|
2000-04-26 08:03:38 +00:00
|
|
|
{
|
|
|
|
|
g_return_if_fail(window != NULL);
|
|
|
|
|
g_return_if_fail(item != NULL);
|
|
|
|
|
|
2001-01-01 07:45:54 +00:00
|
|
|
item->window = window;
|
2000-04-26 08:03:38 +00:00
|
|
|
|
|
|
|
|
if (window->items == NULL) {
|
|
|
|
|
window->active = item;
|
|
|
|
|
window->active_server = item->server;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!automatic || settings_get_bool("window_auto_change")) {
|
|
|
|
|
if (automatic)
|
|
|
|
|
signal_emit("window changed automatic", 1, window);
|
|
|
|
|
window_set_active(window);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
window->items = g_slist_append(window->items, item);
|
|
|
|
|
signal_emit("window item new", 2, window, item);
|
|
|
|
|
|
2001-08-08 15:29:56 +00:00
|
|
|
if (g_slist_length(window->items) == 1 ||
|
|
|
|
|
(!automatic && settings_get_bool("autofocus_new_items"))) {
|
2000-04-26 08:03:38 +00:00
|
|
|
window->active = NULL;
|
|
|
|
|
window_item_set_active(window, item);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-01-06 21:58:28 +00:00
|
|
|
void window_item_remove(WI_ITEM_REC *item)
|
2000-04-26 08:03:38 +00:00
|
|
|
{
|
2001-01-06 21:58:28 +00:00
|
|
|
WINDOW_REC *window;
|
|
|
|
|
|
2000-04-26 08:03:38 +00:00
|
|
|
g_return_if_fail(item != NULL);
|
|
|
|
|
|
2001-01-06 21:58:28 +00:00
|
|
|
window = window_item_window(item);
|
|
|
|
|
|
2001-07-26 01:49:08 +00:00
|
|
|
if (window == NULL)
|
2000-04-26 08:03:38 +00:00
|
|
|
return;
|
|
|
|
|
|
2001-01-01 07:45:54 +00:00
|
|
|
item->window = NULL;
|
2000-04-26 08:03:38 +00:00
|
|
|
window->items = g_slist_remove(window->items, item);
|
|
|
|
|
|
|
|
|
|
if (window->active == item) {
|
2000-06-01 17:08:30 +00:00
|
|
|
window_item_set_active(window, window->items == NULL ? NULL :
|
|
|
|
|
window->items->data);
|
2000-04-26 08:03:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
signal_emit("window item remove", 2, window, item);
|
|
|
|
|
}
|
|
|
|
|
|
2001-01-06 21:58:28 +00:00
|
|
|
void window_item_destroy(WI_ITEM_REC *item)
|
2000-12-02 19:08:21 +00:00
|
|
|
{
|
2001-01-06 21:58:28 +00:00
|
|
|
WINDOW_REC *window;
|
|
|
|
|
|
|
|
|
|
window = window_item_window(item);
|
|
|
|
|
window_item_remove(item);
|
2001-07-26 01:49:08 +00:00
|
|
|
item->destroy(item);
|
2000-12-02 19:08:21 +00:00
|
|
|
}
|
|
|
|
|
|
2000-04-26 08:03:38 +00:00
|
|
|
void window_item_change_server(WI_ITEM_REC *item, void *server)
|
|
|
|
|
{
|
|
|
|
|
WINDOW_REC *window;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail(item != NULL);
|
|
|
|
|
|
2001-01-01 17:07:08 +00:00
|
|
|
window = window_item_window(item);
|
2000-04-26 08:03:38 +00:00
|
|
|
item->server = server;
|
|
|
|
|
|
|
|
|
|
signal_emit("window item server changed", 2, window, item);
|
|
|
|
|
if (window->active == item) window_change_server(window, item->server);
|
|
|
|
|
}
|
|
|
|
|
|
2000-05-15 08:25:45 +00:00
|
|
|
void window_item_set_active(WINDOW_REC *window, WI_ITEM_REC *item)
|
|
|
|
|
{
|
2000-12-02 06:08:31 +00:00
|
|
|
g_return_if_fail(window != NULL);
|
|
|
|
|
|
|
|
|
|
if (item != NULL && window_item_window(item) != window) {
|
|
|
|
|
/* move item to different window */
|
2001-01-06 21:58:28 +00:00
|
|
|
window_item_remove(item);
|
2000-12-02 19:08:21 +00:00
|
|
|
window_item_add(window, item, FALSE);
|
2000-12-02 06:08:31 +00:00
|
|
|
}
|
2000-05-15 08:25:45 +00:00
|
|
|
|
|
|
|
|
if (window->active != item) {
|
|
|
|
|
window->active = item;
|
2001-02-10 02:13:13 +00:00
|
|
|
if (item != NULL && window->active_server != item->server)
|
|
|
|
|
window_change_server(window, item->server);
|
2000-05-15 08:25:45 +00:00
|
|
|
signal_emit("window item changed", 2, window, item);
|
|
|
|
|
}
|
|
|
|
|
}
|
2000-06-12 22:57:53 +00:00
|
|
|
|
|
|
|
|
/* Return TRUE if `item' is the active window item in the window.
|
|
|
|
|
`item' can be NULL. */
|
|
|
|
|
int window_item_is_active(WI_ITEM_REC *item)
|
|
|
|
|
{
|
|
|
|
|
WINDOW_REC *window;
|
|
|
|
|
|
|
|
|
|
if (item == NULL)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
window = window_item_window(item);
|
|
|
|
|
if (window == NULL)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
return window->active == item;
|
|
|
|
|
}
|
2000-05-15 08:25:45 +00:00
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2000-12-02 06:08:31 +00:00
|
|
|
WI_ITEM_REC *window_item_find_window(WINDOW_REC *window,
|
|
|
|
|
void *server, const char *name)
|
2000-04-26 08:03:38 +00:00
|
|
|
{
|
|
|
|
|
GSList *tmp;
|
|
|
|
|
|
|
|
|
|
for (tmp = window->items; tmp != NULL; tmp = tmp->next) {
|
|
|
|
|
WI_ITEM_REC *rec = tmp->data;
|
|
|
|
|
|
|
|
|
|
if ((server == NULL || rec->server == server) &&
|
|
|
|
|
g_strcasecmp(name, rec->name) == 0) return rec;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Find wanted window item by name. `server' can be NULL. */
|
|
|
|
|
WI_ITEM_REC *window_item_find(void *server, const char *name)
|
|
|
|
|
{
|
|
|
|
|
WI_ITEM_REC *item;
|
|
|
|
|
GSList *tmp;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail(name != NULL, NULL);
|
|
|
|
|
|
|
|
|
|
for (tmp = windows; tmp != NULL; tmp = tmp->next) {
|
|
|
|
|
WINDOW_REC *rec = tmp->data;
|
|
|
|
|
|
|
|
|
|
item = window_item_find_window(rec, server, name);
|
|
|
|
|
if (item != NULL) return item;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2001-02-22 05:49:30 +00:00
|
|
|
static int window_bind_has_sticky(WINDOW_REC *window)
|
|
|
|
|
{
|
|
|
|
|
GSList *tmp;
|
|
|
|
|
|
|
|
|
|
for (tmp = window->bound_items; tmp != NULL; tmp = tmp->next) {
|
|
|
|
|
WINDOW_BIND_REC *rec = tmp->data;
|
|
|
|
|
|
|
|
|
|
if (rec->sticky)
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2000-04-26 08:03:38 +00:00
|
|
|
void window_item_create(WI_ITEM_REC *item, int automatic)
|
|
|
|
|
{
|
|
|
|
|
WINDOW_REC *window;
|
2001-08-08 16:08:47 +00:00
|
|
|
WINDOW_BIND_REC *bind;
|
2001-01-01 14:57:55 +00:00
|
|
|
GSList *tmp, *sorted;
|
2000-06-17 12:22:56 +00:00
|
|
|
int clear_waiting, reuse_unused_windows;
|
2000-04-26 08:03:38 +00:00
|
|
|
|
|
|
|
|
g_return_if_fail(item != NULL);
|
|
|
|
|
|
2001-07-28 23:40:00 +00:00
|
|
|
reuse_unused_windows = settings_get_bool("reuse_unused_windows");
|
2000-06-17 12:22:56 +00:00
|
|
|
|
2000-06-11 20:04:15 +00:00
|
|
|
clear_waiting = TRUE;
|
2000-04-26 08:03:38 +00:00
|
|
|
window = NULL;
|
2001-01-01 14:57:55 +00:00
|
|
|
sorted = windows_get_sorted();
|
|
|
|
|
for (tmp = sorted; tmp != NULL; tmp = tmp->next) {
|
2000-04-26 08:03:38 +00:00
|
|
|
WINDOW_REC *rec = tmp->data;
|
|
|
|
|
|
2001-02-10 09:12:53 +00:00
|
|
|
/* is item bound to this window? */
|
2001-08-08 16:08:47 +00:00
|
|
|
if (item->server != NULL) {
|
|
|
|
|
bind = window_bind_find(rec, item->server->tag,
|
|
|
|
|
item->name);
|
|
|
|
|
if (bind != NULL) {
|
|
|
|
|
if (!bind->sticky)
|
|
|
|
|
window_bind_destroy(rec, bind);
|
|
|
|
|
window = rec;
|
|
|
|
|
clear_waiting = FALSE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2000-04-26 08:03:38 +00:00
|
|
|
}
|
2001-02-22 05:49:30 +00:00
|
|
|
|
|
|
|
|
/* use this window IF:
|
|
|
|
|
- reuse_unused_windows is ON
|
|
|
|
|
- window has no existing items
|
2001-05-11 14:32:57 +00:00
|
|
|
- window has no name
|
2001-02-22 05:49:30 +00:00
|
|
|
- window has no sticky binds (/LAYOUT SAVEd)
|
|
|
|
|
- we already haven't found "good enough" window,
|
|
|
|
|
except if
|
|
|
|
|
- this is the active window
|
|
|
|
|
- old window had some temporary bounds and this
|
|
|
|
|
one doesn't
|
|
|
|
|
*/
|
|
|
|
|
if (reuse_unused_windows && rec->items == NULL &&
|
2001-05-11 14:32:57 +00:00
|
|
|
rec->name == NULL && !window_bind_has_sticky(rec) &&
|
2001-02-22 05:49:30 +00:00
|
|
|
(window == NULL || rec == active_win ||
|
|
|
|
|
window->bound_items != NULL))
|
|
|
|
|
window = rec;
|
2000-04-26 08:03:38 +00:00
|
|
|
}
|
2001-01-01 14:57:55 +00:00
|
|
|
g_slist_free(sorted);
|
2000-12-02 22:07:24 +00:00
|
|
|
|
|
|
|
|
if (window == NULL && !settings_get_bool("autocreate_windows")) {
|
|
|
|
|
/* never create new windows automatically */
|
|
|
|
|
window = active_win;
|
|
|
|
|
}
|
2000-04-26 08:03:38 +00:00
|
|
|
|
|
|
|
|
if (window == NULL) {
|
|
|
|
|
/* create new window to use */
|
|
|
|
|
window = window_create(item, automatic);
|
|
|
|
|
} else {
|
|
|
|
|
/* use existing window */
|
2000-12-02 19:08:21 +00:00
|
|
|
window_item_add(window, item, automatic);
|
2000-04-26 08:03:38 +00:00
|
|
|
}
|
2000-06-11 20:04:15 +00:00
|
|
|
|
2001-02-10 09:12:53 +00:00
|
|
|
if (clear_waiting)
|
|
|
|
|
window_bind_remove_unsticky(window);
|
2000-04-26 08:03:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void signal_window_item_changed(WINDOW_REC *window, WI_ITEM_REC *item)
|
|
|
|
|
{
|
|
|
|
|
g_return_if_fail(window != NULL);
|
|
|
|
|
|
|
|
|
|
if (g_slist_length(window->items) > 1) {
|
|
|
|
|
/* default to printing "talking with ...",
|
|
|
|
|
you can override it it you wish */
|
|
|
|
|
printformat(item->server, item->name, MSGLEVEL_CLIENTNOTICE,
|
2001-01-07 19:42:59 +00:00
|
|
|
TXT_TALKING_WITH, item->name);
|
2000-04-26 08:03:38 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void window_items_init(void)
|
|
|
|
|
{
|
2000-06-17 12:22:56 +00:00
|
|
|
settings_add_bool("lookandfeel", "reuse_unused_windows", FALSE);
|
2000-12-02 22:07:24 +00:00
|
|
|
settings_add_bool("lookandfeel", "autocreate_windows", TRUE);
|
2001-08-08 15:29:56 +00:00
|
|
|
settings_add_bool("lookandfeel", "autofocus_new_items", TRUE);
|
2000-06-11 20:21:12 +00:00
|
|
|
|
2000-04-26 08:03:38 +00:00
|
|
|
signal_add_last("window item changed", (SIGNAL_FUNC) signal_window_item_changed);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void window_items_deinit(void)
|
|
|
|
|
{
|
|
|
|
|
signal_remove("window item changed", (SIGNAL_FUNC) signal_window_item_changed);
|
|
|
|
|
}
|