1 /*
2  * rc.cpp - Implementation of JEP-146 (Remote Controlling Clients)
3  * Copyright (C) 2005  Remko Troncon
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  *
19  */
20 
21 #include "iconaction.h"
22 #include "psiaccount.h"
23 #include "psiactionlist.h"
24 #include "psicon.h"
25 #include "psioptions.h"
26 #include "rc.h"
27 #include "xmpp_xdata.h"
28 #include "ahcservermanager.h"
29 #include "ahcommand.h"
30 #include "groupchatdlg.h"
31 
32 using namespace XMPP;
33 
isAllowed(const Jid & j) const34 bool RCCommandServer::isAllowed(const Jid& j) const
35 {
36 	return manager()->account()->jid().compare(j,false);
37 }
38 
execute(const AHCommand & c,const Jid &)39 AHCommand RCSetStatusServer::execute(const AHCommand& c, const Jid&)
40 {
41 	// Check if the session ID is correct
42 	//if (c.sessionId() != "")
43 	//	return AHCommand::errorReply(c,AHCError::AHCError(AHCError::BadSessionID));
44 
45 	if (!c.hasData()) {
46 		// Initial set status form
47 		XData form;
48 		form.setTitle(QObject::tr("Set Status"));
49 		form.setInstructions(QObject::tr("Choose the status and status message"));
50 		form.setType(XData::Data_Form);
51 		XData::FieldList fields;
52 
53 		XData::Field type_field;
54 		type_field.setType(XData::Field::Field_Hidden);
55 		type_field.setVar("FORM_TYPE");
56 		type_field.setValue(QStringList("http://jabber.org/protocol/rc"));
57 		type_field.setRequired(false);
58 		fields += type_field;
59 
60 		XData::Field status_field;
61 		status_field.setType(XData::Field::Field_ListSingle);
62 		status_field.setVar("status");
63 		status_field.setLabel(QObject::tr("Status"));
64 		status_field.setRequired(true);
65 		status_field.setValue(QStringList(manager()->account()->status().typeString()));
66 		XData::Field::OptionList status_options;
67 		if (PsiOptions::instance()->getOption("options.ui.menu.status.chat").toBool()) {
68 			XData::Field::Option chat_option;
69 			chat_option.label = QObject::tr("Chat");
70 			chat_option.value = "chat";
71 			status_options += chat_option;
72 		}
73 		XData::Field::Option online_option;
74 		online_option.label = QObject::tr("Online");
75 		online_option.value = "online";
76 		status_options += online_option;
77 		XData::Field::Option away_option;
78 		away_option.label = QObject::tr("Away");
79 		away_option.value = "away";
80 		status_options += away_option;
81 		if (PsiOptions::instance()->getOption("options.ui.menu.status.xa").toBool()) {
82 			XData::Field::Option xa_option;
83 			xa_option.label = QObject::tr("Extended Away");
84 			xa_option.value = "xa";
85 			status_options += xa_option;
86 		}
87 		XData::Field::Option dnd_option;
88 		dnd_option.label = QObject::tr("Do Not Disturb");
89 		dnd_option.value = "dnd";
90 		status_options += dnd_option;
91 		if (PsiOptions::instance()->getOption("options.ui.menu.status.invisible").toBool()) {
92 			XData::Field::Option invisible_option;
93 			invisible_option.label = QObject::tr("Invisible");
94 			invisible_option.value = "invisible";
95 			status_options += invisible_option;
96 		}
97 		XData::Field::Option offline_option;
98 		offline_option.label = QObject::tr("Offline");
99 		offline_option.value = "offline";
100 		status_options += offline_option;
101 		status_field.setOptions(status_options);
102 		fields += status_field;
103 
104 		XData::Field priority_field;
105 		priority_field.setType(XData::Field::Field_TextSingle);
106 		priority_field.setLabel(QObject::tr("Priority"));
107 		priority_field.setVar("status-priority");
108 		priority_field.setRequired(false);
109 		priority_field.setValue(QStringList(QString::number(manager()->account()->status().priority())));
110 		fields += priority_field;
111 
112 		XData::Field statusmsg_field;
113 		statusmsg_field.setType(XData::Field::Field_TextMulti);
114 		statusmsg_field.setLabel(QObject::tr("Message"));
115 		statusmsg_field.setVar("status-message");
116 		statusmsg_field.setRequired(false);
117 		statusmsg_field.setValue(QStringList(manager()->account()->status().status()));
118 		fields += statusmsg_field;
119 
120 		form.setFields(fields);
121 
122 		return AHCommand::formReply(c, form);
123 	}
124 	else {
125 		// Set the status
126 		Status s;
127 		bool foundStatus = false;
128 		XData::FieldList fl = c.data().fields();
129 		for (int i=0; i < fl.count(); i++) {
130 			if (fl[i].var() == "status" && !(fl[i].value().isEmpty())) {
131 				foundStatus = true;
132 				s.setType(fl[i].value().first());
133 			}
134 			else if (fl[i].var() == "status-message" && !fl[i].value().isEmpty()) {
135 				s.setStatus(fl[i].value().join("\n"));
136 			}
137 			else if (fl[i].var() == "status-priority" && !fl[i].value().isEmpty()) {
138 				s.setPriority(fl[i].value().first().toInt());
139 			}
140 		}
141 		if (foundStatus) {
142 			manager()->account()->setStatus(s, true, true);
143 		}
144 		return AHCommand::completedReply(c);
145 	}
146 }
147 
148 
execute(const AHCommand & c,const Jid & j)149 AHCommand RCForwardServer::execute(const AHCommand& c, const Jid& j)
150 {
151 	int messageCount = manager()->account()->forwardPendingEvents(j);
152 	XData form;
153 	form.setTitle(QObject::tr("Forward Messages"));
154 	form.setInstructions(QObject::tr("Forwarded %1 messages").arg(messageCount));
155 	form.setType(XData::Data_Form);
156 	return AHCommand::completedReply(c,form);
157 }
158 
execute(const AHCommand & c,const Jid &)159 AHCommand RCSetOptionsServer::execute(const AHCommand& c, const Jid&)
160 {
161 	if (!c.hasData()) {
162 		// Initial set options form
163 		XData form;
164 		form.setTitle(QObject::tr("Set Options"));
165 		form.setInstructions(QObject::tr("Set the desired options"));
166 		form.setType(XData::Data_Form);
167 		XData::FieldList fields;
168 
169 		XData::Field type_field;
170 		type_field.setType(XData::Field::Field_Hidden);
171 		type_field.setVar("FORM_TYPE");
172 		type_field.setValue(QStringList("http://jabber.org/protocol/rc"));
173 		type_field.setRequired(false);
174 		fields += type_field;
175 
176 		XData::Field sounds_field;
177 		sounds_field.setType(XData::Field::Field_Boolean);
178 		sounds_field.setLabel(QObject::tr("Play sounds"));
179 		sounds_field.setVar("sounds");
180 		sounds_field.setValue(QStringList((PsiOptions::instance()->getOption("options.ui.notifications.sounds.enable").toBool() ? "1" : "0")));
181 		sounds_field.setRequired(false);
182 		fields += sounds_field;
183 
184 		XData::Field auto_offline_field;
185 		auto_offline_field.setType(XData::Field::Field_Boolean);
186 		auto_offline_field.setLabel(QObject::tr("Automatically go offline when idle"));
187 		auto_offline_field.setVar("auto-offline");
188 		auto_offline_field.setValue(QStringList((PsiOptions::instance()->getOption("options.status.auto-away.use-offline").toBool() ? "1" : "0")));
189 		auto_offline_field.setRequired(false);
190 		fields += auto_offline_field;
191 
192 		XData::Field auto_auth_field;
193 		auto_auth_field.setType(XData::Field::Field_Boolean);
194 		auto_auth_field.setLabel(QObject::tr("Auto-authorize contacts"));
195 		auto_auth_field.setVar("auto-auth");
196 		auto_auth_field.setValue(QStringList((PsiOptions::instance()->getOption("options.subscriptions.automatically-allow-authorization").toBool() ? "1" : "0")));
197 		auto_auth_field.setRequired(false);
198 		fields += auto_auth_field;
199 
200 		XData::Field auto_open_field;
201 		auto_open_field.setType(XData::Field::Field_Boolean);
202 		auto_open_field.setLabel(QObject::tr("Auto-open new messages"));
203 		auto_open_field.setVar("auto-open");
204 		auto_open_field.setValue(QStringList((PsiOptions::instance()->getOption("options.ui.message.auto-popup").toBool() ? "1" : "0")));
205 		auto_open_field.setRequired(false);
206 		fields += auto_open_field;
207 
208 		form.setFields(fields);
209 
210 		return AHCommand::formReply(c, form);
211 	}
212 	else {
213 		// Set the options
214 		XData::FieldList fl = c.data().fields();
215 		for (int i=0; i < fl.count(); i++) {
216 			if (fl[i].var() == "sounds") {
217 				QString v =  fl[i].value().first();
218 				IconAction* soundact = psiCon_->actionList()->suitableActions(PsiActionList::ActionsType( PsiActionList::Actions_MainWin | PsiActionList::Actions_Common)).action("menu_play_sounds");
219 				if (v == "1")
220 					soundact->setChecked(true);
221 				else if (v == "0")
222 					soundact->setChecked(false);
223 			}
224 			else if (fl[i].var() == "auto-offline") {
225 				QString v =  fl[i].value().first();
226 				if (v == "1")
227 					PsiOptions::instance()->setOption("options.status.auto-away.use-offline", (bool) true);
228 				else if (v == "0")
229 					PsiOptions::instance()->setOption("options.status.auto-away.use-offline", (bool) false);
230 			}
231 			else if (fl[i].var() == "auto-auth") {
232 				QString v =  fl[i].value().first();
233 				if (v == "1")
234 					PsiOptions::instance()->setOption("options.subscriptions.automatically-allow-authorization", (bool) true);
235 				else if (v == "0")
236 					PsiOptions::instance()->setOption("options.subscriptions.automatically-allow-authorization", (bool) false);
237 			}
238 			else if (fl[i].var() == "auto-open") {
239 				QString v =  fl[i].value().first();
240 				if (v == "1")
241 					PsiOptions::instance()->setOption("options.ui.message.auto-popup", (bool) true);
242 				else if (v == "0")
243 					PsiOptions::instance()->setOption("options.ui.message.auto-popup", (bool) false);
244 			}
245 		}
246 		return AHCommand::completedReply(c);
247 	}
248 }
249 
execute(const AHCommand & c,const Jid &)250 AHCommand RCLeaveMucServer::execute(const AHCommand& c, const Jid& /*j*/)
251 {
252 	foreach (QString gc, manager()->account()->groupchats()) {
253 		Jid mj(gc);
254 		GCMainDlg *gcDlg = manager()->account()->findDialog<GCMainDlg*>(mj.bare());
255 		if (gcDlg) gcDlg->close();
256 	}
257 	XData form;
258 	form.setTitle(QObject::tr("Leave All Conferences"));
259 	form.setType(XData::Data_Form);
260 	return AHCommand::completedReply(c);
261 }
262