summary refs log tree commit diff stats
path: root/plugins
AgeCommit message (Expand)Author
2011-12-03placeholder for /exec -oBerke Viktor
2011-12-03add some branding to winsys outputBerke Viktor
2011-12-03print system info in one line for othersBerke Viktor
2011-12-02add example for sanitizing xchat_set_pluginpref_int inputBerke Viktor
2011-12-02no need for an extra newline during tcl initBerke Viktor
2011-12-02fix automatic update checkingBerke Viktor
2011-12-02fix deinit message in execBerke Viktor
2011-12-02apparently this is not allowed in C++Berke Viktor
2011-12-02don't use hardcoded strings for plugin namesBerke Viktor
2011-12-02add documentation for plugin config frameworkBerke Viktor
2011-12-01speed up winsys executionsBerke Viktor
2011-12-01plugin api conformanceBerke Viktor
2011-11-30refactoringBerke Viktor
2011-11-30plugin config - separate string and int functionsBerke Viktor
2011-11-30use global xchat-plugin.h for xtrayBerke Viktor
2011-11-30plugin config save is done via raw file access, now works with multiple varsBerke Viktor
2011-11-29initial plugin config framework, can't save multiple entriesBerke Viktor
2011-11-29display sysinfo for self when not in channel/dialogBerke Viktor
2011-11-29own icon for winsysBerke Viktor
2011-11-29relicense own plugins under the MIT licenseBerke Viktor
2011-11-29winsys cosmetics and extensionsBerke Viktor
2011-11-28MSVC-style printBerke Viktor
2011-11-28fix winsys freezeBerke Viktor
2011-11-28now winsys actually works as a pluginBerke Viktor
2011-11-28enable building of winsys with other pluginsBerke Viktor
2011-11-28more winsys fixes and build as c++Berke Viktor
2011-11-28more winsys fixes for wdkBerke Viktor
2011-11-28installer support for obs and gtk engines, x64 supportBerke Viktor
2011-11-28first piece of wdk fixes for winsysBerke Viktor
2011-11-27initial version of winsys sysinfo pluginBerke Viktor
2011-11-27fix the update checker, return correctly with callbackBerke Viktor
2011-11-27some formatting for execBerke Viktor
2011-11-27make exec display as nice as possibleBerke Viktor
2011-11-27exec cleanupBerke Viktor
2011-11-27exec support for releaser and makefileBerke Viktor
2011-11-27initial execBerke Viktor
2011-11-25perform periodic update checks automaticallyBerke Viktor
2011-11-25rename fishlim main file in makefile tooBerke Viktor
2011-11-25get in sync with fishlim upstreamBerke Viktor
2011-11-25rename fishlim main file to avoid confusionBerke Viktor
2011-11-24fix fishlim config handlerBerke Viktor
2011-11-24add fishlim pluginBerke Viktor
2011-11-23forgot to bump updater version numberBerke Viktor
2011-11-23Merge branch 'master' into wdkBerke Viktor
2011-11-23update xchat to r1498Berke Viktor
2011-11-23fix update checker for separate installersBerke Viktor
2011-11-22add doat pluginBerke Viktor
2011-11-22gtk engines are non-existent in gtk.org buildsBerke Viktor
2011-08-18omit gtkpref messagesBerke Viktor
2011-08-17working gtkpref pluginBerke Viktor
a id='n358' href='#n358'>358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449
































































































































































































































































































































































































































































                                                                                                                               
/* X-Chat
 * Copyright (C) 1998 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
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "fe-gtk.h"

#include <gtk/gtkcheckbutton.h>
#include <gtk/gtkentry.h>
#include <gtk/gtkstock.h>
#include <gtk/gtkhbox.h>
#include <gtk/gtkhbbox.h>
#include <gtk/gtkframe.h>
#include <gtk/gtkhseparator.h>
#include <gtk/gtkversion.h>

#include <gtk/gtkliststore.h>
#include <gtk/gtktreeview.h>
#include <gtk/gtktreeselection.h>
#include <gtk/gtkcellrenderertext.h>
#include <gtk/gtkcellrenderertoggle.h>

#include "../common/xchat.h"
#include "../common/ignore.h"
#include "../common/cfgfiles.h"
#include "../common/fe.h"
#include "gtkutil.h"
#include "maingui.h"

enum
{
	MASK_COLUMN,
	CHAN_COLUMN,
	PRIV_COLUMN,
	NOTICE_COLUMN,
	CTCP_COLUMN,
	DCC_COLUMN,
	INVITE_COLUMN,
	UNIGNORE_COLUMN,
	N_COLUMNS
};

static GtkWidget *ignorewin = 0;

static GtkWidget *num_ctcp;
static GtkWidget *num_priv;
static GtkWidget *num_chan;
static GtkWidget *num_noti;
static GtkWidget *num_invi;

static GtkTreeModel *
get_store (void)
{
	return gtk_tree_view_get_model (g_object_get_data (G_OBJECT (ignorewin), "view"));
}

static int
ignore_get_flags (GtkTreeModel *model, GtkTreeIter *iter)
{
	gboolean chan, priv, noti, ctcp, dcc, invi, unig;
	int flags = 0;

	gtk_tree_model_get (model, iter, 1, &chan, 2, &priv, 3, &noti,
	                    4, &ctcp, 5, &dcc, 6, &invi, 7, &unig, -1);
	if (chan)
		flags |= IG_CHAN;
	if (priv)
		flags |= IG_PRIV;
	if (noti)
		flags |= IG_NOTI;
	if (ctcp)
		flags |= IG_CTCP;
	if (dcc)
		flags |= IG_DCC;
	if (invi)
		flags |= IG_INVI;
	if (unig)
		flags |= IG_UNIG;
	return flags;
}

static void
mask_edited (GtkCellRendererText *render, gchar *path, gchar *new, gpointer dat)
{
	GtkListStore *store = GTK_LIST_STORE (get_store ());
	GtkTreeIter iter;
	char *old;
	int flags;

	gtkutil_treemodel_string_to_iter (GTK_TREE_MODEL (store), path, &iter);
	gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, 0, &old, -1);
	
	if (!strcmp (old, new))	/* no change */
		;
	else if (ignore_exists (new))	/* duplicate, ignore */
		fe_message (_("That mask already exists."), FE_MSG_ERROR);
	else
	{
		/* delete old mask, and add new one with original flags */
		ignore_del (old, NULL);
		flags = ignore_get_flags (GTK_TREE_MODEL (store), &iter);
		ignore_add (new, flags);

		/* update tree */
		gtk_list_store_set (store, &iter, MASK_COLUMN, new, -1);
	}
	g_free (old);
	
}

static void
option_toggled (GtkCellRendererToggle *render, gchar *path, gpointer data)
{
	GtkListStore *store = GTK_LIST_STORE (get_store ());
	GtkTreeIter iter;
	int col_id = GPOINTER_TO_INT (data);
	gboolean active;
	char *mask;
	int flags;

	gtkutil_treemodel_string_to_iter (GTK_TREE_MODEL (store), path, &iter);

	/* update model */
	gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, col_id, &active, -1);
	gtk_list_store_set (store, &iter, col_id, !active, -1);

	/* update ignore list */
	gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, 0, &mask, -1);
	flags = ignore_get_flags (GTK_TREE_MODEL (store), &iter);
	if (ignore_add (mask, flags) != 2)
		g_warning ("ignore treeview is out of sync!\n");
	
	g_free (mask);
}

static GtkWidget *
ignore_treeview_new (GtkWidget *box)
{
	GtkListStore *store;
	GtkWidget *view;
	GtkTreeViewColumn *col;
	GtkCellRenderer *render;
	int col_id;

	store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING,
	                            G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
	                            G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
	                            G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
	                            G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
	g_return_val_if_fail (store != NULL, NULL);

	view = gtkutil_treeview_new (box, GTK_TREE_MODEL (store),
	                             NULL,
	                             MASK_COLUMN, _("Mask"),
	                             CHAN_COLUMN, _("Channel"),
	                             PRIV_COLUMN, _("Private"),
	                             NOTICE_COLUMN, _("Notice"),
	                             CTCP_COLUMN, _("CTCP"),
	                             DCC_COLUMN, _("DCC"),
	                             INVITE_COLUMN, _("Invite"),
	                             UNIGNORE_COLUMN, _("Unignore"),
	                             -1);

	gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
	gtk_tree_view_column_set_expand (gtk_tree_view_get_column (GTK_TREE_VIEW (view), 0), TRUE);

	/* attach to signals and customise columns */
	for (col_id=0; (col = gtk_tree_view_get_column (GTK_TREE_VIEW (view), col_id));
	     col_id++)
	{
		GList *list = gtk_tree_view_column_get_cell_renderers (col);
		GList *tmp;

		for (tmp = list; tmp; tmp = tmp->next)
		{
			render = tmp->data;
			if (col_id > 0)	/* it's a toggle button column */
			{
				g_signal_connect (render, "toggled", G_CALLBACK (option_toggled),
				                  GINT_TO_POINTER (col_id));
			} else	/* mask column */
			{
				g_object_set (G_OBJECT (render), "editable", TRUE, NULL);
				g_signal_connect (render, "edited", G_CALLBACK (mask_edited), NULL);
				/* make this column sortable */
				gtk_tree_view_column_set_sort_column_id (col, col_id);
				gtk_tree_view_column_set_min_width (col, 272);
			}
			/* centre titles */
			gtk_tree_view_column_set_alignment (col, 0.5);
		}

		g_list_free (list);
	}
	
	gtk_widget_show (view);
	return view;
}

static void
ignore_delete_entry_clicked (GtkWidget * wid, struct session *sess)
{
	GtkTreeView *view = g_object_get_data (G_OBJECT (ignorewin), "view");
	GtkListStore *store = GTK_LIST_STORE (gtk_tree_view_get_model (view));
	GtkTreeIter iter;
	GtkTreePath *path;
	char *mask = NULL;

	if (gtkutil_treeview_get_selected (view, &iter, 0, &mask, -1))
	{
		/* delete this row, select next one */
#if (GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION == 0)
		gtk_list_store_remove (store, &iter);
#else
		if (gtk_list_store_remove (store, &iter))
		{
			path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
			gtk_tree_view_scroll_to_cell (view, path, NULL, TRUE, 1.0, 0.0);
			gtk_tree_view_set_cursor (view, path, NULL, FALSE);
			gtk_tree_path_free (path);
		}
#endif

		ignore_del (mask, NULL);
		g_free (mask);
	}
}

static void
ignore_store_new (int cancel, char *mask, gpointer data)
{
	GtkTreeView *view = g_object_get_data (G_OBJECT (ignorewin), "view");
	GtkListStore *store = GTK_LIST_STORE (get_store ());
	GtkTreeIter iter;
	GtkTreePath *path;
	int flags = IG_CHAN | IG_PRIV | IG_NOTI | IG_CTCP | IG_DCC | IG_INVI;

	if (cancel)
		return;
	/* check if it already exists */
	if (ignore_exists (mask))
	{
		fe_message (_("That mask already exists."), FE_MSG_ERROR);
		return;
	}

	ignore_add (mask, flags);

	gtk_list_store_append (store, &iter);
	/* ignore everything by default */
	gtk_list_store_set (store, &iter, 0, mask, 1, TRUE, 2, TRUE, 3, TRUE,
	                    4, TRUE, 5, TRUE, 6, TRUE, 7, FALSE, -1);
	/* make sure the new row is visible and selected */
	path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
	gtk_tree_view_scroll_to_cell (view, path, NULL, TRUE, 1.0, 0.0);
	gtk_tree_view_set_cursor (view, path, NULL, FALSE);
	gtk_tree_path_free (path);
}

static void
ignore_clear_entry_clicked (GtkWidget * wid, gpointer unused)
{
	GtkListStore *store = GTK_LIST_STORE (get_store ());
	GtkTreeIter iter;
	char *mask;

	if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
	{
		/* remove from ignore_list */
		do
		{
			mask = NULL;
			gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, MASK_COLUMN, &mask, -1);
			ignore_del (mask, NULL);
			g_free (mask);
		}
		while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));

		/* remove from GUI */
		gtk_list_store_clear (store);
	}
}

static void
ignore_new_entry_clicked (GtkWidget * wid, struct session *sess)
{
	fe_get_str (_("Enter mask to ignore:"), "nick!userid@host.com",
	            ignore_store_new, NULL);

}

static void
close_ignore_gui_callback ()
{
	ignore_save ();
	ignorewin = 0;
}

static GtkWidget *
ignore_stats_entry (GtkWidget * box, char *label, int value)
{
	GtkWidget *wid;
	char buf[16];

	sprintf (buf, "%d", value);
	gtkutil_label_new (label, box);
	wid = gtkutil_entry_new (16, box, 0, 0);
	gtk_widget_set_size_request (wid, 30, -1);
	gtk_editable_set_editable (GTK_EDITABLE (wid), FALSE);
	gtk_widget_set_sensitive (GTK_WIDGET (wid), FALSE);
	gtk_entry_set_text (GTK_ENTRY (wid), buf);

	return wid;
}

void
ignore_gui_open ()
{
	GtkWidget *vbox, *box, *stat_box, *frame;
	GtkWidget *view;
	GtkListStore *store;
	GtkTreeIter iter;
	GSList *temp = ignore_list;
	char *mask;
	gboolean private, chan, notice, ctcp, dcc, invite, unignore;

	if (ignorewin)
	{
		mg_bring_tofront (ignorewin);
		return;
	}

	ignorewin =
			  mg_create_generic_tab ("IgnoreList", _("XChat: Ignore list"),
											FALSE, TRUE, close_ignore_gui_callback,
											NULL, 600, 256, &vbox, 0);

	view = ignore_treeview_new (vbox);
	g_object_set_data (G_OBJECT (ignorewin), "view", view);
	
	frame = gtk_frame_new (_("Ignore Stats:"));
	gtk_widget_show (frame);

	stat_box = gtk_hbox_new (0, 2);
	gtk_container_set_border_width (GTK_CONTAINER (stat_box), 6);
	gtk_container_add (GTK_CONTAINER (frame), stat_box);
	gtk_widget_show (stat_box);

	num_chan = ignore_stats_entry (stat_box, _("Channel:"), ignored_chan);
	num_priv = ignore_stats_entry (stat_box, _("Private:"), ignored_priv);
	num_noti = ignore_stats_entry (stat_box, _("Notice:"), ignored_noti);
	num_ctcp = ignore_stats_entry (stat_box, _("CTCP:"), ignored_ctcp);
	num_invi = ignore_stats_entry (stat_box, _("Invite:"), ignored_invi);

	gtk_box_pack_start (GTK_BOX (vbox), frame, 0, 0, 5);

	box = gtk_hbutton_box_new ();
	gtk_button_box_set_layout (GTK_BUTTON_BOX (box), GTK_BUTTONBOX_SPREAD);
	gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, FALSE, 2);
	gtk_container_set_border_width (GTK_CONTAINER (box), 5);
	gtk_widget_show (box);

	gtkutil_button (box, GTK_STOCK_NEW, 0, ignore_new_entry_clicked, 0,
						 _("Add..."));
	gtkutil_button (box, GTK_STOCK_DELETE, 0, ignore_delete_entry_clicked,
						 0, _("Delete"));
	gtkutil_button (box, GTK_STOCK_CLEAR, 0, ignore_clear_entry_clicked,
						 0, _("Clear"));

	store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (view)));

	while (temp)
	{
		struct ignore *ignore = temp->data;

		mask = ignore->mask;
		chan = (ignore->type & IG_CHAN);
		private = (ignore->type & IG_PRIV);
		notice = (ignore->type & IG_NOTI);
		ctcp = (ignore->type & IG_CTCP);
		dcc = (ignore->type & IG_DCC);
		invite = (ignore->type & IG_INVI);
		unignore = (ignore->type & IG_UNIG);

		gtk_list_store_append (store, &iter);
		gtk_list_store_set (store, &iter,
		                    MASK_COLUMN, mask,
		                    CHAN_COLUMN, chan,
		                    PRIV_COLUMN, private,
		                    NOTICE_COLUMN, notice,
		                    CTCP_COLUMN, ctcp,
		                    DCC_COLUMN, dcc,
		                    INVITE_COLUMN, invite,
		                    UNIGNORE_COLUMN, unignore,
		                    -1);
		
		temp = temp->next;
	}
	gtk_widget_show (ignorewin);
}

void
fe_ignore_update (int level)
{
	/* some ignores have changed via /ignore, we should update
	   the gui now */
	/* level 1 = the list only. */
	/* level 2 = the numbers only. */
	/* for now, ignore level 1, since the ignore GUI isn't realtime,
	   only saved when you click OK */
	char buf[16];

	if (level == 2 && ignorewin)
	{
		sprintf (buf, "%d", ignored_ctcp);
		gtk_entry_set_text (GTK_ENTRY (num_ctcp), buf);

		sprintf (buf, "%d", ignored_noti);
		gtk_entry_set_text (GTK_ENTRY (num_noti), buf);

		sprintf (buf, "%d", ignored_chan);
		gtk_entry_set_text (GTK_ENTRY (num_chan), buf);

		sprintf (buf, "%d", ignored_invi);
		gtk_entry_set_text (GTK_ENTRY (num_invi), buf);

		sprintf (buf, "%d", ignored_priv);
		gtk_entry_set_text (GTK_ENTRY (num_priv), buf);
	}
}