/**
* This file is part of TelepathyQt
*
* @copyright Copyright (C) 2010 Collabora Ltd.
* @copyright Copyright (C) 2010 Nokia Corporation
* @license LGPL 2.1
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include
#include
#include
#include
#include
namespace Tp
{
struct TP_QT_NO_EXPORT ProtocolInfo::Private : public QSharedData
{
Private()
: dbusConnection(QDBusConnection::sessionBus()), // make the compiler happy
addressingIface(nullptr)
{
}
Private(const ConnectionManagerPtr &cm, const QString &name)
: dbusConnection(cm->dbusConnection()),
busName(cm->busName()),
cmName(cm->name()),
name(name),
iconName(QString(QLatin1String("im-%1")).arg(name)),
addressingIface(nullptr)
{
QString escapedProtocolName = name;
escapedProtocolName.replace(QLatin1Char('-'), QLatin1Char('_'));
objectPath = QString(QLatin1String("%1/%2")).arg(cm->objectPath()).arg(escapedProtocolName);
}
~Private()
{
delete addressingIface;
}
Client::ProtocolInterfaceAddressingInterface *addressingInterface()
{
if (!addressingIface) {
addressingIface = new Client::ProtocolInterfaceAddressingInterface(
dbusConnection, busName, objectPath);
}
return addressingIface;
}
QDBusConnection dbusConnection;
QString busName;
QString objectPath;
QString cmName;
QString name;
ProtocolParameterList params;
ConnectionCapabilities caps;
QString vcardField;
QString englishName;
QString iconName;
PresenceSpecList statuses;
AvatarSpec avatarRequirements;
QStringList addressableVCardFields;
QStringList addressableUriSchemes;
Client::ProtocolInterfaceAddressingInterface *addressingIface;
};
/**
* \class ProtocolInfo
* \ingroup clientcm
* \headerfile TelepathyQt/protocol-info.h
*
* \brief The ProtocolInfo class represents a Telepathy Protocol.
*/
ProtocolInfo::ProtocolInfo()
{
}
/**
* Construct a new ProtocolInfo object.
*
* \param cm Connection manager owning this ProtocolInfo.
* \param name Protocol name.
*/
ProtocolInfo::ProtocolInfo(const ConnectionManagerPtr &cm, const QString &name)
: mPriv(new Private(cm, name))
{
}
ProtocolInfo::ProtocolInfo(const ProtocolInfo &other)
: mPriv(other.mPriv)
{
}
/**
* Class destructor.
*/
ProtocolInfo::~ProtocolInfo()
{
}
ProtocolInfo &ProtocolInfo::operator=(const ProtocolInfo &other)
{
this->mPriv = other.mPriv;
return *this;
}
/**
* Return the short name of the connection manager (e.g. "gabble") for this protocol.
*
* \return The name of the connection manager for this protocol.
*/
QString ProtocolInfo::cmName() const
{
if (!isValid()) {
return QString();
}
return mPriv->cmName;
}
/**
* Return the string identifying this protocol as described in the \telepathy_spec
* (e.g. "jabber").
*
* This identifier is not intended to be displayed to users directly; user
* interfaces are responsible for mapping them to localized strings.
*
* \return A string identifying this protocol.
*/
QString ProtocolInfo::name() const
{
if (!isValid()) {
return QString();
}
return mPriv->name;
}
/**
* Return all supported parameters for this protocol. The parameters' names
* may either be the well-known strings specified by the \telepathy_spec
* (e.g. "account" and "password"), or implementation-specific strings.
*
* \return A list of parameters for this protocol.
*/
ProtocolParameterList ProtocolInfo::parameters() const
{
if (!isValid()) {
return ProtocolParameterList();
}
return mPriv->params;
}
/**
* Return whether a given parameter can be passed to the connection
* manager when creating a connection to this protocol.
*
* \param name The name of a parameter.
* \return true if the given parameter exists.
*/
bool ProtocolInfo::hasParameter(const QString &name) const
{
if (!isValid()) {
return false;
}
foreach (const ProtocolParameter ¶m, mPriv->params) {
if (param.name() == name) {
return true;
}
}
return false;
}
/**
* Return whether it might be possible to register new accounts on this
* protocol, by setting the special parameter named
* register
to true
.
*
* \return The same thing as hasParameter("register").
* \sa hasParameter()
*/
bool ProtocolInfo::canRegister() const
{
if (!isValid()) {
return false;
}
return hasParameter(QLatin1String("register"));
}
/**
* Return the capabilities that are expected to be available from a connection
* to this protocol, i.e. those for which Connection::createChannel() can
* reasonably be expected to succeed.
* User interfaces can use this information to show or hide UI components.
*
* @return An object representing the capabilities expected to be available from
* a connection to this protocol.
*/
ConnectionCapabilities ProtocolInfo::capabilities() const
{
if (!isValid()) {
return ConnectionCapabilities();
}
return mPriv->caps;
}
/**
* Return the name of the most common vcard field used for this protocol's
* contact identifiers, normalized to lower case.
*
* One valid use of this field is to answer the question: given a contact's
* vcard containing an X-JABBER field, how can you communicate with the contact?
* By iterating through protocols looking for an x-jabber VCardField, one can
* build up a list of protocols that handle x-jabber, then offer the user a list
* of accounts for those protocols and/or the option to create a new account for
* one of those protocols.
* It is not necessarily valid to interpret contacts' identifiers as values of
* this vcard field. For instance, telepathy-sofiasip supports contacts whose
* identifiers are of the form sip:jenny@example.com or tel:8675309, which would
* not normally both be represented by any single vcard field.
*
* \return The most common vcard field used for this protocol's contact
* identifiers, or an empty string if there is no such field.
*/
QString ProtocolInfo::vcardField() const
{
if (!isValid()) {
return QString();
}
return mPriv->vcardField;
}
/**
* Return the English-language name of this protocol, such as "AIM" or "Yahoo!".
*
* The name can be used as a fallback if an application doesn't have a localized name for this
* protocol.
*
* If the manager file or the CM service doesn't specify the english name, it is inferred from this
* protocol name, such that for example "google-talk" becomes "Google Talk", but "local-xmpp"
* becomes "Local Xmpp".
*
* \return An English-language name for this protocol.
*/
QString ProtocolInfo::englishName() const
{
if (!isValid()) {
return QString();
}
return mPriv->englishName;
}
/**
* Return the name of an icon for this protocol in the system's icon theme, such as "im-msn".
*
* If the manager file or the CM service doesn't specify the icon name, "im-" is
* assumed.
*
* \return The likely name of an icon for this protocol.
*/
QString ProtocolInfo::iconName() const
{
if (!isValid()) {
return QString();
}
return mPriv->iconName;
}
/**
* Return a list of PresenceSpec representing the possible presence statuses
* from a connection to this protocol.
*
* \return A list of PresenceSpec representing the possible presence statuses
* from a connection to this protocol.
*/
PresenceSpecList ProtocolInfo::allowedPresenceStatuses() const
{
if (!isValid()) {
return PresenceSpecList();
}
return mPriv->statuses;
}
/**
* Return the requirements (size limits, supported MIME types, etc)
* for avatars used on to this protocol.
*
* \return The requirements for avatars used on this protocol.
*/
AvatarSpec ProtocolInfo::avatarRequirements() const
{
if (!isValid()) {
return AvatarSpec();
}
return mPriv->avatarRequirements;
}
/**
* Return the vcard fields that can be used to request a contact with on this protocol,
* normalized to lower case.
*
* \return The vcard fields normalized to lower case.
* \sa addressableUriSchemes()
*/
QStringList ProtocolInfo::addressableVCardFields() const
{
if (!isValid()) {
return QStringList();
}
return mPriv->addressableVCardFields;
}
/**
* Return the URI schemes that are supported by this protocol.
*
* \return The URI schemes.
* \sa addressableVCardFields()
*/
QStringList ProtocolInfo::addressableUriSchemes() const
{
if (!isValid()) {
return QStringList();
}
return mPriv->addressableUriSchemes;
}
/**
* Attempt to normalize the given \a vcardAddress.
*
* For example, a vcard TEL field formatted as +1 (206) 555 1234,
* could be normalized to +12065551234.
*
* If a vcard address X would be normalized to Y, a successful ContactManager
* contact request using ContactManager::contactsForVCardAddresses() for
* vcard address X would result in a contact with Y reported as an
* address that can identify it in Contact::vcardAddresses().
*
* \param vcardField The vcard field the \a vcardAddress belongs to.
* \param vcardAddress The address to normalize.
* \return A PendingString which will emit PendingString::finished
* when the address has been normalized or an error occurred.
* \sa normalizeContactUri()
*/
PendingString *ProtocolInfo::normalizeVCardAddress(const QString &vcardField,
const QString &vcardAddress)
{
if (!isValid()) {
return new PendingString(TP_QT_ERROR_NOT_AVAILABLE,
QLatin1String("Protocol object is invalid"));
}
Client::ProtocolInterfaceAddressingInterface *iface = mPriv->addressingInterface();
if (!iface->isValid()) {
// cm is still valid but no Protocol object found
return new PendingString(TP_QT_ERROR_NOT_IMPLEMENTED,
QLatin1String("ConnectionManager does not support Protocol.I.Addressing"));
}
return new PendingString(iface->NormalizeVCardAddress(vcardField, vcardAddress),
SharedPtr());
}
/**
* Attempt to normalize the given contact \a uri.
*
* If the URI has extra information beyond what's necessary to identify a particular contact, such
* as an XMPP resource or an action to carry out, this extra information wil be removed.
*
* An example would be xmpp:romeo@Example.Com/Empathy?message;body=Hello, which would be normalized
* to xmpp:romeo@example.com.
*
* If a URI address X would be normalized to Y, a successful ContactManager
* contact request using ContactManager::contactsForUris() for
* URI address X would result in a contact with Y reported as an
* address that can identify it in Contact::uris().
*
* \param uri The URI to normalize.
* \return A PendingString which will emit PendingString::finished
* when the \a uri has been normalized or an error occurred.
* \sa normalizeVCardAddress()
*/
PendingString *ProtocolInfo::normalizeContactUri(const QString &uri)
{
if (!isValid()) {
return new PendingString(TP_QT_ERROR_NOT_AVAILABLE,
QLatin1String("Protocol object is invalid"));
}
Client::ProtocolInterfaceAddressingInterface *iface = mPriv->addressingInterface();
if (!iface->isValid()) {
// cm is still valid but no Protocol object found
return new PendingString(TP_QT_ERROR_NOT_IMPLEMENTED,
QLatin1String("ConnectionManager does not support Protocol.I.Addressing"));
}
return new PendingString(iface->NormalizeContactURI(uri),
SharedPtr());
}
void ProtocolInfo::addParameter(const ParamSpec &spec)
{
if (!isValid()) {
mPriv = new Private;
}
QVariant defaultValue;
if (spec.flags & ConnMgrParamFlagHasDefault) {
defaultValue = spec.defaultValue.variant();
}
uint flags = spec.flags;
if (spec.name.endsWith(QLatin1String("password"))) {
flags |= ConnMgrParamFlagSecret;
}
ProtocolParameter param(spec.name,
QDBusSignature(spec.signature),
(ConnMgrParamFlag) flags,
defaultValue);
mPriv->params.append(param);
}
void ProtocolInfo::setVCardField(const QString &vcardField)
{
if (!isValid()) {
mPriv = new Private;
}
mPriv->vcardField = vcardField;
}
void ProtocolInfo::setEnglishName(const QString &englishName)
{
if (!isValid()) {
mPriv = new Private;
}
mPriv->englishName = englishName;
}
void ProtocolInfo::setIconName(const QString &iconName)
{
if (!isValid()) {
mPriv = new Private;
}
mPriv->iconName = iconName;
}
void ProtocolInfo::setRequestableChannelClasses(
const RequestableChannelClassList &caps)
{
if (!isValid()) {
mPriv = new Private;
}
mPriv->caps.updateRequestableChannelClasses(caps);
}
void ProtocolInfo::setAllowedPresenceStatuses(const PresenceSpecList &statuses)
{
if (!isValid()) {
mPriv = new Private;
}
mPriv->statuses = statuses;
}
void ProtocolInfo::setAvatarRequirements(const AvatarSpec &avatarRequirements)
{
if (!isValid()) {
mPriv = new Private;
}
mPriv->avatarRequirements = avatarRequirements;
}
void ProtocolInfo::setAddressableVCardFields(const QStringList &vcardFields)
{
if (!isValid()) {
mPriv = new Private;
}
mPriv->addressableVCardFields = vcardFields;
}
void ProtocolInfo::setAddressableUriSchemes(const QStringList &uriSchemes)
{
if (!isValid()) {
mPriv = new Private;
}
mPriv->addressableUriSchemes = uriSchemes;
}
} // Tp