/** * This file is part of TelepathyQt * * @copyright Copyright (C) 2010-2011 Collabora Ltd. * @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 "TelepathyQt/_gen/tube-channel.moc.hpp" #include "TelepathyQt/debug-internal.h" #include namespace Tp { struct TP_QT_NO_EXPORT TubeChannel::Private { Private(TubeChannel *parent); static void introspectTube(TubeChannel::Private *self); void extractTubeProperties(const QVariantMap &props); // Public object TubeChannel *parent; ReadinessHelper *readinessHelper; // Introspection TubeChannelState state; QVariantMap parameters; }; TubeChannel::Private::Private(TubeChannel *parent) : parent(parent), readinessHelper(parent->readinessHelper()), state((TubeChannelState) -1) { ReadinessHelper::Introspectables introspectables; ReadinessHelper::Introspectable introspectableTube( QSet() << 0, // makesSenseForStatuses Features() << Channel::FeatureCore, // dependsOnFeatures (core) QStringList() << TP_QT_IFACE_CHANNEL_INTERFACE_TUBE, // dependsOnInterfaces (ReadinessHelper::IntrospectFunc) &TubeChannel::Private::introspectTube, this); introspectables[TubeChannel::FeatureCore] = introspectableTube; readinessHelper->addIntrospectables(introspectables); } void TubeChannel::Private::introspectTube(TubeChannel::Private *self) { TubeChannel *parent = self->parent; debug() << "Introspecting tube properties"; Client::ChannelInterfaceTubeInterface *tubeInterface = parent->interface(); parent->connect(tubeInterface, SIGNAL(TubeChannelStateChanged(uint)), SLOT(onTubeChannelStateChanged(uint))); PendingVariantMap *pvm = tubeInterface->requestAllProperties(); parent->connect(pvm, SIGNAL(finished(Tp::PendingOperation *)), SLOT(gotTubeProperties(Tp::PendingOperation *))); } void TubeChannel::Private::extractTubeProperties(const QVariantMap &props) { state = (Tp::TubeChannelState) qdbus_cast(props[QLatin1String("State")]); parameters = qdbus_cast(props[QLatin1String("Parameters")]); } /** * \class TubeChannel * \ingroup clientchannel * \headerfile TelepathyQt/tube-channel.h * * \brief The TubeChannel class is a base class for all tube types. * * A tube is a mechanism for arbitrary data transfer between two or more IM users, * used to allow applications on the users' systems to communicate without having * to establish network connections themselves. * * Note that TubeChannel should never be instantiated directly, instead one of its * subclasses (e.g. IncomingStreamTubeChannel or OutgoingStreamTubeChannel) should be used. * * See \ref async_model, \ref shared_ptr */ /** * Feature representing the core that needs to become ready to make the * TubeChannel object usable. * * Note that this feature must be enabled in order to use most * TubeChannel methods. * See specific methods documentation for more details. */ const Feature TubeChannel::FeatureCore = Feature(QLatin1String(TubeChannel::staticMetaObject.className()), 0); /** * Create a new TubeChannel channel. * * \param connection Connection owning this channel, and specifying the * service. * \param objectPath The channel object path. * \param immutableProperties The channel immutable properties. * \return A TubeChannelPtr object pointing to the newly created * TubeChannel object. */ TubeChannelPtr TubeChannel::create(const ConnectionPtr &connection, const QString &objectPath, const QVariantMap &immutableProperties) { return TubeChannelPtr(new TubeChannel(connection, objectPath, immutableProperties)); } /** * Construct a new TubeChannel object. * * \param connection Connection owning this channel, and specifying the * service. * \param objectPath The channel object path. * \param immutableProperties The channel immutable properties. * \param coreFeature The core feature of the channel type, if any. The corresponding introspectable should * depend on TubeChannel::FeatureCore. */ TubeChannel::TubeChannel(const ConnectionPtr &connection, const QString &objectPath, const QVariantMap &immutableProperties, const Feature &coreFeature) : Channel(connection, objectPath, immutableProperties, coreFeature), mPriv(new Private(this)) { } /** * Class destructor. */ TubeChannel::~TubeChannel() { delete mPriv; } /** * Return the parameters associated with this tube, if any. * * The parameters are populated when an outgoing tube is offered, but they are most useful in the * receiving end, where the parameters passed to the offer can be extracted for the tube's entire * lifetime to bootstrap legacy protocols. All parameters are passed unchanged. * * This method requires TubeChannel::FeatureCore to be ready. * * \return The parameters as QVariantMap. */ QVariantMap TubeChannel::parameters() const { if (!isReady(FeatureCore)) { warning() << "TubeChannel::parameters() used with FeatureCore not ready"; return QVariantMap(); } return mPriv->parameters; } /** * Return the state of this tube. * * Change notification is via the stateChanged() signal. * * This method requires TubeChannel::FeatureCore to be ready. * * \return The state as #TubeChannelState. * \sa stateChanged() */ TubeChannelState TubeChannel::state() const { if (!isReady(FeatureCore)) { warning() << "TubeChannel::state() used with FeatureCore not ready"; return TubeChannelStateNotOffered; } return mPriv->state; } void TubeChannel::setParameters(const QVariantMap ¶meters) { mPriv->parameters = parameters; } void TubeChannel::onTubeChannelStateChanged(uint newState) { if (newState == mPriv->state) { return; } uint oldState = mPriv->state; debug() << "Tube state changed to" << newState; mPriv->state = (Tp::TubeChannelState) newState; /* only emit stateChanged if we already received the state from initial introspection */ if (oldState != (uint) -1) { emit stateChanged((Tp::TubeChannelState) newState); } } void TubeChannel::gotTubeProperties(PendingOperation *op) { if (!op->isError()) { PendingVariantMap *pvm = qobject_cast(op); mPriv->extractTubeProperties(pvm->result()); debug() << "Got reply to Properties::GetAll(TubeChannel)"; mPriv->readinessHelper->setIntrospectCompleted(TubeChannel::FeatureCore, true); } else { warning().nospace() << "Properties::GetAll(TubeChannel) failed " "with " << op->errorName() << ": " << op->errorMessage(); mPriv->readinessHelper->setIntrospectCompleted(TubeChannel::FeatureCore, false, op->errorName(), op->errorMessage()); } } /** * \fn void TubeChannel::stateChanged(Tp::TubeChannelState state) * * Emitted when the value of state() changes. * * \sa state The new state of this tube. */ } // Tp