PageRenderTime 43ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/telepathy-qt-0.9.3/TelepathyQt/protocol-info.cpp

#
C++ | 529 lines | 275 code | 69 blank | 185 comment | 31 complexity | 99bdcb68d16d5ebc7ab2e63fc3671cf5 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * This file is part of TelepathyQt
  3. *
  4. * @copyright Copyright (C) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
  5. * @copyright Copyright (C) 2010 Nokia Corporation
  6. * @license LGPL 2.1
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2.1 of the License, or (at your option) any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  21. */
  22. #include <TelepathyQt/ProtocolInfo>
  23. #include <TelepathyQt/ConnectionCapabilities>
  24. #include <TelepathyQt/ConnectionManager>
  25. #include <TelepathyQt/PendingFailure>
  26. #include <TelepathyQt/PendingString>
  27. namespace Tp
  28. {
  29. struct TP_QT_NO_EXPORT ProtocolInfo::Private : public QSharedData
  30. {
  31. Private()
  32. : dbusConnection(QDBusConnection::sessionBus()), // make the compiler happy
  33. addressingIface(0)
  34. {
  35. }
  36. Private(const ConnectionManagerPtr &cm, const QString &name)
  37. : dbusConnection(cm->dbusConnection()),
  38. busName(cm->busName()),
  39. cmName(cm->name()),
  40. name(name),
  41. iconName(QString(QLatin1String("im-%1")).arg(name)),
  42. addressingIface(0)
  43. {
  44. QString escapedProtocolName = name;
  45. escapedProtocolName.replace(QLatin1Char('-'), QLatin1Char('_'));
  46. objectPath = QString(QLatin1String("%1/%2")).arg(cm->objectPath()).arg(escapedProtocolName);
  47. }
  48. ~Private()
  49. {
  50. delete addressingIface;
  51. }
  52. Client::ProtocolInterfaceAddressingInterface *addressingInterface()
  53. {
  54. if (!addressingIface) {
  55. addressingIface = new Client::ProtocolInterfaceAddressingInterface(
  56. dbusConnection, busName, objectPath);
  57. }
  58. return addressingIface;
  59. }
  60. QDBusConnection dbusConnection;
  61. QString busName;
  62. QString objectPath;
  63. QString cmName;
  64. QString name;
  65. ProtocolParameterList params;
  66. ConnectionCapabilities caps;
  67. QString vcardField;
  68. QString englishName;
  69. QString iconName;
  70. PresenceSpecList statuses;
  71. AvatarSpec avatarRequirements;
  72. QStringList addressableVCardFields;
  73. QStringList addressableUriSchemes;
  74. Client::ProtocolInterfaceAddressingInterface *addressingIface;
  75. };
  76. /**
  77. * \class ProtocolInfo
  78. * \ingroup clientcm
  79. * \headerfile TelepathyQt/protocol-info.h <TelepathyQt/ProtocolInfo>
  80. *
  81. * \brief The ProtocolInfo class represents a <a
  82. * href="http://telepathy.freedesktop.org/spec/Protocol.html">Telepathy Protocol</a>.
  83. */
  84. ProtocolInfo::ProtocolInfo()
  85. {
  86. }
  87. /**
  88. * Construct a new ProtocolInfo object.
  89. *
  90. * \param cm Connection manager owning this ProtocolInfo.
  91. * \param name Protocol name.
  92. */
  93. ProtocolInfo::ProtocolInfo(const ConnectionManagerPtr &cm, const QString &name)
  94. : mPriv(new Private(cm, name))
  95. {
  96. }
  97. ProtocolInfo::ProtocolInfo(const ProtocolInfo &other)
  98. : mPriv(other.mPriv)
  99. {
  100. }
  101. /**
  102. * Class destructor.
  103. */
  104. ProtocolInfo::~ProtocolInfo()
  105. {
  106. }
  107. ProtocolInfo &ProtocolInfo::operator=(const ProtocolInfo &other)
  108. {
  109. this->mPriv = other.mPriv;
  110. return *this;
  111. }
  112. /**
  113. * Return the short name of the connection manager (e.g. "gabble") for this protocol.
  114. *
  115. * \return The name of the connection manager for this protocol.
  116. */
  117. QString ProtocolInfo::cmName() const
  118. {
  119. if (!isValid()) {
  120. return QString();
  121. }
  122. return mPriv->cmName;
  123. }
  124. /**
  125. * Return the string identifying this protocol as described in the \telepathy_spec
  126. * (e.g. "jabber").
  127. *
  128. * This identifier is not intended to be displayed to users directly; user
  129. * interfaces are responsible for mapping them to localized strings.
  130. *
  131. * \return A string identifying this protocol.
  132. */
  133. QString ProtocolInfo::name() const
  134. {
  135. if (!isValid()) {
  136. return QString();
  137. }
  138. return mPriv->name;
  139. }
  140. /**
  141. * Return all supported parameters for this protocol. The parameters' names
  142. * may either be the well-known strings specified by the \telepathy_spec
  143. * (e.g. "account" and "password"), or implementation-specific strings.
  144. *
  145. * \return A list of parameters for this protocol.
  146. */
  147. ProtocolParameterList ProtocolInfo::parameters() const
  148. {
  149. if (!isValid()) {
  150. return ProtocolParameterList();
  151. }
  152. return mPriv->params;
  153. }
  154. /**
  155. * Return whether a given parameter can be passed to the connection
  156. * manager when creating a connection to this protocol.
  157. *
  158. * \param name The name of a parameter.
  159. * \return true if the given parameter exists.
  160. */
  161. bool ProtocolInfo::hasParameter(const QString &name) const
  162. {
  163. if (!isValid()) {
  164. return false;
  165. }
  166. foreach (const ProtocolParameter &param, mPriv->params) {
  167. if (param.name() == name) {
  168. return true;
  169. }
  170. }
  171. return false;
  172. }
  173. /**
  174. * Return whether it might be possible to register new accounts on this
  175. * protocol, by setting the special parameter named
  176. * <code>register</code> to <code>true</code>.
  177. *
  178. * \return The same thing as hasParameter("register").
  179. * \sa hasParameter()
  180. */
  181. bool ProtocolInfo::canRegister() const
  182. {
  183. if (!isValid()) {
  184. return false;
  185. }
  186. return hasParameter(QLatin1String("register"));
  187. }
  188. /**
  189. * Return the capabilities that are expected to be available from a connection
  190. * to this protocol, i.e. those for which Connection::createChannel() can
  191. * reasonably be expected to succeed.
  192. * User interfaces can use this information to show or hide UI components.
  193. *
  194. * @return An object representing the capabilities expected to be available from
  195. * a connection to this protocol.
  196. */
  197. ConnectionCapabilities ProtocolInfo::capabilities() const
  198. {
  199. if (!isValid()) {
  200. return ConnectionCapabilities();
  201. }
  202. return mPriv->caps;
  203. }
  204. /**
  205. * Return the name of the most common vcard field used for this protocol's
  206. * contact identifiers, normalized to lower case.
  207. *
  208. * One valid use of this field is to answer the question: given a contact's
  209. * vcard containing an X-JABBER field, how can you communicate with the contact?
  210. * By iterating through protocols looking for an x-jabber VCardField, one can
  211. * build up a list of protocols that handle x-jabber, then offer the user a list
  212. * of accounts for those protocols and/or the option to create a new account for
  213. * one of those protocols.
  214. * It is not necessarily valid to interpret contacts' identifiers as values of
  215. * this vcard field. For instance, telepathy-sofiasip supports contacts whose
  216. * identifiers are of the form sip:jenny@example.com or tel:8675309, which would
  217. * not normally both be represented by any single vcard field.
  218. *
  219. * \return The most common vcard field used for this protocol's contact
  220. * identifiers, or an empty string if there is no such field.
  221. */
  222. QString ProtocolInfo::vcardField() const
  223. {
  224. if (!isValid()) {
  225. return QString();
  226. }
  227. return mPriv->vcardField;
  228. }
  229. /**
  230. * Return the English-language name of this protocol, such as "AIM" or "Yahoo!".
  231. *
  232. * The name can be used as a fallback if an application doesn't have a localized name for this
  233. * protocol.
  234. *
  235. * If the manager file or the CM service doesn't specify the english name, it is inferred from this
  236. * protocol name, such that for example "google-talk" becomes "Google Talk", but "local-xmpp"
  237. * becomes "Local Xmpp".
  238. *
  239. * \return An English-language name for this protocol.
  240. */
  241. QString ProtocolInfo::englishName() const
  242. {
  243. if (!isValid()) {
  244. return QString();
  245. }
  246. return mPriv->englishName;
  247. }
  248. /**
  249. * Return the name of an icon for this protocol in the system's icon theme, such as "im-msn".
  250. *
  251. * If the manager file or the CM service doesn't specify the icon name, "im-<protocolname>" is
  252. * assumed.
  253. *
  254. * \return The likely name of an icon for this protocol.
  255. */
  256. QString ProtocolInfo::iconName() const
  257. {
  258. if (!isValid()) {
  259. return QString();
  260. }
  261. return mPriv->iconName;
  262. }
  263. /**
  264. * Return a list of PresenceSpec representing the possible presence statuses
  265. * from a connection to this protocol.
  266. *
  267. * \return A list of PresenceSpec representing the possible presence statuses
  268. * from a connection to this protocol.
  269. */
  270. PresenceSpecList ProtocolInfo::allowedPresenceStatuses() const
  271. {
  272. if (!isValid()) {
  273. return PresenceSpecList();
  274. }
  275. return mPriv->statuses;
  276. }
  277. /**
  278. * Return the requirements (size limits, supported MIME types, etc)
  279. * for avatars used on to this protocol.
  280. *
  281. * \return The requirements for avatars used on this protocol.
  282. */
  283. AvatarSpec ProtocolInfo::avatarRequirements() const
  284. {
  285. if (!isValid()) {
  286. return AvatarSpec();
  287. }
  288. return mPriv->avatarRequirements;
  289. }
  290. /**
  291. * Return the vcard fields that can be used to request a contact with on this protocol,
  292. * normalized to lower case.
  293. *
  294. * \return The vcard fields normalized to lower case.
  295. * \sa addressableUriSchemes()
  296. */
  297. QStringList ProtocolInfo::addressableVCardFields() const
  298. {
  299. if (!isValid()) {
  300. return QStringList();
  301. }
  302. return mPriv->addressableVCardFields;
  303. }
  304. /**
  305. * Return the URI schemes that are supported by this protocol.
  306. *
  307. * \return The URI schemes.
  308. * \sa addressableVCardFields()
  309. */
  310. QStringList ProtocolInfo::addressableUriSchemes() const
  311. {
  312. if (!isValid()) {
  313. return QStringList();
  314. }
  315. return mPriv->addressableUriSchemes;
  316. }
  317. /**
  318. * Attempt to normalize the given \a vcardAddress.
  319. *
  320. * For example, a vcard TEL field formatted as +1 (206) 555 1234,
  321. * could be normalized to +12065551234.
  322. *
  323. * If a vcard address X would be normalized to Y, a successful ContactManager
  324. * contact request using ContactManager::contactsForVCardAddresses() for
  325. * vcard address X would result in a contact with Y reported as an
  326. * address that can identify it in Contact::vcardAddresses().
  327. *
  328. * \param vcardField The vcard field the \a vcardAddress belongs to.
  329. * \param vcardAddress The address to normalize.
  330. * \return A PendingString which will emit PendingString::finished
  331. * when the address has been normalized or an error occurred.
  332. * \sa normalizeContactUri()
  333. */
  334. PendingString *ProtocolInfo::normalizeVCardAddress(const QString &vcardField,
  335. const QString &vcardAddress)
  336. {
  337. if (!isValid()) {
  338. return new PendingString(TP_QT_ERROR_NOT_AVAILABLE,
  339. QLatin1String("Protocol object is invalid"));
  340. }
  341. Client::ProtocolInterfaceAddressingInterface *iface = mPriv->addressingInterface();
  342. if (!iface->isValid()) {
  343. // cm is still valid but no Protocol object found
  344. return new PendingString(TP_QT_ERROR_NOT_IMPLEMENTED,
  345. QLatin1String("ConnectionManager does not support Protocol.I.Addressing"));
  346. }
  347. return new PendingString(iface->NormalizeVCardAddress(vcardField, vcardAddress),
  348. SharedPtr<RefCounted>());
  349. }
  350. /**
  351. * Attempt to normalize the given contact \a uri.
  352. *
  353. * If the URI has extra information beyond what's necessary to identify a particular contact, such
  354. * as an XMPP resource or an action to carry out, this extra information wil be removed.
  355. *
  356. * An example would be xmpp:romeo@Example.Com/Empathy?message;body=Hello, which would be normalized
  357. * to xmpp:romeo@example.com.
  358. *
  359. * If a URI address X would be normalized to Y, a successful ContactManager
  360. * contact request using ContactManager::contactsForUris() for
  361. * URI address X would result in a contact with Y reported as an
  362. * address that can identify it in Contact::uris().
  363. *
  364. * \param uri The URI to normalize.
  365. * \return A PendingString which will emit PendingString::finished
  366. * when the \a uri has been normalized or an error occurred.
  367. * \sa normalizeVCardAddress()
  368. */
  369. PendingString *ProtocolInfo::normalizeContactUri(const QString &uri)
  370. {
  371. if (!isValid()) {
  372. return new PendingString(TP_QT_ERROR_NOT_AVAILABLE,
  373. QLatin1String("Protocol object is invalid"));
  374. }
  375. Client::ProtocolInterfaceAddressingInterface *iface = mPriv->addressingInterface();
  376. if (!iface->isValid()) {
  377. // cm is still valid but no Protocol object found
  378. return new PendingString(TP_QT_ERROR_NOT_IMPLEMENTED,
  379. QLatin1String("ConnectionManager does not support Protocol.I.Addressing"));
  380. }
  381. return new PendingString(iface->NormalizeContactURI(uri),
  382. SharedPtr<RefCounted>());
  383. }
  384. void ProtocolInfo::addParameter(const ParamSpec &spec)
  385. {
  386. if (!isValid()) {
  387. mPriv = new Private;
  388. }
  389. QVariant defaultValue;
  390. if (spec.flags & ConnMgrParamFlagHasDefault) {
  391. defaultValue = spec.defaultValue.variant();
  392. }
  393. uint flags = spec.flags;
  394. if (spec.name.endsWith(QLatin1String("password"))) {
  395. flags |= ConnMgrParamFlagSecret;
  396. }
  397. ProtocolParameter param(spec.name,
  398. QDBusSignature(spec.signature),
  399. (ConnMgrParamFlag) flags,
  400. defaultValue);
  401. mPriv->params.append(param);
  402. }
  403. void ProtocolInfo::setVCardField(const QString &vcardField)
  404. {
  405. if (!isValid()) {
  406. mPriv = new Private;
  407. }
  408. mPriv->vcardField = vcardField;
  409. }
  410. void ProtocolInfo::setEnglishName(const QString &englishName)
  411. {
  412. if (!isValid()) {
  413. mPriv = new Private;
  414. }
  415. mPriv->englishName = englishName;
  416. }
  417. void ProtocolInfo::setIconName(const QString &iconName)
  418. {
  419. if (!isValid()) {
  420. mPriv = new Private;
  421. }
  422. mPriv->iconName = iconName;
  423. }
  424. void ProtocolInfo::setRequestableChannelClasses(
  425. const RequestableChannelClassList &caps)
  426. {
  427. if (!isValid()) {
  428. mPriv = new Private;
  429. }
  430. mPriv->caps.updateRequestableChannelClasses(caps);
  431. }
  432. void ProtocolInfo::setAllowedPresenceStatuses(const PresenceSpecList &statuses)
  433. {
  434. if (!isValid()) {
  435. mPriv = new Private;
  436. }
  437. mPriv->statuses = statuses;
  438. }
  439. void ProtocolInfo::setAvatarRequirements(const AvatarSpec &avatarRequirements)
  440. {
  441. if (!isValid()) {
  442. mPriv = new Private;
  443. }
  444. mPriv->avatarRequirements = avatarRequirements;
  445. }
  446. void ProtocolInfo::setAddressableVCardFields(const QStringList &vcardFields)
  447. {
  448. if (!isValid()) {
  449. mPriv = new Private;
  450. }
  451. mPriv->addressableVCardFields = vcardFields;
  452. }
  453. void ProtocolInfo::setAddressableUriSchemes(const QStringList &uriSchemes)
  454. {
  455. if (!isValid()) {
  456. mPriv = new Private;
  457. }
  458. mPriv->addressableUriSchemes = uriSchemes;
  459. }
  460. } // Tp