/pidgin/main: ef161f30f8bc: Add PurpleCommandsUiOps API from ins...

Florian Qu?ze florian at instantbird.org
Wed Jun 15 23:05:08 EDT 2016


Changeset: ef161f30f8bcfa29262cf320f6938f36cc512289
Author:	 Florian Qu?ze <florian at instantbird.org>
Date:	 2016-05-15 18:53 -0300
Branch:	 release-2.x.y
URL: https://hg.pidgin.im/pidgin/main/rev/ef161f30f8bc

Description:

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

diffstat:

 ChangeLog.API    |   2 +
 libpurple/cmds.c |  62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 libpurple/cmds.h |  61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 123 insertions(+), 2 deletions(-)

diffs (221 lines):

diff --git a/ChangeLog.API b/ChangeLog.API
--- a/ChangeLog.API
+++ b/ChangeLog.API
@@ -5,6 +5,8 @@ version 2.11.0:
 		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
diff --git a/libpurple/cmds.c b/libpurple/cmds.c
--- a/libpurple/cmds.c
+++ b/libpurple/cmds.c
@@ -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 @@ typedef struct _PurpleCmd {
 	PurpleCmdFunc func;
 	gchar *help;
 	void *data;
-} PurpleCmd;
+};
 
 
 static gint cmds_compare_func(const PurpleCmd *a, const PurpleCmd *b)
@@ -59,6 +60,7 @@ PurpleCmdId purple_cmd_register(const gc
 {
 	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 @@ PurpleCmdId purple_cmd_register(const gc
 
 	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 @@ void purple_cmd_unregister(PurpleCmdId i
 		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 @@ PurpleCmdStatus purple_cmd_do_command(Pu
 
 }
 
+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 @@ gpointer purple_cmds_get_handle(void)
 	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();
diff --git a/libpurple/cmds.h b/libpurple/cmds.h
--- a/libpurple/cmds.h
+++ b/libpurple/cmds.h
@@ -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 @@ typedef enum _PurpleCmdFlag {
 	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 @@ PurpleCmdStatus purple_cmd_do_command(Pu
                                   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 @@ GList *purple_cmd_help(PurpleConversatio
 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
  */



More information about the Commits mailing list