soc.2009.transport: 7ec6bcf4: clean code

hanzz at soc.pidgin.im hanzz at soc.pidgin.im
Sun Jul 26 12:45:46 EDT 2009


-----------------------------------------------------------------
Revision: 7ec6bcf44deaaa86605398cf212074ba4f48f50c
Ancestor: e57dbfc55599f243a2185a268826f080d6a62bfc
Author: hanzz at soc.pidgin.im
Date: 2009-07-26T14:58:09
Branch: im.pidgin.soc.2009.transport
URL: http://d.pidgin.im/viewmtn/revision/info/7ec6bcf44deaaa86605398cf212074ba4f48f50c

Modified files:
        adhochandler.cpp adhochandler.h adhocrepeater.cpp
        adhocrepeater.h adhocsettings.h main.cpp

ChangeLog: 

clean code

-------------- next part --------------
============================================================
--- adhochandler.cpp	a5cd707dc7750bd7b8ee2d2071d9cc6a1d03d6a4
+++ adhochandler.cpp	66e5364e945316b7efcce4a3bb0d4f8de8c84b16
@@ -51,69 +51,77 @@ StringList GlooxAdhocHandler::handleDisc
 	return features;
 }
 
+/*
+ * Returns ItemList which contains list of available commands
+ */
 Disco::ItemList GlooxAdhocHandler::handleDiscoNodeItems( const JID &_from, const JID &_to, const std::string& node ) {
 	Disco::ItemList lst;
 	std::string from = _from.bare();
 	std::string to = _to.bare();
 	Log().Get("GlooxAdhocHandler") << "items" << from << to;
-// 	if (node.empty()) {
-// 		lst.push_back( new Disco::Item( main->jid(), XMLNS_ADHOC_COMMANDS, "Ad-Hoc Commands" ) );
-// 	}
-// 	else if (node == XMLNS_ADHOC_COMMANDS) {
-		if (to == main->jid()) {
-			User *user = main->userManager()->getUserByJID(from);
-			if (user) {
-				for(std::map<std::string, adhocCommand>::iterator u = m_handlers.begin(); u != m_handlers.end() ; u++) {
-					lst.push_back( new Disco::Item( main->jid(), (*u).first, (std::string) tr(user->getLang(), (*u).second.name) ) );
-				}
-				if (user->isConnected() && purple_account_get_connection(user->account())) {
-					PurpleConnection *gc = purple_account_get_connection(user->account());
-					PurplePlugin *plugin = gc && PURPLE_CONNECTION_IS_CONNECTED(gc) ? gc->prpl : NULL;
-					if (plugin && PURPLE_PLUGIN_HAS_ACTIONS(plugin)) {
-						PurplePluginAction *action = NULL;
-						GList *actions, *l;
 
-						actions = PURPLE_PLUGIN_ACTIONS(plugin, gc);
+	// it's adhoc request for transport
+	if (to == main->jid()) {
+		User *user = main->userManager()->getUserByJID(from);
+		if (user) {
+			// add internal commands from m_handlers
+			for(std::map<std::string, adhocCommand>::iterator u = m_handlers.begin(); u != m_handlers.end() ; u++) {
+				lst.push_back( new Disco::Item( main->jid(), (*u).first, (std::string) tr(user->getLang(), (*u).second.name) ) );
+			}
+			// add commands from libpurple
+			if (user->isConnected() && purple_account_get_connection(user->account())) {
+				PurpleConnection *gc = purple_account_get_connection(user->account());
+				PurplePlugin *plugin = gc && PURPLE_CONNECTION_IS_CONNECTED(gc) ? gc->prpl : NULL;
+				if (plugin && PURPLE_PLUGIN_HAS_ACTIONS(plugin)) {
+					PurplePluginAction *action = NULL;
+					GList *actions, *l;
 
-						for (l = actions; l != NULL; l = l->next) {
-							if (l->data) {
-								action = (PurplePluginAction *) l->data;
-								lst.push_back( new Disco::Item( main->jid(), "transport_" + (std::string) action->label,(std::string) tr(user->getLang(), action->label) ) );
-								purple_plugin_action_free(action);
-							}
+					actions = PURPLE_PLUGIN_ACTIONS(plugin, gc);
+
+					for (l = actions; l != NULL; l = l->next) {
+						if (l->data) {
+							action = (PurplePluginAction *) l->data;
+							// we are using "transport_" prefix here to identify command in disco#info handler
+							// it's ugly and we're bastards, but it's the easy solution
+							lst.push_back( new Disco::Item( main->jid(), "transport_" + (std::string) action->label,(std::string) tr(user->getLang(), action->label) ) );
+							purple_plugin_action_free(action);
 						}
 					}
 				}
 			}
 		}
-		else {
-			User *user = main->userManager()->getUserByJID(from);
-			if (user) {
-				if (user->isConnected() && purple_account_get_connection(user->account())) {
-					Log().Get("GlooxAdhocHandler") << user->getLang();
-					GList *l, *ll;
-					PurpleConnection *gc = purple_account_get_connection(user->account());
-					PurplePlugin *plugin = gc && PURPLE_CONNECTION_IS_CONNECTED(gc) ? gc->prpl : NULL;
-					PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin);
+	}
+	// it's request for some PurpleBuddy
+	else {
+		User *user = main->userManager()->getUserByJID(from);
+		if (user) {
+			if (user->isConnected() && purple_account_get_connection(user->account())) {
+				Log().Get("GlooxAdhocHandler") << user->getLang();
+				GList *l, *ll;
+				PurpleConnection *gc = purple_account_get_connection(user->account());
+				PurplePlugin *plugin = gc && PURPLE_CONNECTION_IS_CONNECTED(gc) ? gc->prpl : NULL;
+				PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin);
 
-					if(!prpl_info || !prpl_info->blist_node_menu)
-						return lst;
-					std::string name(JID(to).username());
-					std::for_each( name.begin(), name.end(), replaceJidCharacters() );
-					PurpleBuddy *buddy = purple_find_buddy(user->account(), name.c_str());
+				if(!prpl_info || !prpl_info->blist_node_menu)
+					return lst;
+				std::string name(JID(to).username());
+				std::for_each( name.begin(), name.end(), replaceJidCharacters() );
+				PurpleBuddy *buddy = purple_find_buddy(user->account(), name.c_str());
 
-					for(l = ll = prpl_info->blist_node_menu((PurpleBlistNode*)buddy); l; l = l->next) {
-						PurpleMenuAction *action = (PurpleMenuAction *) l->data;
-						lst.push_back( new Disco::Item( _to.bare(), "transport_" + (std::string) action->label, (std::string) tr(user->getLang(), action->label) ) );
-						purple_menu_action_free(action);
-					}
+				for(l = ll = prpl_info->blist_node_menu((PurpleBlistNode*)buddy); l; l = l->next) {
+					PurpleMenuAction *action = (PurpleMenuAction *) l->data;
+					lst.push_back( new Disco::Item( _to.bare(), "transport_" + (std::string) action->label, (std::string) tr(user->getLang(), action->label) ) );
+					purple_menu_action_free(action);
 				}
 			}
 		}
-// 	}
+	}
 	return lst;
 }
 
+/*
+ * Returns IdentityList (copied from Gloox :) )
+ */
 Disco::IdentityList GlooxAdhocHandler::handleDiscoNodeIdentities( const JID& jid, const std::string& node ) {
 	Disco::IdentityList l;
 	l.push_back( new Disco::Identity( "automation",node == XMLNS_ADHOC_COMMANDS ? "command-list" : "command-node",node == XMLNS_ADHOC_COMMANDS ? "Ad-Hoc Commands" : "") );
@@ -136,8 +144,10 @@ bool GlooxAdhocHandler::handleIq( const 
 
 	User *user = main->userManager()->getUserByJID(from);
 	if (user) {
+		// check if we have existing session for this jid
 		if (hasSession(stanza.from().full())) {
 			if( m_sessions[stanza.from().full()]->handleIq(stanza) ) {
+				// AdhocCommandHandler returned true, so we should remove it
 				std::string jid = stanza.from().full();
 				delete m_sessions[jid];
 				unregisterSession(jid);
@@ -145,12 +155,14 @@ bool GlooxAdhocHandler::handleIq( const 
 			delete stanzaTag;
 			return true;
 		}
+		// check if we have registered handler for this node and create AdhocCommandHandler class
 		else if (m_handlers.find(node) != m_handlers.end()) {
 			AdhocCommandHandler *handler = m_handlers[node].createHandler(main, user, stanza.from().full(), stanza.id());
 			registerSession(stanza.from().full(), handler);
 			delete stanzaTag;
 			return true;
 		}
+		// if it's PurpleAction, so we don't have handler for it, we have to execute the action here.
 		if (user->isConnected() && purple_account_get_connection(user->account())) {
 			if (to == main->jid()) {
 				PurpleConnection *gc = purple_account_get_connection(user->account());
@@ -229,8 +241,7 @@ bool GlooxAdhocHandler::hasSession(const
 	return false;
 }
 
-void GlooxAdhocHandler::handleIqID( const IQ &iq, int context ) {
-}
+void GlooxAdhocHandler::handleIqID( const IQ &iq, int context ) {}
 
 void GlooxAdhocHandler::handleDiscoInfo(const JID &jid, const Disco::Info &info, int context) {
 	Log().Get("handle disco info adhoc") << jid.full();
============================================================
--- adhochandler.h	0949f16231e286dc210d600ade72a82478a1bf8e
+++ adhochandler.h	c234c51fe7c0baf9199404acfae5efeca82b17f0
@@ -31,8 +31,13 @@ class AdhocRepeater;
 class GlooxMessageHandler;
 class AdhocRepeater;
 
+
+/*
+ * Structure used for registering Ad-Hoc command
+ */
 struct adhocCommand {
-	std::string name;
+	std::string name;	// command's name
+	// function which creates AdhocCommandHandler class which will be used as handler for this command
 	AdhocCommandHandler * (*createHandler)(GlooxMessageHandler *m, User *user, const std::string &from, const std::string &id);
 };
 
@@ -54,9 +59,9 @@ class GlooxAdhocHandler : public DiscoNo
 		bool hasSession(const std::string &jid);
 
 	private:
-		GlooxMessageHandler *main;
-		std::map<std::string, AdhocCommandHandler *> m_sessions;
-		std::map<std::string, adhocCommand> m_handlers;	// m_handlers[node] = handler
+		GlooxMessageHandler *main;									// client
+		std::map<std::string, AdhocCommandHandler *> m_sessions;	// sessions (m_sessions[full_jid] = handler)
+		std::map<std::string, adhocCommand> m_handlers;				// handlers (m_handlers[node] = handler)
 
 };
 
============================================================
--- adhocrepeater.cpp	8f90c89c1588aed6da5e9a12cb07ded9d4e759b0
+++ adhocrepeater.cpp	14e2b6616e967f4e72d66083111c7036d417cbc2
@@ -22,7 +22,7 @@
 #include "gloox/stanza.h"
 #include "log.h"
 #include "dataforms.h"
- 
+
 static gboolean removeRepeater(gpointer data){
 	AdhocRepeater *repeater = (AdhocRepeater*) data;
 	purple_request_close(repeater->type(),repeater);
@@ -42,6 +42,7 @@ AdhocRepeater::AdhocRepeater(GlooxMessag
 	setType(PURPLE_REQUEST_INPUT);
 	setRequestType(CALLER_ADHOC);
 	
+	// generate IQ-result for IQ-get (that IQ-get is handled in AdhocHandler class)
 	IQ _response(IQ::Result, data.from, data.id);
 	Tag *response = _response.tag();
 	response->addAttribute("from",main->jid());
@@ -63,7 +64,6 @@ AdhocRepeater::AdhocRepeater(GlooxMessag
 	
 	response->addChild(c);
 	main->j->send(response);
-
 }
 
 AdhocRepeater::AdhocRepeater(GlooxMessageHandler *m, User *user, const std::string &title, const std::string &primaryString, const std::string &secondaryString, int default_action, void * user_data, size_t action_count, va_list acts) {
@@ -86,6 +86,7 @@ AdhocRepeater::AdhocRepeater(GlooxMessag
 //         <option label='None'><value>none</value></option>
 //       </field>
 
+	// generate IQ-result for IQ-get (that IQ-get is handled in AdhocHandler class)
 	IQ _response(IQ::Result, data.from, data.id);
 	Tag *response = _response.tag();
 	response->addAttribute("from",main->jid());
@@ -101,6 +102,7 @@ AdhocRepeater::AdhocRepeater(GlooxMessag
 	actions->addChild(new Tag("complete"));
 	c->addChild(actions);
 
+	// save action to m_actions; only keys will be saved
 	for (unsigned int i = 0; i < action_count; i++)
 		m_actions[i] = va_arg(acts, GCallback);
 
@@ -122,6 +124,7 @@ AdhocRepeater::AdhocRepeater(GlooxMessag
 	m_from = data.from;
 	setRequestType(CALLER_ADHOC);
 	
+	// generate IQ-result for IQ-get (that IQ-get is handled in AdhocHandler class)
 	IQ _response(IQ::Result, data.from, data.id);
 	Tag *response = _response.tag();
 	response->addAttribute("from",main->jid());
@@ -148,6 +151,8 @@ bool AdhocRepeater::handleIq(const IQ &s
 	Tag *stanzaTag = stanza.tag();
 	if (!stanzaTag) return false;
 	Tag *tag = stanzaTag->findChild( "command" );
+	
+	// check if user canceled request
 	if (tag->hasAttribute("action","cancel")){
 		IQ _response(IQ::Result, stanza.from().full(), stanza.id());
 		_response.setFrom(main->jid());
============================================================
--- adhocrepeater.h	40b068f03ab1792cd7fd1455490a55bba621949f
+++ adhocrepeater.h	2f89a14d0aecad181b05da74b7a3fd22f16e7c34
@@ -31,6 +31,9 @@ class User;
 class GlooxMessageHandler;
 class User;
 
+/*
+ * Handler for PURPLE_REQUESTs. It handles different requests and resends them as Ad-Hoc commands.
+ */
 class AdhocRepeater : public AdhocCommandHandler
 {
 	public:
@@ -42,21 +45,22 @@ class AdhocRepeater : public AdhocComman
 		AdhocRepeater(GlooxMessageHandler *m, User *user, const std::string &title, const std::string &primaryString, const std::string &secondaryString, PurpleRequestFields *fields, GCallback ok_cb, GCallback cancel_cb, void * user_data);
 		~AdhocRepeater();
 		bool handleIq(const IQ &iq);
+		
 		void setType(PurpleRequestType t) { m_type = t; }
 		PurpleRequestType type() { return m_type; }
 		std::string & from() { return m_from; }
 	
 	private:
-		GlooxMessageHandler *main;
-		User *m_user;
-		void *m_requestData;
-		GCallback m_ok_cb;
-		GCallback m_cancel_cb;
-		PurpleRequestType m_type;
-		std::string m_from;
-		std::map<int, GCallback> m_actions;
-		PurpleRequestFields *m_fields;
-		std::string m_defaultString;
+		GlooxMessageHandler *main;				// client
+		User *m_user;							// User to which Ad-Hoc are sent
+		void *m_requestData;					// user_data from PURPLE_REQUEST
+		GCallback m_ok_cb;						// callback which is called when user accepts the dialog
+		GCallback m_cancel_cb;					// callback which is called when user rejects the dialog
+		PurpleRequestType m_type;				// type of request
+		std::string m_from;						// full jid from which initial IQ-get was sent
+		std::map<int, GCallback> m_actions;		// callbacks for PURPLE_REQUEST_ACTION
+		PurpleRequestFields *m_fields;			// fields for PURPLE_REQUEST_FIELDS
+		std::string m_defaultString;			// default value of PURPLE_REQUEST_INPUT
 };
 
 #endif
============================================================
--- adhocsettings.h	7440af0914d36c4159d6a102869c842914d004e6
+++ adhocsettings.h	42682d946fff5fbe3d29e84fcb4e1f826c142d98
@@ -31,6 +31,9 @@ class User;
 class GlooxMessageHandler;
 class User;
 
+/*
+ * AdhocCommandHandler for Transport Settings node
+ */
 class AdhocSettings : public AdhocCommandHandler
 {
 	public:
@@ -40,9 +43,9 @@ class AdhocSettings : public AdhocComman
 		std::string & from() { return m_from; }
 	
 	private:
-		GlooxMessageHandler *main;
-		std::string m_from;
-		User *m_user;
+		GlooxMessageHandler *main;		// client
+		std::string m_from;				// full jid
+		User *m_user;					// User class
 };
 
 #endif
============================================================
--- main.cpp	9d69471f3c73c3017421205f7951fc56c4ba3a6d
+++ main.cpp	9b77fd795f12e2a59252ac0c0426133f5cf07340
@@ -48,58 +48,50 @@ namespace gloox {
 #include <gloox/compressionbase.h>
 
 namespace gloox {
-    class HiComponent : public Component {
-    public:
-        HiComponent(const std::string & ns, const std::string & server,
-                    const std::string & component, const std::string & password,
-                    int port = 5347)
-            : Component(ns, server, component, password, port)
-        {
-        };
+	class HiComponent : public Component {
+		public:
+			HiComponent(const std::string & ns, const std::string & server, const std::string & component, const std::string & password, int port = 5347) : Component(ns, server, component, password, port) {};
 
-        virtual ~HiComponent() {};
+			virtual ~HiComponent() {};
 
-        virtual void send(Tag *tag) // unfortunately we can't override const std::string variant
-        {
-            std::string tagxml;
-            std::string outxml;
-            if (!tag)
-             return;
+			// unfortunately we can't override const std::string variant
+			virtual void send(Tag *tag) {
+				std::string tagxml;
+				std::string outxml;
+				if (!tag)
+					return;
 
-            try {
-                tagxml = tag->xml();
-                outxml.resize(tagxml.size(), 0);
+				try {
+					tagxml = tag->xml();
+					outxml.resize(tagxml.size(), 0);
 
-                // replace invalid utf-8 characters
-                utf8::replace_invalid(tagxml.begin(), tagxml.end(), outxml.begin(), '?');
+					// replace invalid utf-8 characters
+					utf8::replace_invalid(tagxml.begin(), tagxml.end(), outxml.begin(), '?');
 
-                // replace invalid xml characters
-                for (std::string::iterator it = outxml.begin(); it != outxml.end(); ++it) {
-                    if (((unsigned char)*it) < 0x20 && (*it != 0x09 && *it != 0x0A && *it != 0x0D)) {
-                        *it = '?';
-                    }
-                }
-//                 std::cout << outxml << "\n\n";
-                send(outxml);
-            } catch (...) {     // replace_invalid can throw exception? wtf!
-            }
+					// replace invalid xml characters
+					for (std::string::iterator it = outxml.begin(); it != outxml.end(); ++it) {
+						if (((unsigned char)*it) < 0x20 && (*it != 0x09 && *it != 0x0A && *it != 0x0D)) {
+							*it = '?';
+						}
+					}
+					send(outxml);
+				} catch (...) {     // replace_invalid can throw exception? wtf!
+				}
 
-            delete tag;
-        }
-    protected:
-        void send( const std::string & xml)    // copied from ClientBase::send(std::string), why have private function which handles protected data ??
-        {
-            if( m_connection && m_connection->state() == StateConnected )
-            {
-                if( m_compression && m_compressionActive )
-                    m_compression->compress( xml );
-                else if( m_encryption && m_encryptionActive )
-                    m_encryption->encrypt( xml );
-                else
-                    m_connection->send( xml );
-            }                                                       
-        }
-    };
+				delete tag;
+			}
+		protected:
+			void send( const std::string & xml) {    // copied from ClientBase::send(std::string), why have private function which handles protected data ??
+				if( m_connection && m_connection->state() == StateConnected ) {
+					if( m_compression && m_compressionActive )
+						m_compression->compress( xml );
+					else if( m_encryption && m_encryptionActive )
+						m_encryption->encrypt( xml );
+					else
+						m_connection->send( xml );
+				}
+			}
+	};
 };
 
 /*
@@ -111,17 +103,23 @@ static void newMessageReceived(PurpleAcc
 }
 
 /*
- * Called when message from legacy network arrived (we have to resend message)
+ * Called when libpurple wants to write some message to Chat
  */
 static void conv_write_im(PurpleConversation *conv, const char *who, const char *message, PurpleMessageFlags flags, time_t mtime)
 {
 	GlooxMessageHandler::instance()->purpleConversationWriteIM(conv,who,message,flags,mtime);
 }
 
+/*
+ * Called when libpurple wants to write some message to Groupchat
+ */
 static void conv_write_chat(PurpleConversation *conv, const char *who, const char *message, PurpleMessageFlags flags, time_t mtime) {
 	GlooxMessageHandler::instance()->purpleConversationWriteChat(conv,who,message,flags,mtime);
 }
 
+/*
+ * Called when libpurple wants to write some message to Conversation
+ */
 static void conv_write_conv(PurpleConversation *conv, const char *who, const char *alias,const char *message, PurpleMessageFlags flags, time_t mtime) {
 	if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
 		conv_write_im(conv, who, message, flags, mtime);
@@ -131,18 +129,30 @@ static void conv_write_conv(PurpleConver
 	}
 }
 
+/*
+ * Called when chat topic was changed
+ */
 static void conv_chat_topic_changed(PurpleConversation *chat, const char *who, const char *topic) {
 	GlooxMessageHandler::instance()->purpleChatTopicChanged(chat, who, topic);
 }
 
+/*
+ * Called when there are new users added
+ */
 static void conv_chat_add_users(PurpleConversation *conv, GList *cbuddies, gboolean new_arrivals) {
 	GlooxMessageHandler::instance()->purpleChatAddUsers(conv, cbuddies, new_arrivals);
 }
 
+/*
+ * Called when user is renamed
+ */
 static void conv_chat_rename_user(PurpleConversation *conv, const char *old_name, const char *new_name, const char *new_alias) {
 	GlooxMessageHandler::instance()->purpleChatRenameUser(conv, old_name, new_name, new_alias);
 }
 
+/*
+ * Called when there are is removed
+ */
 static void conv_chat_remove_users(PurpleConversation *conv, GList *users) {
 	GlooxMessageHandler::instance()->purpleChatRemoveUsers(conv, users);
 }
@@ -184,15 +194,16 @@ void connection_report_disconnect(Purple
 }
 
 /*
- * Called when purple wants to some input from transport. Showed as input box in Pidgin.
+ * Called when purple wants to some input from transport.
  */
 static void * requestInput(const char *title, const char *primary,const char *secondary, const char *default_value,gboolean multiline, gboolean masked, gchar *hint,const char *ok_text, GCallback ok_cb,const char *cancel_text, GCallback cancel_cb,PurpleAccount *account, const char *who,PurpleConversation *conv, void *user_data){
 	Log().Get("purple") << "new requestInput";
-	if (primary){
+	if (primary) {
 		std::string primaryString(primary);
 		Log().Get("purple") << "primary string: " << primaryString;
 		User *user = GlooxMessageHandler::instance()->userManager()->getUserByAccount(account);
 		if (!user) return NULL;
+		// Check if there is some adhocData. If it's there, this request will be handled by some handler registered to this data.
 		if (!user->adhocData().id.empty()) {
 			if (user->adhocData().callerType == CALLER_ADHOC) {
 				AdhocRepeater *repeater = new AdhocRepeater(GlooxMessageHandler::instance(), user, title ? std::string(title):std::string(), primaryString, secondary ? std::string(secondary):std::string(), default_value ? std::string(default_value):std::string(), multiline, masked, ok_cb, cancel_cb, user_data);
@@ -210,8 +221,8 @@ static void * requestInput(const char *t
 // 				user->setAdhocData(data);
 				return repeater;
 			}
-
 		}
+		// emit protocol signal
 		GlooxMessageHandler::instance()->protocol()->onPurpleRequestInput(user, title, primary, secondary, default_value, multiline, masked, hint, ok_text, ok_cb, cancel_text, cancel_cb, account, who, conv, user_data);
 	}
 	return NULL;
@@ -228,6 +239,7 @@ static void * notifySearchResults(Purple
 			user->setAdhocData(data);
 		}
 	}
+
 	return NULL;
 }
 
@@ -356,6 +368,9 @@ static void * notifyMessage(PurpleNotify
 }
 
 static void * notifyMessage(PurpleNotifyMsgType type, const char *title, const char *primary, const char *secondary) {
+	// TODO: We have to patch libpurple to be able to identify from which account the message came from...
+	// without this the function is quite useles...
+	
 // 	User *user = GlooxMessageHandler::instance()->userManager()->getUserByAccount(account);
 // 	if (user && !user->adhocData().id.empty()) {
 // 		AdhocRepeater *repeater = new AdhocRepeater(GlooxMessageHandler::instance(), user, title ? std::string(title):std::string(), primary ? std::string(primary):std::string(), secondary ? std::string(secondary):std::string(), default_action, user_data, action_count, actions);


More information about the Commits mailing list