soc.2009.transport: e3600bb3: Added initial support for PURPLE_REQUEST...

hanzz at soc.pidgin.im hanzz at soc.pidgin.im
Fri Jun 26 16:40:22 EDT 2009


-----------------------------------------------------------------
Revision: e3600bb3c2c0e5e5247c50396e677a2a17494f1f
Ancestor: 77aaafde9dadeaecfbb35535d44c995632b10795
Author: hanzz at soc.pidgin.im
Date: 2009-06-26T20:35:05
Branch: im.pidgin.soc.2009.transport
URL: http://d.pidgin.im/viewmtn/revision/info/e3600bb3c2c0e5e5247c50396e677a2a17494f1f

Modified files:
        adhocrepeater.cpp adhocrepeater.h dataforms.cpp dataforms.h
        main.cpp registerhandler.cpp

ChangeLog: 

Added initial support for PURPLE_REQUEST_FIELDS

-------------- next part --------------
============================================================
--- adhocrepeater.cpp	bfb256cc1d99284582391cc849f8bd0f0f6c2388
+++ adhocrepeater.cpp	cf719fe044496bb6e77064a6b7f86d88cc330cbc
@@ -107,6 +107,35 @@ AdhocRepeater::AdhocRepeater(GlooxMessag
 
 }
 
+AdhocRepeater::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) {
+	setType(PURPLE_REQUEST_FIELDS);
+	main = m;
+	m_user = user;
+	m_requestData = user_data;
+	AdhocData data = user->adhocData();
+	m_from = data.from;
+	setRequestType(CALLER_ADHOC);
+	
+	IQ _response(IQ::Result, data.from, data.id);
+	Tag *response = _response.tag();
+	response->addAttribute("from",main->jid());
+
+	Tag *c = new Tag("command");
+	c->addAttribute("xmlns","http://jabber.org/protocol/commands");
+	c->addAttribute("sessionid",main->j->getID());
+	c->addAttribute("node",data.node);
+	c->addAttribute("status","executing");
+
+	Tag *actions = new Tag("actions");
+	actions->addAttribute("execute","complete");
+	actions->addChild(new Tag("complete"));
+	c->addChild(actions);
+	
+	c->addChild( xdataFromRequestFields(title, primaryString, fields) );
+	response->addChild(c);
+	main->j->send(response);
+}
+
 AdhocRepeater::~AdhocRepeater() {}
 
 bool AdhocRepeater::handleIq(const IQ &stanza) {
@@ -133,26 +162,31 @@ bool AdhocRepeater::handleIq(const IQ &s
 	
 	Tag *x = tag->findChildWithAttrib("xmlns","jabber:x:data");
 	if (x) {
-		std::string result("");
-		for(std::list<Tag*>::const_iterator it = x->children().begin(); it != x->children().end(); ++it){
-			if ((*it)->hasAttribute("var","result")){
-				result = (*it)->findChild("value")->cdata();
-				break;
+		if (m_type == PURPLE_REQUEST_FIELDS) {
+			// TODO :) too tired to do it now... it's just typing... nothing to think about
+		}
+		else {
+			std::string result("");
+			for(std::list<Tag*>::const_iterator it = x->children().begin(); it != x->children().end(); ++it){
+				if ((*it)->hasAttribute("var","result")){
+					result = (*it)->findChild("value")->cdata();
+					break;
+				}
 			}
-		}
 
-		if (m_type == PURPLE_REQUEST_INPUT) {
-			((PurpleRequestInputCb) m_ok_cb)(m_requestData, result.c_str());
-		}
-		else if (m_type == PURPLE_REQUEST_ACTION) {
-			std::istringstream i(result);
-			int index;
-			i >> index;
-			if (m_actions.find(index) != m_actions.end()) {
-				PurpleRequestActionCb callback = (PurpleRequestActionCb) m_actions[index];
-				if (callback)
-					(callback)(m_requestData,index);
+			if (m_type == PURPLE_REQUEST_INPUT) {
+				((PurpleRequestInputCb) m_ok_cb)(m_requestData, result.c_str());
 			}
+			else if (m_type == PURPLE_REQUEST_ACTION) {
+				std::istringstream i(result);
+				int index;
+				i >> index;
+				if (m_actions.find(index) != m_actions.end()) {
+					PurpleRequestActionCb callback = (PurpleRequestActionCb) m_actions[index];
+					if (callback)
+						(callback)(m_requestData,index);
+				}
+			}
 		}
 
 		IQ _s(IQ::Result, stanza.from().full(), stanza.id());
============================================================
--- adhocrepeater.h	4fdd4851f783ccaf563d64c88ce2b0e4df27d176
+++ adhocrepeater.h	7449f26026af0d2704293f723da940167b908b31
@@ -34,8 +34,12 @@ class AdhocRepeater : public AdhocComman
 class AdhocRepeater : public AdhocCommandHandler
 {
 	public:
+		// PURPLE_REQUEST_INPUT
 		AdhocRepeater(GlooxMessageHandler *m, User *user, const std::string &title, const std::string &primaryString, const std::string &secondaryString, const std::string &value, gboolean multiline, gboolean masked, GCallback ok_cb, GCallback cancel_cb, void * user_data);
+		// PURPLE_REQUEST_ACTION
 		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 actions);
+		// PURPLE_REQUEST_FIELDS
+		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; }
============================================================
--- dataforms.cpp	63d2869271bc9a26b3e417c9574c428131ddfa62
+++ dataforms.cpp	fb97044ccb82a26669c9d2216a01648f504bfbef
@@ -72,3 +72,149 @@ Tag * xdataFromRequestAction(const std::
 	
 	return xdata;
 }
+
+Tag * xdataFromRequestFields(const std::string &title, const std::string &primaryString, PurpleRequestFields *fields) {
+	GList *gl, *fl;
+	PurpleRequestField *fld;
+	Tag *field;
+	Tag *xdata = new Tag("x");
+	xdata->addAttribute("xmlns","jabber:x:data");
+	xdata->addAttribute("type","form");
+	xdata->addChild(new Tag("title",title));
+	xdata->addChild(new Tag("instructions",primaryString));
+
+	for (gl = purple_request_fields_get_groups(fields);
+		 gl != NULL;
+		 gl = gl->next)
+	{
+		GList *field_list;
+		size_t field_count = 0;
+
+		PurpleRequestFieldGroup *group = (PurpleRequestFieldGroup *) gl->data;
+		field_list = purple_request_field_group_get_fields(group);
+
+		if (purple_request_field_group_get_title(group) != NULL) {
+			field = new Tag("field");
+			field->addAttribute("type","fixed");
+			field->addChild(new Tag("value", (std::string) purple_request_field_group_get_title(group)));
+			xdata->addChild(field);
+		}
+
+		field_count = g_list_length(field_list);
+
+		for (fl = field_list; fl != NULL; fl = fl->next){
+			PurpleRequestFieldType type;
+			const char *field_label;
+
+			fld = (PurpleRequestField *) fl->data;
+
+			if (!purple_request_field_is_visible(fld)) {
+				continue;
+			}
+
+			type = purple_request_field_get_type(fld);
+			field_label = purple_request_field_get_label(fld);
+
+			if (type == PURPLE_REQUEST_FIELD_STRING) {
+				const char *v = purple_request_field_string_get_default_value(fld);
+				field = new Tag("field");
+				if (!purple_request_field_string_is_multiline(fld))
+					field->addAttribute("type","text-single");
+				else
+					field->addAttribute("type","text-multi");
+				field->addAttribute("label",(std::string) field_label);
+				field->addAttribute("var",(std::string) field_label);
+				if (v)
+					field->addChild(new Tag("value", (std::string) v));
+				xdata->addChild(field);
+			}
+			else if (type == PURPLE_REQUEST_FIELD_INTEGER) {
+				int v = purple_request_field_int_get_default_value(fld);
+				field = new Tag("field");
+				field->addAttribute("type","text-single");
+				field->addAttribute("label",(std::string) field_label);
+				field->addAttribute("var",(std::string) field_label);
+				if (v!=0) {
+					std::ostringstream os;
+					os << v;
+					field->addChild(new Tag("value", os.str()));
+				}
+				xdata->addChild(field);
+			}
+			else if (type == PURPLE_REQUEST_FIELD_BOOLEAN) {
+				field = new Tag("field");
+				field->addAttribute("type","boolean");
+				field->addAttribute("label",(std::string) field_label);
+				field->addAttribute("var",(std::string) field_label);
+				if (purple_request_field_bool_get_default_value(fld))
+					field->addChild(new Tag("value", "1"));
+				else
+					field->addChild(new Tag("value", "0"));
+				xdata->addChild(field);
+			}	
+			else if (type == PURPLE_REQUEST_FIELD_CHOICE) {
+				int i = 0;
+				GList *labels = purple_request_field_choice_get_labels(fld);
+				GList *l;
+				field = new Tag("field");
+				field->addAttribute("type","list-single");
+				field->addAttribute("label",(std::string) field_label);
+				field->addAttribute("var",(std::string) field_label);
+
+				for (l = labels; l != NULL; l = l->next, i++) {
+					Tag *option;
+					std::ostringstream os;
+					os << i;
+					std::string name((char *) l->data);
+					if (i == 0)
+						field->addChild(new Tag("value",os.str()));
+					option = new Tag("option");
+					option->addAttribute("label",name);
+					option->addChild( new Tag("value",os.str()) );
+					field->addChild(option);
+				}
+				field->addAttribute("var","result");
+				xdata->addChild(field);
+			}
+			else if (type == PURPLE_REQUEST_FIELD_LIST) {
+				int i = 0;
+				GList *l;
+				field = new Tag("field");
+				if (purple_request_field_list_get_multi_select(fld))
+					field->addAttribute("type","list-multi");
+				else
+					field->addAttribute("type","list-single");
+				field->addAttribute("label",(std::string) field_label);
+				field->addAttribute("var",(std::string) field_label);
+				
+				for (l = purple_request_field_list_get_items(fld); l != NULL; l = l->next, i++) {
+					Tag *option;
+					std::ostringstream os;
+					os << i;
+					std::string name((char *) l->data);
+					if (i == 0)
+						field->addChild(new Tag("value",os.str()));
+					option = new Tag("option");
+					option->addAttribute("label",name);
+					option->addChild( new Tag("value",os.str()) );
+					field->addChild(option);
+				}
+				field->addAttribute("var","result");
+				xdata->addChild(field);
+			}
+			else if (type == PURPLE_REQUEST_FIELD_IMAGE) {
+// 				widget = create_image_field(field);
+			}
+			else if (type == PURPLE_REQUEST_FIELD_ACCOUNT) {
+// 				widget = create_account_field(field);
+			}
+			else
+				continue;
+
+// 			purple_request_field_set_ui_data(field, widget);
+		}
+	}
+
+	
+	return xdata;
+}
============================================================
--- dataforms.h	015fac2ba22be73f037b174d030701b307d6b959
+++ dataforms.h	2bd839419e22d1d1585d0b774b309c29ed6850e0
@@ -23,10 +23,12 @@
 
 #include <glib.h>
 #include "gloox/tag.h"
+#include "request.h"
 
 using namespace gloox;
 
 Tag * xdataFromRequestInput(const std::string &title, const std::string &primaryString, const std::string &value, gboolean multiline);
 Tag * xdataFromRequestAction(const std::string &title, const std::string &primaryString, size_t action_count, va_list acts);
+Tag * xdataFromRequestFields(const std::string &title, const std::string &primaryString, PurpleRequestFields *fields);
 
 #endif
============================================================
--- main.cpp	558ffcc1a4833fe3938af5b3b65ad0b00d4e9368
+++ main.cpp	c96d309a2b582a7ce8978ce44c101fce44b4e520
@@ -280,6 +280,20 @@ static void * notifySearchResults(Purple
 	return NULL;
 }
 
+static void *requestFields(const char *title, const char *primary, const char *secondary, PurpleRequestFields *fields, const char *ok_text, GCallback ok_cb, const char *cancel_text, GCallback cancel_cb, PurpleAccount *account, const char *who, PurpleConversation *conv, void *user_data) {
+	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(), fields, ok_cb, cancel_cb, user_data);
+		GlooxMessageHandler::instance()->adhoc()->registerSession(user->adhocData().from, repeater);
+		AdhocData data;
+		data.id="";
+		user->setAdhocData(data);
+		return repeater;
+	}
+
+	return NULL;
+}
+
 static void * requestAction(const char *title, const char *primary,const char *secondary, int default_action,PurpleAccount *account, const char *who,PurpleConversation *conv, void *user_data,size_t action_count, va_list actions){
 	User *user = GlooxMessageHandler::instance()->userManager()->getUserByAccount(account);
 	if (user && !user->adhocData().id.empty()) {
@@ -402,6 +416,7 @@ static void * notifyMessage(PurpleNotify
 // 		user->setAdhocData(data);
 // 		return repeater;
 // 	}
+	return NULL;
 }
 
 static void buddyListAddBuddy(PurpleAccount *account, const char *username, const char *group, const char *alias){
@@ -465,8 +480,8 @@ static PurpleRequestUiOps requestUiOps =
 	requestInput,
 	NULL,
 	requestAction,
+	requestFields,
 	NULL,
-	NULL,
 	requestClose,
 	NULL,
 	NULL,
============================================================
--- registerhandler.cpp	4c04234fe1d4d4518573f4fc077524ef024543fb
+++ registerhandler.cpp	e3786baee9c768fe48a07e836c5885911b48fe5a
@@ -105,11 +105,17 @@ bool GlooxRegisterHandler::handleIq (con
 		field->addAttribute("label", "Language");
 		if (res.id!=-1)
 			field->addChild( new Tag("value", res.language) );
-		
+		else
+			field->addChild( new Tag("value", "cs") );
+
 		Tag *option = new Tag("option");
 		option->addAttribute("label", "Cesky");
 		option->addChild( new Tag("value", "cs") );
-		
+
+		option = new Tag("option");
+		option->addAttribute("label", "English");
+		option->addChild( new Tag("value", "en") );
+
 		if (res.id!=1) {
 			field = new Tag("field");
 			field->addAttribute("type", "boolean");


More information about the Commits mailing list