pidgin/pidgin

Add PurpleCommandsUiOps API from instantbird
release-2.x.y
2016-05-15, Florian Quèze
ef161f30f8bc
Parents 5e5e84e8a798
Children 403b13cb3a47
Add PurpleCommandsUiOps API from instantbird

This allows the UI to override the built-in handling of commands.

Instantbird ticket: https://bugzilla.mozilla.org/show_bug.cgi?id=953569
--- a/ChangeLog.API Sun May 15 05:41:39 2016 -0300
+++ b/ChangeLog.API Sun May 15 18:53:55 2016 -0300
@@ -5,6 +5,8 @@
Added:
* account-status-changing signal (account signals)
* buddy-removed-from-group signal (blist signals)
+ * PurpleCommandsUiOps, to allow the UI to override the
+ built-in handling of commands.
version 2.10.12:
* No changes
--- a/libpurple/cmds.c Sun May 15 05:41:39 2016 -0300
+++ b/libpurple/cmds.c Sun May 15 18:53:55 2016 -0300
@@ -27,10 +27,11 @@
#include "util.h"
#include "cmds.h"
+static PurpleCommandsUiOps *cmds_ui_ops = NULL;
static GList *cmds = NULL;
static guint next_id = 1;
-typedef struct _PurpleCmd {
+struct _PurpleCmd {
PurpleCmdId id;
gchar *cmd;
gchar *args;
@@ -40,7 +41,7 @@
PurpleCmdFunc func;
gchar *help;
void *data;
-} PurpleCmd;
+};
static gint cmds_compare_func(const PurpleCmd *a, const PurpleCmd *b)
@@ -59,6 +60,7 @@
{
PurpleCmdId id;
PurpleCmd *c;
+ PurpleCommandsUiOps *ops;
g_return_val_if_fail(cmd != NULL && *cmd != '\0', 0);
g_return_val_if_fail(args != NULL, 0);
@@ -79,6 +81,10 @@
cmds = g_list_insert_sorted(cmds, c, (GCompareFunc)cmds_compare_func);
+ ops = purple_cmds_get_ui_ops();
+ if (ops && ops->register_command)
+ ops->register_command(cmd, p, f, prpl_id, helpstr, c);
+
purple_signal_emit(purple_cmds_get_handle(), "cmd-added", cmd, p, f);
return id;
@@ -102,6 +108,10 @@
c = l->data;
if (c->id == id) {
+ PurpleCommandsUiOps *ops = purple_cmds_get_ui_ops();
+ if (ops && ops->unregister_command)
+ ops->unregister_command(c->cmd, c->prpl_id);
+
cmds = g_list_remove(cmds, c);
purple_signal_emit(purple_cmds_get_handle(), "cmd-removed", c->cmd);
purple_cmd_free(c);
@@ -301,6 +311,39 @@
}
+gboolean purple_cmd_execute(PurpleCmd *c, PurpleConversation *conv,
+ const gchar *cmdline)
+{
+ gchar *err = NULL;
+ gchar **args = NULL;
+ PurpleCmdRet ret = PURPLE_CMD_RET_CONTINUE;
+
+ if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
+ if (!(c->flags & PURPLE_CMD_FLAG_IM))
+ return FALSE;
+ }
+ else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
+ if (!(c->flags & PURPLE_CMD_FLAG_CHAT))
+ return FALSE;
+ }
+ else
+ return FALSE;
+
+ /* XXX: Don't worry much about the markup version of the command
+ line, there's not a single use case... */
+ /* this checks the allow bad args flag for us */
+ if (!purple_cmd_parse_args(c, cmdline, cmdline, &args)) {
+ g_strfreev(args);
+ return FALSE;
+ }
+
+ ret = c->func(conv, c->cmd, args, &err, c->data);
+
+ g_free(err);
+ g_strfreev(args);
+
+ return ret == PURPLE_CMD_RET_OK;
+}
GList *purple_cmd_list(PurpleConversation *conv)
{
@@ -368,6 +411,21 @@
return &handle;
}
+void
+purple_cmds_set_ui_ops(PurpleCommandsUiOps *ops)
+{
+ cmds_ui_ops = ops;
+}
+
+PurpleCommandsUiOps *
+purple_cmds_get_ui_ops(void)
+{
+ /* It is perfectly acceptable for cmds_ui_ops to be NULL; this just
+ * means that the default libpurple implementation will be used.
+ */
+ return cmds_ui_ops;
+}
+
void purple_cmds_init(void)
{
gpointer handle = purple_cmds_get_handle();
--- a/libpurple/cmds.h Sun May 15 05:41:39 2016 -0300
+++ b/libpurple/cmds.h Sun May 15 18:53:55 2016 -0300
@@ -31,6 +31,8 @@
/**************************************************************************/
/*@{*/
+typedef struct _PurpleCmd PurpleCmd;
+
/** The possible results of running a command with purple_cmd_do_command(). */
typedef enum _PurpleCmdStatus {
PURPLE_CMD_STATUS_OK,
@@ -96,6 +98,31 @@
PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS = 0x08
} PurpleCmdFlag;
+/**
+ * Command UI operations; UIs should implement this if they want to handle
+ * commands themselves, rather than relying on the core.
+ *
+ * @see @ref ui-ops
+ */
+typedef struct
+{
+ /** If implemented, the UI is responsible for handling commands. */
+ /* @see purple_cmd_register for the argument values. */
+ void (*register_command)(const gchar *name, PurpleCmdPriority p,
+ PurpleCmdFlag f, const gchar *prpl_id,
+ const gchar *helpstr, PurpleCmd *cmd);
+
+ /** Should be implemented if register_command is implemented.
+ * name and prpl_id should have the same value that were used
+ * for the register_command call.
+ */
+ void (*unregister_command)(const gchar *name, const gchar *prpl_id);
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+} PurpleCommandsUiOps;
/*@}*/
@@ -194,6 +221,23 @@
const gchar *markup, gchar **errormsg);
/**
+ * Execute a specific command.
+ *
+ * The UI calls this to execute a command, after parsing the
+ * command name.
+ *
+ * @param c The command to execute.
+ * @param conv The conversation the command was typed in.
+ * @param cmdline The command the user typed (only the arguments).
+ * The caller should remove the prefix and the command name.
+ * It should not contain any formatting, and should be
+ * in plain text (no html entities).
+ * @return TRUE if the command handled the cmdline, FALSE otherwise.
+ */
+gboolean purple_cmd_execute(PurpleCmd *c, PurpleConversation *conv,
+ const gchar *cmdline);
+
+/**
* List registered commands.
*
* Returns a <tt>GList</tt> (which must be freed by the caller) of all commands
@@ -230,6 +274,23 @@
gpointer purple_cmds_get_handle(void);
/**
+ * Sets the UI operations structure to be used when registering and
+ * unregistering commands. The UI operations need only be set if the
+ * UI wants to handle the commands itself; otherwise, leave it as NULL.
+ *
+ * @param ops The UI operations structure.
+ */
+void purple_cmds_set_ui_ops(PurpleCommandsUiOps *ops);
+
+/**
+ * Returns the UI operations structure to be used when registering and
+ * unregistering commands.
+ *
+ * @return The UI operations structure.
+ */
+PurpleCommandsUiOps *purple_cmds_get_ui_ops(void);
+
+/**
* Initialize the commands subsystem.
* @since 2.5.0
*/