marking.c
author Myhailo Danylenko <isbear@ukrpost.net>
Thu, 30 Jun 2011 16:13:59 +0300
changeset 21 66ece9145926
parent 19 c7e7218be611
child 22 cbae62eecb1d
permissions -rw-r--r--
Remove api.h


/*
 * marking.c            -- Actions on multiple buddies
 *
 * Copyrigth (C) 2009      Myhailo Danylenko <isbear@ukrpost.net>
 *
 * 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 <glib.h>
#include <string.h>

#include <mcabber/hbuf.h>
#include <mcabber/screen.h>
#include <mcabber/commands.h>
#include <mcabber/compl.h>
#include <mcabber/utils.h>
#include <mcabber/logprint.h>
#include <mcabber/modules.h>

#include "config.h"

void marking_init   (void);
void marking_uninit (void);

#define DESCRIPTION ( "Actions on multiple marked buddies\nProvides commands /mark and /marked" )

static module_info_t info_marking_dev = {
	.branch      = "dev",
	.api         = 20,
	.version     = PROJECT_VERSION,
	.description = DESCRIPTION,
	.requires    = NULL,
	.init        = marking_init,
	.uninit      = marking_uninit,
	.next        = NULL,
};

module_info_t info_marking = {
	.branch      = "0.10.1",
	.api         = 1,
	.version     = PROJECT_VERSION,
	.description = DESCRIPTION,
	.requires    = NULL,
	.init        = marking_init,
	.uninit      = marking_uninit,
	.next        = &info_marking_dev,
};

#ifdef MCABBER_API_HAVE_CMD_ID
static gpointer mark_cmid   = NULL;
static gpointer marked_cmid = NULL;
#endif

static GSList *marked_jids = NULL;

// mark set jid
// mark clear jid
// mark toggle jid
static void do_mark (char *arg)
{
	char     **args   = split_arg (arg, 2, 1);
	char      *cmd    = NULL;
	char      *jid    = NULL;
	gboolean   jfree  = FALSE;
	int        marked = -1;

	if (args[0]) {
		cmd = args[0];

		if (args[1])
			jid = jidtodisp (args[1]);
	} else
		cmd = "set";
	
	if (!strcmp (cmd, "set")) {

		if (!g_slist_find_custom (marked_jids, jid ? jid : CURRENT_JID, (GCompareFunc) g_strcmp0)) {
			marked_jids = g_slist_append (marked_jids, jid ? jid : g_strdup (CURRENT_JID));
			marked = 1;
		} else
			jfree = TRUE;

	} else if (!strcmp (cmd, "clear")) {

		GSList *mel = g_slist_find_custom (marked_jids, jid ? jid : CURRENT_JID, (GCompareFunc) g_strcmp0);

		if (mel) {
			g_free (mel->data);
			marked_jids = g_slist_delete_link (marked_jids, mel);
			marked = 0;
		}

		jfree = TRUE;

	} else if (!strcmp (cmd, "toggle")) {

		GSList *mel = g_slist_find_custom (marked_jids, jid ? jid : CURRENT_JID, (GCompareFunc) g_strcmp0);

		if (mel) {
			g_free (mel->data);
			marked_jids = g_slist_delete_link (marked_jids, mel);
			marked = 0;
			jfree  = TRUE;
		} else {
			marked_jids = g_slist_append (marked_jids, jid ? jid : g_strdup (CURRENT_JID));
			marked = 1;
		}
	}

	if (marked == 1)
		scr_write_incoming_message (jid ? jid : CURRENT_JID, "Marked", 0, HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0);
	else if (marked == 0)
		scr_write_incoming_message (jid ? jid : CURRENT_JID, "Mark cleared", 0, HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0);

	if (jfree && jid)
		g_free (jid);

	free_arg_lst (args);
}

// marked clear
// marked do cmd
void do_marked (char *arg)
{
	char **args = split_arg (arg, 2, 1);
	char  *cmd = args[0];

	if (!cmd)
		cmd = "list";

	if (!strcmp (cmd, "list")) {

		GSList *mel;

		scr_log_print (LPRINT_NORMAL, "Marked jids:");
		for (mel = marked_jids; mel; mel = mel->next) {
			char *jid = (char *) mel->data;
			scr_log_print (LPRINT_NORMAL, " * %s", jid);
		}

	} else if (!strcmp (cmd, "clear")) {

		GSList *mel;

		for (mel = marked_jids; mel; mel = mel->next)
			g_free (mel->data);

		g_slist_free (marked_jids);
		marked_jids = NULL;

	} else if (!strcmp (cmd, "do")) {
		char *format = args[1];

		if (!format)
			scr_log_print (LPRINT_NORMAL, "You must specify action to do with marked jids");
		else {
			char     *pos   = format;
			gboolean  found = FALSE;
			gboolean  error = FALSE;

			for (pos = strchr (pos, '%'); pos; pos = strchr (pos, '%')) {
				if (*(pos + 1) == 's')
					found = TRUE;
				else if (*(pos + 1) == '%')
					++pos;
				else {
					scr_log_print (LPRINT_NORMAL, "Action string must not contain any other %%-sequesnces!");
					error = TRUE;
					break;
				}

				++pos;
			}

			if (!found)
				scr_log_print (LPRINT_NORMAL, "Action string must contain one %%s!");
			else if (!error) {
				GSList *mel;

				for (mel = marked_jids; mel; mel = mel->next) {
					char *jid     = (char *) mel->data;
					char *command = g_strdup_printf (format, jid);
					process_command (command, TRUE);
					g_free (command);
				}
			}
		}
	}

	free_arg_lst (args);
}

void marking_init (void)
{
#ifndef MCABBER_API_HAVE_CMD_ID
	cmd_add ("mark", "", 0, COMPL_JID, do_mark, NULL);
	cmd_add ("marked", "", 0, COMPL_CMD, do_marked, NULL);
#else
	mark_cmid   = cmd_add ("mark", "", 0, COMPL_JID, do_mark, NULL);
	marked_cmid = cmd_add ("marked", "", 0, COMPL_CMD, do_marked, NULL);
#endif
}

void marking_uninit (void)
{
#ifndef MCABBER_API_HAVE_CMD_ID
	cmd_del ("mark");
	cmd_del ("marked");
#else
	if (mark_cmid)
		cmd_del (mark_cmid);
	if (marked_cmid)
		cmd_del (marked_cmid);
#endif

	{
		GSList *mel;

		for (mel = marked_jids; mel; mel = mel->next)
			g_free (mel->data);

		g_slist_free (marked_jids);
		marked_jids = NULL;
	}
}

/* vim: se ts=4 sw=4: */