/*
* marking.c -- Actions on multiple buddies
*
* Copyright (C) 2009-2012 Myhailo Danylenko <isbear@ukrpost.net>
* Copyright (C) 2012 Mikael Berthe <mikael@lilotux.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\n" \
"Provides commands /mark and /marked" )
module_info_t info_marking = {
.branch = MCABBER_BRANCH,
.api = MCABBER_API_VERSION,
.version = PROJECT_VERSION,
.description = DESCRIPTION,
.requires = NULL,
.init = marking_init,
.uninit = marking_uninit,
.next = NULL,
};
#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;
guint len;
if (args[0]) {
cmd = args[0];
if (args[1]) {
const char *j = args[1];
if (check_jid_syntax(j)) {
scr_log_print(LPRINT_NORMAL|LPRINT_NOTUTF8,
"<%s> is not a valid Jabber ID.", j);
return;
}
jid = g_strdup(j);
if (!jid) {
scr_log_print (LPRINT_NORMAL|LPRINT_NOTUTF8,
"Unexpected error.");
return;
}
jfree = TRUE;
}
} else
cmd = "set";
if (!jid) {
// JID was not provided
const char *j = NULL;
if (current_buddy)
j = CURRENT_JID;
if (!j) {
scr_log_print (LPRINT_NORMAL, "No buddy is currently selected.");
return;
}
jid = g_strdup (j);
jfree = TRUE;
}
if (!strcmp (cmd, "set")) {
if (!g_slist_find_custom (marked_jids, jid, (GCompareFunc) g_strcmp0)) {
marked_jids = g_slist_append (marked_jids, jid);
marked = 1;
jfree = FALSE;
}
} else if (!strcmp (cmd, "clear")) {
GSList *mel = g_slist_find_custom (marked_jids, jid, (GCompareFunc) g_strcmp0);
if (mel) {
g_free (mel->data);
marked_jids = g_slist_delete_link (marked_jids, mel);
marked = 0;
}
} else if (!strcmp (cmd, "toggle")) {
GSList *mel = g_slist_find_custom (marked_jids, jid, (GCompareFunc) g_strcmp0);
if (mel) {
g_free (mel->data);
marked_jids = g_slist_delete_link (marked_jids, mel);
marked = 0;
} else {
marked_jids = g_slist_append (marked_jids, jid);
marked = 1;
jfree = FALSE;
}
}
len = g_slist_length(marked_jids);
if (marked == 1) {
scr_write_incoming_message (jid, "Marked", 0,
HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0);
} else if (marked == 0) {
scr_write_incoming_message (jid, "Mark cleared", 0,
HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0);
}
if (marked >= 0) {
scr_log_print (LPRINT_NORMAL, "<%s> is now %s (%u mark%s).", jid,
marked == 1 ? "marked" : "unmarked",
len, len > 1 ? "s" : "");
}
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;
guint len = g_slist_length (marked_jids);
if (!marked_jids) {
scr_log_print (LPRINT_NORMAL, "No marked JIDs.");
} else {
scr_log_print (LPRINT_NORMAL, "%d marked JIDs:", len);
for (mel = marked_jids; mel; mel = mel->next) {
char *jid = (char *) mel->data;
scr_log_print (LPRINT_NORMAL, " * %s", jid);
}
// XXX Smartly set the status flag if we have more marks than the log
// window height.
if (len + 1 > scr_getlogwinheight()) {
scr_setmsgflag_if_needed(SPECIAL_BUFFER_STATUS_ID, TRUE);
scr_setattentionflag_if_needed(SPECIAL_BUFFER_STATUS_ID, TRUE,
ROSTER_UI_PRIO_STATUS_WIN_MESSAGE, prio_max);
}
}
} 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 %%-sequences!");
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: */