1
0
mirror of https://github.com/irssi/irssi.git synced 2024-12-04 14:46:39 -05:00
irssi/src/fe-common/core/window-items.c
Timo Sirainen d346fbe1a9 Better !channel support - window items now have "visual_name" and channels
and queries also have "name". Normally they're identical but with !channels
the visible_name contains the short !channel name, while name contains
full !ABCDEchannel name.

The visible_name should be used whenever displaying the channel name, or as
printtext()'s target. So, this breaks a few scripts in !channels, they need
to be modified to use $channel->{visible_name} instead.

Also /LAYOUT SAVE should finally work properly with !channels.


git-svn-id: http://svn.irssi.org/repos/irssi/trunk@2797 dbcabf3a-b0e7-0310-adc4-f8d773084564
2002-05-16 00:34:37 +00:00

348 lines
8.6 KiB
C

/*
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"
#include "servers.h"
#include "channels.h"
#include "settings.h"
#include "levels.h"
#include "fe-windows.h"
#include "window-items.h"
#include "printtext.h"
void window_item_add(WINDOW_REC *window, WI_ITEM_REC *item, int automatic)
{
g_return_if_fail(window != NULL);
g_return_if_fail(item != NULL);
g_return_if_fail(item->window == NULL);
item->window = window;
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);
if (g_slist_length(window->items) == 1 ||
(!automatic && settings_get_bool("autofocus_new_items"))) {
window->active = NULL;
window_item_set_active(window, item);
}
}
void window_item_remove(WI_ITEM_REC *item)
{
WINDOW_REC *window;
g_return_if_fail(item != NULL);
window = window_item_window(item);
if (window == NULL)
return;
item->window = NULL;
window->items = g_slist_remove(window->items, item);
if (window->active == item) {
window_item_set_active(window, window->items == NULL ? NULL :
window->items->data);
}
signal_emit("window item remove", 2, window, item);
}
void window_item_destroy(WI_ITEM_REC *item)
{
WINDOW_REC *window;
window = window_item_window(item);
window_item_remove(item);
item->destroy(item);
}
void window_item_change_server(WI_ITEM_REC *item, void *server)
{
WINDOW_REC *window;
g_return_if_fail(item != NULL);
window = window_item_window(item);
item->server = server;
signal_emit("window item server changed", 2, window, item);
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 (item != NULL && window_item_window(item) != window) {
/* move item to different window */
window_item_remove(item);
window_item_add(window, item, FALSE);
}
if (window->active != item) {
window->active = item;
if (item != NULL && window->active_server != item->server)
window_change_server(window, item->server);
signal_emit("window item changed", 2, window, item);
}
}
/* 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;
}
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);
}
WI_ITEM_REC *window_item_find_window(WINDOW_REC *window,
void *server, const char *name)
{
CHANNEL_REC *channel;
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->visible_name) == 0)
return rec;
}
/* try with channel name too, it's not necessarily
same as visible_name (!channels) */
channel = channel_find(server, name);
if (channel != NULL && window_item_window(channel) == window)
return (WI_ITEM_REC *) channel;
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;
}
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;
}
void window_item_create(WI_ITEM_REC *item, int automatic)
{
WINDOW_REC *window;
WINDOW_BIND_REC *bind;
GSList *tmp, *sorted;
int clear_waiting, reuse_unused_windows;
g_return_if_fail(item != NULL);
reuse_unused_windows = settings_get_bool("reuse_unused_windows");
clear_waiting = TRUE;
window = NULL;
sorted = windows_get_sorted();
for (tmp = sorted; tmp != NULL; tmp = tmp->next) {
WINDOW_REC *rec = tmp->data;
/* is item bound to this window? */
if (item->server != NULL) {
bind = window_bind_find(rec, item->server->tag,
item->visible_name);
if (bind != NULL) {
if (!bind->sticky)
window_bind_destroy(rec, bind);
window = rec;
clear_waiting = FALSE;
break;
}
}
/* use this window IF:
- reuse_unused_windows is ON
- window has no existing items
- window has no name
- 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 &&
rec->name == NULL && !window_bind_has_sticky(rec) &&
(window == NULL || rec == active_win ||
window->bound_items != NULL))
window = rec;
}
g_slist_free(sorted);
if (window == NULL && !settings_get_bool("autocreate_windows")) {
/* never create new windows automatically */
window = active_win;
}
if (window == NULL) {
/* create new window to use */
if (settings_get_bool("autocreate_split_windows")) {
signal_emit("gui window create override", 1,
GINT_TO_POINTER(0));
}
window = window_create(item, automatic);
} else {
/* use existing window */
window_item_add(window, item, automatic);
}
if (clear_waiting)
window_bind_remove_unsticky(window);
}
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->visible_name,
MSGLEVEL_CLIENTNOTICE,
TXT_TALKING_WITH, item->visible_name);
}
}
void window_items_init(void)
{
settings_add_bool("lookandfeel", "reuse_unused_windows", FALSE);
settings_add_bool("lookandfeel", "autocreate_windows", TRUE);
settings_add_bool("lookandfeel", "autocreate_split_windows", FALSE);
settings_add_bool("lookandfeel", "autofocus_new_items", TRUE);
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);
}