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

Florian Qu?ze <[email protected]>
Newsgroups gmane.comp.gnome.gaim.cvs
Message-ID <[email protected]>
Changeset: ef161f30f8bcfa29262cf320f6938f36cc512289
Author:	 Florian Qu?ze <[email protected]>
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
  */

_______________________________________________
Commits mailing list
[email protected]
https://pidgin.im/cgi-bin/mailman/listinfo/commits
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.