hexchat/src/fe-gtk/maingui.c

3903 lines
99 KiB
C
Raw Permalink Normal View History

2011-02-23 22:14:30 -05:00
/* X-Chat
* Copyright (C) 1998-2005 Peter Zelezny.
*
* 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
2012-12-23 14:36:54 -05:00
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
2011-02-23 22:14:30 -05:00
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
2013-07-24 20:47:01 -04:00
#include <gdk/gdkkeysyms.h>
2012-10-24 15:33:02 -04:00
#include "../common/hexchat.h"
2011-02-23 22:14:30 -05:00
#include "../common/fe.h"
#include "../common/server.h"
2012-10-24 15:33:02 -04:00
#include "../common/hexchatc.h"
2011-02-23 22:14:30 -05:00
#include "../common/outbound.h"
#include "../common/inbound.h"
#include "../common/plugin.h"
#include "../common/modes.h"
#include "../common/url.h"
#include "../common/util.h"
2012-07-21 08:26:19 -04:00
#include "../common/text.h"
2013-06-06 19:16:50 -04:00
#include "../common/chanopt.h"
2013-07-24 20:47:01 -04:00
#include "../common/cfgfiles.h"
2011-02-23 22:14:30 -05:00
#include "fe-gtk.h"
#include "banlist.h"
#include "gtkutil.h"
#include "joind.h"
#include "palette.h"
#include "maingui.h"
#include "menu.h"
#include "fkeys.h"
#include "userlistgui.h"
#include "chanview.h"
#include "pixmaps.h"
#include "plugin-tray.h"
#include "xtext.h"
#include "sexy-spell-entry.h"
#define GUI_SPACING (3)
#define GUI_BORDER (0)
enum
{
POS_INVALID = 0,
POS_TOPLEFT = 1,
POS_BOTTOMLEFT = 2,
POS_TOPRIGHT = 3,
POS_BOTTOMRIGHT = 4,
POS_TOP = 5, /* for tabs only */
POS_BOTTOM = 6,
POS_HIDDEN = 7
};
/* two different types of tabs */
#define TAG_IRC 0 /* server, channel, dialog */
#define TAG_UTIL 1 /* dcc, notify, chanlist */
static void mg_create_entry (session *sess, GtkWidget *box);
2013-07-24 20:47:01 -04:00
static void mg_create_search (session *sess, GtkWidget *box);
2011-02-23 22:14:30 -05:00
static void mg_link_irctab (session *sess, int focus);
static session_gui static_mg_gui;
static session_gui *mg_gui = NULL; /* the shared irc tab */
static int ignore_chanmode = FALSE;
static const char chan_flags[] = { 'c', 'n', 't', 'i', 'm', 'l', 'k' };
2011-02-23 22:14:30 -05:00
static chan *active_tab = NULL; /* active tab */
GtkWidget *parent_window = NULL; /* the master window */
GtkStyle *input_style;
static PangoAttrList *away_list;
static PangoAttrList *newdata_list;
static PangoAttrList *nickseen_list;
static PangoAttrList *newmsg_list;
static PangoAttrList *plain_list = NULL;
static PangoAttrList *
mg_attr_list_create (GdkColor *col, int size)
{
PangoAttribute *attr;
PangoAttrList *list;
list = pango_attr_list_new ();
if (col)
{
attr = pango_attr_foreground_new (col->red, col->green, col->blue);
attr->start_index = 0;
attr->end_index = 0xffff;
pango_attr_list_insert (list, attr);
}
if (size > 0)
{
attr = pango_attr_scale_new (size == 1 ? PANGO_SCALE_SMALL : PANGO_SCALE_X_SMALL);
attr->start_index = 0;
attr->end_index = 0xffff;
pango_attr_list_insert (list, attr);
}
return list;
}
static void
mg_create_tab_colors (void)
{
if (plain_list)
{
pango_attr_list_unref (plain_list);
pango_attr_list_unref (newmsg_list);
pango_attr_list_unref (newdata_list);
pango_attr_list_unref (nickseen_list);
pango_attr_list_unref (away_list);
}
2012-10-22 07:49:28 -04:00
plain_list = mg_attr_list_create (NULL, prefs.hex_gui_tab_small);
newdata_list = mg_attr_list_create (&colors[COL_NEW_DATA], prefs.hex_gui_tab_small);
nickseen_list = mg_attr_list_create (&colors[COL_HILIGHT], prefs.hex_gui_tab_small);
newmsg_list = mg_attr_list_create (&colors[COL_NEW_MSG], prefs.hex_gui_tab_small);
2011-02-23 22:14:30 -05:00
away_list = mg_attr_list_create (&colors[COL_AWAY], FALSE);
}
static void
set_window_urgency (GtkWidget *win, gboolean set)
{
2011-02-28 12:59:32 -05:00
gtk_window_set_urgency_hint (GTK_WINDOW (win), set);
2011-02-23 22:14:30 -05:00
}
static void
flash_window (GtkWidget *win)
{
2014-05-11 04:43:01 -04:00
#ifdef HAVE_GTK_MAC
gtkosx_application_attention_request (osx_app, INFO_REQUEST);
#endif
2011-02-23 22:14:30 -05:00
set_window_urgency (win, TRUE);
}
static void
unflash_window (GtkWidget *win)
{
set_window_urgency (win, FALSE);
}
/* flash the taskbar button */
void
fe_flash_window (session *sess)
{
if (fe_gui_info (sess, 0) != 1) /* only do it if not focused */
flash_window (sess->gui->window);
}
/* set a tab plain, red, light-red, or blue */
void
fe_set_tab_color (struct session *sess, int col)
{
struct session *server_sess = sess->server->server_session;
if (sess->gui->is_tab && (col == 0 || sess != current_tab))
{
switch (col)
{
case 0: /* no particular color (theme default) */
sess->new_data = FALSE;
sess->msg_said = FALSE;
sess->nick_said = FALSE;
chan_set_color (sess->res->tab, plain_list);
break;
case 1: /* new data has been displayed (dark red) */
sess->new_data = TRUE;
sess->msg_said = FALSE;
sess->nick_said = FALSE;
chan_set_color (sess->res->tab, newdata_list);
2012-05-04 13:17:36 -04:00
if (chan_is_collapsed (sess->res->tab)
&& !(server_sess->msg_said || server_sess->nick_said)
&& !(server_sess == current_tab))
2011-02-23 22:14:30 -05:00
{
server_sess->new_data = TRUE;
server_sess->msg_said = FALSE;
server_sess->nick_said = FALSE;
chan_set_color (chan_get_parent (sess->res->tab), newdata_list);
}
break;
case 2: /* new message arrived in channel (light red) */
sess->new_data = FALSE;
sess->msg_said = TRUE;
sess->nick_said = FALSE;
chan_set_color (sess->res->tab, newmsg_list);
if (chan_is_collapsed (sess->res->tab)
&& !server_sess->nick_said
&& !(server_sess == current_tab))
2011-02-23 22:14:30 -05:00
{
server_sess->new_data = FALSE;
server_sess->msg_said = TRUE;
server_sess->nick_said = FALSE;
chan_set_color (chan_get_parent (sess->res->tab), newmsg_list);
}
break;
case 3: /* your nick has been seen (blue) */
sess->new_data = FALSE;
sess->msg_said = FALSE;
sess->nick_said = TRUE;
chan_set_color (sess->res->tab, nickseen_list);
if (chan_is_collapsed (sess->res->tab) && !(server_sess == current_tab))
2011-02-23 22:14:30 -05:00
{
server_sess->new_data = FALSE;
server_sess->msg_said = FALSE;
server_sess->nick_said = TRUE;
chan_set_color (chan_get_parent (sess->res->tab), nickseen_list);
}
break;
}
lastact_update (sess);
2011-02-23 22:14:30 -05:00
}
}
static void
mg_set_myself_away (session_gui *gui, gboolean away)
{
gtk_label_set_attributes (GTK_LABEL (gtk_bin_get_child (GTK_BIN (gui->nick_label))),
2011-02-23 22:14:30 -05:00
away ? away_list : NULL);
}
/* change the little icon to the left of your nickname */
void
mg_set_access_icon (session_gui *gui, GdkPixbuf *pix, gboolean away)
{
if (gui->op_xpm)
{
if (pix == gtk_image_get_pixbuf (GTK_IMAGE (gui->op_xpm))) /* no change? */
{
mg_set_myself_away (gui, away);
return;
}
gtk_widget_destroy (gui->op_xpm);
gui->op_xpm = NULL;
}
if (pix && prefs.hex_gui_input_icon)
2011-02-23 22:14:30 -05:00
{
gui->op_xpm = gtk_image_new_from_pixbuf (pix);
gtk_box_pack_start (GTK_BOX (gui->nick_box), gui->op_xpm, 0, 0, 0);
gtk_widget_show (gui->op_xpm);
}
mg_set_myself_away (gui, away);
}
static gboolean
mg_inputbox_focus (GtkWidget *widget, GdkEventFocus *event, session_gui *gui)
{
GSList *list;
session *sess;
if (gui->is_tab)
return FALSE;
list = sess_list;
while (list)
{
sess = list->data;
if (sess->gui == gui)
{
current_sess = sess;
if (!sess->server->server_session)
sess->server->server_session = sess;
break;
}
list = list->next;
}
return FALSE;
}
void
mg_inputbox_cb (GtkWidget *igad, session_gui *gui)
{
char *cmd;
static int ignore = FALSE;
GSList *list;
session *sess = NULL;
if (ignore)
return;
cmd = SPELL_ENTRY_GET_TEXT (igad);
if (cmd[0] == 0)
return;
cmd = g_strdup (cmd);
2011-02-23 22:14:30 -05:00
/* avoid recursive loop */
ignore = TRUE;
SPELL_ENTRY_SET_TEXT (igad, "");
ignore = FALSE;
/* where did this event come from? */
if (gui->is_tab)
{
sess = current_tab;
} else
{
list = sess_list;
while (list)
{
sess = list->data;
if (sess->gui == gui)
break;
list = list->next;
}
if (!list)
sess = NULL;
}
if (sess)
handle_multiline (sess, cmd, TRUE, FALSE);
g_free (cmd);
2011-02-23 22:14:30 -05:00
}
static gboolean
mg_spellcheck_cb (SexySpellEntry *entry, gchar *word, gpointer data)
{
/* This can cause freezes on long words, nicks arn't very long anyway. */
if (strlen (word) > 20)
return TRUE;
/* Ignore anything we think is a valid url */
if (url_check_word (word) != 0)
return FALSE;
return TRUE;
}
2012-10-22 01:24:52 -04:00
#if 0
2011-02-23 22:14:30 -05:00
static gboolean
has_key (char *modes)
{
if (!modes)
return FALSE;
/* this is a crude check, but "-k" can't exist, so it works. */
while (*modes)
{
if (*modes == 'k')
return TRUE;
if (*modes == ' ')
return FALSE;
modes++;
}
return FALSE;
}
2012-10-22 01:24:52 -04:00
#endif
2011-02-23 22:14:30 -05:00
void
fe_set_title (session *sess)
{
char tbuf[512];
int type;
if (sess->gui->is_tab && sess != current_tab)
return;
type = sess->type;
if (sess->server->connected == FALSE && sess->type != SESS_DIALOG)
goto def;
switch (type)
{
case SESS_DIALOG:
2014-12-17 18:49:59 -05:00
g_snprintf (tbuf, sizeof (tbuf), DISPLAY_NAME": %s %s @ %s",
2011-02-23 22:14:30 -05:00
_("Dialog with"), sess->channel, server_get_network (sess->server, TRUE));
break;
case SESS_SERVER:
2014-12-17 18:49:59 -05:00
g_snprintf (tbuf, sizeof (tbuf), DISPLAY_NAME": %s @ %s",
2011-02-23 22:14:30 -05:00
sess->server->nick, server_get_network (sess->server, TRUE));
break;
case SESS_CHANNEL:
/* don't display keys in the titlebar */
2012-10-22 07:49:28 -04:00
if (prefs.hex_gui_win_modes)
2012-10-22 01:24:52 -04:00
{
2014-12-17 18:49:59 -05:00
g_snprintf (tbuf, sizeof (tbuf),
2012-10-22 01:24:52 -04:00
DISPLAY_NAME": %s @ %s / %s (%s)",
2011-02-23 22:14:30 -05:00
sess->server->nick, server_get_network (sess->server, TRUE),
2012-10-22 01:24:52 -04:00
sess->channel, sess->current_modes ? sess->current_modes : "");
}
2011-02-23 22:14:30 -05:00
else
2012-10-22 01:24:52 -04:00
{
2014-12-17 18:49:59 -05:00
g_snprintf (tbuf, sizeof (tbuf),
2012-10-22 01:24:52 -04:00
DISPLAY_NAME": %s @ %s / %s",
2011-02-23 22:14:30 -05:00
sess->server->nick, server_get_network (sess->server, TRUE),
2012-10-22 01:24:52 -04:00
sess->channel);
}
2012-10-22 07:49:28 -04:00
if (prefs.hex_gui_win_ucount)
2012-10-22 01:24:52 -04:00
{
2014-12-17 18:49:59 -05:00
g_snprintf (tbuf + strlen (tbuf), 9, " (%d)", sess->total);
2012-10-22 01:24:52 -04:00
}
2011-02-23 22:14:30 -05:00
break;
case SESS_NOTICES:
case SESS_SNOTICES:
2014-12-17 18:49:59 -05:00
g_snprintf (tbuf, sizeof (tbuf), DISPLAY_NAME": %s @ %s (notices)",
2011-02-23 22:14:30 -05:00
sess->server->nick, server_get_network (sess->server, TRUE));
break;
default:
def:
2014-12-17 18:49:59 -05:00
g_snprintf (tbuf, sizeof (tbuf), DISPLAY_NAME);
2011-05-30 18:40:13 -04:00
gtk_window_set_title (GTK_WINDOW (sess->gui->window), tbuf);
2011-02-23 22:14:30 -05:00
return;
}
gtk_window_set_title (GTK_WINDOW (sess->gui->window), tbuf);
}
static gboolean
mg_windowstate_cb (GtkWindow *wid, GdkEventWindowState *event, gpointer userdata)
{
if ((event->changed_mask & GDK_WINDOW_STATE_ICONIFIED) &&
(event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) &&
prefs.hex_gui_tray_minimize && prefs.hex_gui_tray &&
!unity_mode ())
2011-02-23 22:14:30 -05:00
{
tray_toggle_visibility (TRUE);
gtk_window_deiconify (wid);
}
prefs.hex_gui_win_state = 0;
if (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED)
prefs.hex_gui_win_state = 1;
2013-09-19 17:52:17 -04:00
prefs.hex_gui_win_fullscreen = 0;
if (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)
prefs.hex_gui_win_fullscreen = 1;
menu_set_fullscreen (current_sess->gui, prefs.hex_gui_win_fullscreen);
2011-02-23 22:14:30 -05:00
return FALSE;
}
static gboolean
mg_configure_cb (GtkWidget *wid, GdkEventConfigure *event, session *sess)
{
if (sess == NULL) /* for the main_window */
{
if (mg_gui)
{
2013-09-19 17:52:17 -04:00
if (prefs.hex_gui_win_save && !prefs.hex_gui_win_state && !prefs.hex_gui_win_fullscreen)
2011-02-23 22:14:30 -05:00
{
sess = current_sess;
2012-10-22 07:49:28 -04:00
gtk_window_get_position (GTK_WINDOW (wid), &prefs.hex_gui_win_left,
&prefs.hex_gui_win_top);
gtk_window_get_size (GTK_WINDOW (wid), &prefs.hex_gui_win_width,
&prefs.hex_gui_win_height);
2011-02-23 22:14:30 -05:00
}
}
}
if (sess)
{
2012-10-22 07:49:28 -04:00
if (sess->type == SESS_DIALOG && prefs.hex_gui_win_save)
2011-02-23 22:14:30 -05:00
{
2012-10-22 07:49:28 -04:00
gtk_window_get_position (GTK_WINDOW (wid), &prefs.hex_gui_dialog_left,
&prefs.hex_gui_dialog_top);
gtk_window_get_size (GTK_WINDOW (wid), &prefs.hex_gui_dialog_width,
&prefs.hex_gui_dialog_height);
2011-02-23 22:14:30 -05:00
}
}
return FALSE;
}
/* move to a non-irc tab */
static void
mg_show_generic_tab (GtkWidget *box)
{
int num;
GtkWidget *f = NULL;
if (current_sess && gtk_widget_has_focus (current_sess->gui->input_box))
f = current_sess->gui->input_box;
num = gtk_notebook_page_num (GTK_NOTEBOOK (mg_gui->note_book), box);
gtk_notebook_set_current_page (GTK_NOTEBOOK (mg_gui->note_book), num);
gtk_tree_view_set_model (GTK_TREE_VIEW (mg_gui->user_tree), NULL);
gtk_window_set_title (GTK_WINDOW (mg_gui->window),
g_object_get_data (G_OBJECT (box), "title"));
gtk_widget_set_sensitive (mg_gui->menu, FALSE);
if (f)
gtk_widget_grab_focus (f);
}
/* a channel has been focused */
static void
mg_focus (session *sess)
{
if (sess->gui->is_tab)
current_tab = sess;
current_sess = sess;
/* dirty trick to avoid auto-selection */
SPELL_ENTRY_SET_EDITABLE (sess->gui->input_box, FALSE);
gtk_widget_grab_focus (sess->gui->input_box);
SPELL_ENTRY_SET_EDITABLE (sess->gui->input_box, TRUE);
sess->server->front_session = sess;
if (sess->server->server_session != NULL)
{
if (sess->server->server_session->type != SESS_SERVER)
sess->server->server_session = sess;
} else
{
sess->server->server_session = sess;
}
if (sess->new_data || sess->nick_said || sess->msg_said)
{
sess->nick_said = FALSE;
sess->msg_said = FALSE;
sess->new_data = FALSE;
lastact_update (sess);
2011-02-23 22:14:30 -05:00
/* when called via mg_changui_new, is_tab might be true, but
sess->res->tab is still NULL. */
if (sess->res->tab)
fe_set_tab_color (sess, 0);
}
}
static int
mg_progressbar_update (GtkWidget *bar)
{
static int type = 0;
2014-12-04 07:06:38 -05:00
static gdouble pos = 0;
2011-02-23 22:14:30 -05:00
pos += 0.05;
if (pos >= 0.99)
{
if (type == 0)
{
type = 1;
gtk_progress_bar_set_orientation ((GtkProgressBar *) bar,
GTK_PROGRESS_RIGHT_TO_LEFT);
} else
{
type = 0;
gtk_progress_bar_set_orientation ((GtkProgressBar *) bar,
GTK_PROGRESS_LEFT_TO_RIGHT);
}
pos = 0.05;
}
gtk_progress_bar_set_fraction ((GtkProgressBar *) bar, pos);
return 1;
}
void
mg_progressbar_create (session_gui *gui)
{
gui->bar = gtk_progress_bar_new ();
gtk_box_pack_start (GTK_BOX (gui->nick_box), gui->bar, 0, 0, 0);
gtk_widget_show (gui->bar);
gui->bartag = fe_timeout_add (50, mg_progressbar_update, gui->bar);
}
void
mg_progressbar_destroy (session_gui *gui)
{
fe_timeout_remove (gui->bartag);
gtk_widget_destroy (gui->bar);
gui->bar = 0;
gui->bartag = 0;
}
/* switching tabs away from this one, so remember some info about it! */
static void
mg_unpopulate (session *sess)
{
restore_gui *res;
session_gui *gui;
int i;
gui = sess->gui;
res = sess->res;
res->input_text = g_strdup (SPELL_ENTRY_GET_TEXT (gui->input_box));
res->topic_text = g_strdup (gtk_entry_get_text (GTK_ENTRY (gui->topic_entry)));
res->limit_text = g_strdup (gtk_entry_get_text (GTK_ENTRY (gui->limit_entry)));
res->key_text = g_strdup (gtk_entry_get_text (GTK_ENTRY (gui->key_entry)));
2011-02-23 22:14:30 -05:00
if (gui->laginfo)
res->lag_text = g_strdup (gtk_label_get_text (GTK_LABEL (gui->laginfo)));
2011-02-23 22:14:30 -05:00
if (gui->throttleinfo)
res->queue_text = g_strdup (gtk_label_get_text (GTK_LABEL (gui->throttleinfo)));
2011-02-23 22:14:30 -05:00
for (i = 0; i < NUM_FLAG_WIDS - 1; i++)
res->flag_wid_state[i] = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gui->flag_wid[i]));
2011-02-23 22:14:30 -05:00
res->old_ul_value = userlist_get_value (gui->user_tree);
if (gui->lagometer)
res->lag_value = gtk_progress_bar_get_fraction (
GTK_PROGRESS_BAR (gui->lagometer));
if (gui->throttlemeter)
res->queue_value = gtk_progress_bar_get_fraction (
GTK_PROGRESS_BAR (gui->throttlemeter));
if (gui->bar)
{
res->c_graph = TRUE; /* still have a graph, just not visible now */
mg_progressbar_destroy (gui);
}
}
static void
mg_restore_label (GtkWidget *label, char **text)
{
if (!label)
return;
if (*text)
{
gtk_label_set_text (GTK_LABEL (label), *text);
g_free (*text);
2011-02-23 22:14:30 -05:00
*text = NULL;
} else
{
gtk_label_set_text (GTK_LABEL (label), "");
}
}
static void
mg_restore_entry (GtkWidget *entry, char **text)
{
if (*text)
{
gtk_entry_set_text (GTK_ENTRY (entry), *text);
g_free (*text);
2011-02-23 22:14:30 -05:00
*text = NULL;
} else
{
gtk_entry_set_text (GTK_ENTRY (entry), "");
}
gtk_editable_set_position (GTK_EDITABLE (entry), -1);
}
static void
mg_restore_speller (GtkWidget *entry, char **text)
{
if (*text)
{
SPELL_ENTRY_SET_TEXT (entry, *text);
g_free (*text);
2011-02-23 22:14:30 -05:00
*text = NULL;
} else
{
SPELL_ENTRY_SET_TEXT (entry, "");
}
SPELL_ENTRY_SET_POS (entry, -1);
}
void
mg_set_topic_tip (session *sess)
{
char *text;
switch (sess->type)
{
case SESS_CHANNEL:
if (sess->topic)
{
text = g_strdup_printf (_("Topic for %s is: %s"), sess->channel,
sess->topic);
2014-01-18 04:08:32 -05:00
gtk_widget_set_tooltip_text (sess->gui->topic_entry, text);
2011-02-23 22:14:30 -05:00
g_free (text);
} else
2014-01-18 04:08:32 -05:00
gtk_widget_set_tooltip_text (sess->gui->topic_entry, _("No topic is set"));
2011-02-23 22:14:30 -05:00
break;
default:
if (gtk_entry_get_text (GTK_ENTRY (sess->gui->topic_entry)) &&
gtk_entry_get_text (GTK_ENTRY (sess->gui->topic_entry))[0])
2014-01-18 04:08:32 -05:00
gtk_widget_set_tooltip_text (sess->gui->topic_entry, (char *)gtk_entry_get_text (GTK_ENTRY (sess->gui->topic_entry)));
2011-02-23 22:14:30 -05:00
else
2014-01-18 04:08:32 -05:00
gtk_widget_set_tooltip_text (sess->gui->topic_entry, NULL);
2011-02-23 22:14:30 -05:00
}
}
static void
mg_hide_empty_pane (GtkPaned *pane)
{
if ((gtk_paned_get_child1 (pane) == NULL || !gtk_widget_get_visible (gtk_paned_get_child1 (pane))) &&
(gtk_paned_get_child2 (pane) == NULL || !gtk_widget_get_visible (gtk_paned_get_child2 (pane))))
2011-02-23 22:14:30 -05:00
{
gtk_widget_hide (GTK_WIDGET (pane));
return;
}
gtk_widget_show (GTK_WIDGET (pane));
}
static void
mg_hide_empty_boxes (session_gui *gui)
{
/* hide empty vpanes - so the handle is not shown */
mg_hide_empty_pane ((GtkPaned*)gui->vpane_right);
mg_hide_empty_pane ((GtkPaned*)gui->vpane_left);
}
static void
mg_userlist_showhide (session *sess, int show)
{
session_gui *gui = sess->gui;
int handle_size;
int right_size;
GtkAllocation allocation;
2012-10-22 07:49:28 -04:00
right_size = MAX (prefs.hex_gui_pane_right_size, prefs.hex_gui_pane_right_size_min);
2011-02-23 22:14:30 -05:00
if (show)
{
gtk_widget_show (gui->user_box);
gui->ul_hidden = 0;
gtk_widget_get_allocation (gui->hpane_right, &allocation);
2011-02-23 22:14:30 -05:00
gtk_widget_style_get (GTK_WIDGET (gui->hpane_right), "handle-size", &handle_size, NULL);
gtk_paned_set_position (GTK_PANED (gui->hpane_right), allocation.width - (right_size + handle_size));
2011-02-23 22:14:30 -05:00
}
else
{
gtk_widget_hide (gui->user_box);
gui->ul_hidden = 1;
}
mg_hide_empty_boxes (gui);
}
static gboolean
mg_is_userlist_and_tree_combined (void)
{
2012-10-22 07:49:28 -04:00
if (prefs.hex_gui_tab_pos == POS_TOPLEFT && prefs.hex_gui_ulist_pos == POS_BOTTOMLEFT)
2011-02-23 22:14:30 -05:00
return TRUE;
2012-10-22 07:49:28 -04:00
if (prefs.hex_gui_tab_pos == POS_BOTTOMLEFT && prefs.hex_gui_ulist_pos == POS_TOPLEFT)
2011-02-23 22:14:30 -05:00
return TRUE;
2012-10-22 07:49:28 -04:00
if (prefs.hex_gui_tab_pos == POS_TOPRIGHT && prefs.hex_gui_ulist_pos == POS_BOTTOMRIGHT)
2011-02-23 22:14:30 -05:00
return TRUE;
2012-10-22 07:49:28 -04:00
if (prefs.hex_gui_tab_pos == POS_BOTTOMRIGHT && prefs.hex_gui_ulist_pos == POS_TOPRIGHT)
2011-02-23 22:14:30 -05:00
return TRUE;
return FALSE;
}
/* decide if the userlist should be shown or hidden for this tab */
void
mg_decide_userlist (session *sess, gboolean switch_to_current)
{
/* when called from menu.c we need this */
if (sess->gui == mg_gui && switch_to_current)
sess = current_tab;
2012-10-22 07:49:28 -04:00
if (prefs.hex_gui_ulist_hide)
2011-02-23 22:14:30 -05:00
{
mg_userlist_showhide (sess, FALSE);
return;
}
switch (sess->type)
{
case SESS_SERVER:
case SESS_DIALOG:
case SESS_NOTICES:
case SESS_SNOTICES:
if (mg_is_userlist_and_tree_combined ())
mg_userlist_showhide (sess, TRUE); /* show */
else
mg_userlist_showhide (sess, FALSE); /* hide */
break;
default:
mg_userlist_showhide (sess, TRUE); /* show */
}
}
static void
mg_userlist_toggle_cb (GtkWidget *button, gpointer userdata)
{
2012-10-22 07:49:28 -04:00
prefs.hex_gui_ulist_hide = !prefs.hex_gui_ulist_hide;
2011-02-23 22:14:30 -05:00
mg_decide_userlist (current_sess, FALSE);
gtk_widget_grab_focus (current_sess->gui->input_box);
}
static int ul_tag = 0;
static gboolean
mg_populate_userlist (session *sess)
{
if (!sess)
sess = current_tab;
if (is_session (sess))
{
if (sess->type == SESS_DIALOG)
mg_set_access_icon (sess->gui, NULL, sess->server->is_away);
else
mg_set_access_icon (sess->gui, get_user_icon (sess->server, sess->me), sess->server->is_away);
userlist_show (sess);
userlist_set_value (sess->gui->user_tree, sess->res->old_ul_value);
}
ul_tag = 0;
return 0;
}
/* fill the irc tab with a new channel */
static void
mg_populate (session *sess)
{
session_gui *gui = sess->gui;
restore_gui *res = sess->res;
int i, render = TRUE;
guint16 vis = gui->ul_hidden;
GtkAllocation allocation;
2011-02-23 22:14:30 -05:00
switch (sess->type)
{
case SESS_DIALOG:
/* show the dialog buttons */
gtk_widget_show (gui->dialogbutton_box);
/* hide the chan-mode buttons */
gtk_widget_hide (gui->topicbutton_box);
/* hide the userlist */
mg_decide_userlist (sess, FALSE);
/* shouldn't edit the topic */
gtk_editable_set_editable (GTK_EDITABLE (gui->topic_entry), FALSE);
/* might be hidden from server tab */
if (prefs.hex_gui_topicbar)
gtk_widget_show (gui->topic_bar);
2011-02-23 22:14:30 -05:00
break;
case SESS_SERVER:
2012-10-22 07:49:28 -04:00
if (prefs.hex_gui_mode_buttons)
2011-02-23 22:14:30 -05:00
gtk_widget_show (gui->topicbutton_box);
/* hide the dialog buttons */
gtk_widget_hide (gui->dialogbutton_box);
/* hide the userlist */
mg_decide_userlist (sess, FALSE);
/* servers don't have topics */
gtk_widget_hide (gui->topic_bar);
2011-02-23 22:14:30 -05:00
break;
default:
/* hide the dialog buttons */
gtk_widget_hide (gui->dialogbutton_box);
2012-10-22 07:49:28 -04:00
if (prefs.hex_gui_mode_buttons)
2011-02-23 22:14:30 -05:00
gtk_widget_show (gui->topicbutton_box);
/* show the userlist */
mg_decide_userlist (sess, FALSE);
/* let the topic be editted */
gtk_editable_set_editable (GTK_EDITABLE (gui->topic_entry), TRUE);
if (prefs.hex_gui_topicbar)
gtk_widget_show (gui->topic_bar);
2011-02-23 22:14:30 -05:00
}
/* move to THE irc tab */
if (gui->is_tab)
gtk_notebook_set_current_page (GTK_NOTEBOOK (gui->note_book), 0);
/* xtext size change? Then don't render, wait for the expose caused
by showing/hidding the userlist */
gtk_widget_get_allocation (gui->user_box, &allocation);
if (vis != gui->ul_hidden && allocation.width > 1)
2011-02-23 22:14:30 -05:00
render = FALSE;
gtk_xtext_buffer_show (GTK_XTEXT (gui->xtext), res->buffer, render);
if (gui->is_tab)
gtk_widget_set_sensitive (gui->menu, TRUE);
/* restore all the GtkEntry's */
mg_restore_entry (gui->topic_entry, &res->topic_text);
mg_restore_speller (gui->input_box, &res->input_text);
mg_restore_entry (gui->key_entry, &res->key_text);
mg_restore_entry (gui->limit_entry, &res->limit_text);
mg_restore_label (gui->laginfo, &res->lag_text);
mg_restore_label (gui->throttleinfo, &res->queue_text);
mg_focus (sess);
fe_set_title (sess);
/* this one flickers, so only change if necessary */
if (strcmp (sess->server->nick, gtk_button_get_label (GTK_BUTTON (gui->nick_label))) != 0)
gtk_button_set_label (GTK_BUTTON (gui->nick_label), sess->server->nick);
/* this is slow, so make it a timeout event */
if (!gui->is_tab)
{
mg_populate_userlist (sess);
} else
{
if (ul_tag == 0)
ul_tag = g_idle_add ((GSourceFunc)mg_populate_userlist, NULL);
}
fe_userlist_numbers (sess);
/* restore all the channel mode buttons */
ignore_chanmode = TRUE;
for (i = 0; i < NUM_FLAG_WIDS - 1; i++)
{
/* Hide if mode not supported */
if (sess->server && strchr (sess->server->chanmodes, chan_flags[i]) == NULL)
gtk_widget_hide (sess->gui->flag_wid[i]);
else
gtk_widget_show (sess->gui->flag_wid[i]);
/* Update state */
2011-02-23 22:14:30 -05:00
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gui->flag_wid[i]),
res->flag_wid_state[i]);
}
2011-02-23 22:14:30 -05:00
ignore_chanmode = FALSE;
if (gui->lagometer)
{
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (gui->lagometer),
res->lag_value);
if (res->lag_tip)
2014-01-18 04:08:32 -05:00
gtk_widget_set_tooltip_text (gtk_widget_get_parent (sess->gui->lagometer), res->lag_tip);
2011-02-23 22:14:30 -05:00
}
if (gui->throttlemeter)
{
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (gui->throttlemeter),
res->queue_value);
if (res->queue_tip)
2014-01-18 04:08:32 -05:00
gtk_widget_set_tooltip_text (gtk_widget_get_parent (sess->gui->throttlemeter), res->queue_tip);
2011-02-23 22:14:30 -05:00
}
/* did this tab have a connecting graph? restore it.. */
if (res->c_graph)
{
res->c_graph = FALSE;
mg_progressbar_create (gui);
}
/* menu items */
menu_set_away (gui, sess->server->is_away);
2011-02-23 22:14:30 -05:00
gtk_widget_set_sensitive (gui->menu_item[MENU_ID_AWAY], sess->server->connected);
gtk_widget_set_sensitive (gui->menu_item[MENU_ID_JOIN], sess->server->end_of_motd);
gtk_widget_set_sensitive (gui->menu_item[MENU_ID_DISCONNECT],
sess->server->connected || sess->server->recondelay_tag);
mg_set_topic_tip (sess);
plugin_emit_dummy_print (sess, "Focus Tab");
}
void
mg_bring_tofront_sess (session *sess) /* IRC tab or window */
{
if (sess->gui->is_tab)
chan_focus (sess->res->tab);
else
gtk_window_present (GTK_WINDOW (sess->gui->window));
}
void
mg_bring_tofront (GtkWidget *vbox) /* non-IRC tab or window */
{
chan *ch;
ch = g_object_get_data (G_OBJECT (vbox), "ch");
if (ch)
chan_focus (ch);
else