Simon McVittie wrote:
On Fri, 03 Apr 2009 at 15:15:59 -0300, Andre Moreira Magalhaes wrote:
Simon McVittie wrote:
Can't we have this happen at construct time?

Yeah, we can, But I was thinking if we will be able to add filters at runtime.

We have 2 solutions:
- Receive the filters in the constructor
- Have a addFilters instead of setFilters

The model we have in telepathy-spec at the moment is that each Client name
(which can be like "Empathy" or "Empathy._1._42" or "Empathy._1._42.Window3")
has a fixed set of filters for its entire lifetime. If you want to change your
filters, drop and re-add a Client name (but you can't usefully do that anyway
if your filters are hard-coded in a .client file - activatable clients should
have their normal set of filters in their .client file, then add additional
transient names if necessary in order to widen the filters while running).

That's a point - we need a way to release the bus name...

Revised API attached. Added unregisterClient/s and received the filters at construction.

BR
Andrunko


typedef uint OperationHandle;
typedef SharedPtr<ChannelDispatchOperation> ChannelDispatchOperationPtr;
typedef SharedPtr<ChannelRequest> ChannelRequestPtr;

class ChannelDispatchOperation : public StatefulDBusProxy,
                                 private OptionalInterfaceFactory<ChannelDispatchOperation>,
                                 public ReadyObject,
                                 public SharedData
{
    Q_OBJECT

public:
    static ChannelDispatchOperationPtr create(const QString &objectPath,
            const QVariantMap &immutableProperties);

    ~ChannelDispatchOperation();

    AccountPtr account() const;

    ConnectionPtr connection() const;

    QList<ChannelPtr> channels() const;

    QStringList possibleHandlers() const;

    PendingOperation *handleWith(const QString &handler);

    PendingOperation *claim();

Q_SIGNALS:
    void channelLost(const QString &channelObjectPath, const QString &errorName,
            const QString &errorMessage);

    // TODO should we have finished, or use invalidated?
};

class ChannelRequest : public StatefulDBusProxy,
                       private OptionalInterfaceFactory<ChannelDispatchOperation>,
                       public ReadyObject,
                       public SharedData
{
    Q_OBJECT

public:
    static ChannelRequestPtr create(const QString &objectPath,
            const QVariantMap &immutableProperties);

    ~ChannelRequest();

    AccountPtr account() const;

    QDateTime userActionTime() const;

    QVariantMap requests() const;

    PendingOperation *proceed();
    PendingOperation *cancel();

Q_SIGNALS:
    void failed(const QString &errorName, const QString &errorMessage);
    void succeeded();
};

class BaseClient : public QObject
{
    Q_OBJECT

public:
    BaseClient(const QVariantMap &filters, QObject *parent = 0);
    ~BaseClient();

    QVariantMap filters() const;

    // when finished processing an operation (observeChannels, handlerChannels,
    // ...), the client should call setOperationFinished/WithError with the
    // given operationHandle.
    // This allows operations to be threated asynchronously
    void setOperationFinished(OperationHandle operationHandle);
    void setOperationFinishedWithError(OperationHandle operationHandle,
            const QString &errorName, const QString &errorMessage);

Q_SIGNALS:
    void operationFinished(OperationHandle operationHandle);
    void operationFinishedWithError(OperationHandle operationHandle,
            const QString &errorName, const QString &errorMessage);
};

class BaseObserverClient : public BaseClient
{
public:
    BaseObserver(const QVariantMap &filters, QObject *parent = 0);
    virtual ~BaseObserver();

    virtual void observeChannels(OperationHandle operationHandle,
            const AccountPtr &account,
            const ConnectionPtr &connection,
            const QList<ChannelPtr> &channels,
            const ChannelDispatchOperationPtr &dispatchOperation) = 0;
};

class BaseApproverClient : public BaseClient
{
public:
    BaseApprover(const QVariantMap &filters, QObject *parent = 0);
    virtual ~BaseApprover();

    virtual void addDispatchOperation(OperationHandle operationHandle,
            const ChannelDispatchOperationPtr &dispatchOperation) = 0;
};

class BaseHandlerClient : public BaseClient
{
public:
    BaseHandler(const QVariantMap &filters, QObject *parent = 0);
    virtual ~BaseHandler();

    // addRequest/removeFailedRequest will only be called if true, default =
    // true
    void listenRequests(bool listen);

    virtual void handleChannels(OperationHandle operationHandle,
            const AccountPtr &account,
            const ConnectionPtr &connection,
            const QList<ChannelPtr> &channels,
            const QList<ChannelRequestPtr> &requestsSatisfied,
            const QDateTime &userActionTime) = 0;

    virtual void addRequest(const ChannelRequestPtr &request);
    virtual void removeFailedRequest(const ChannelRequestPtr &request,
            const QString &error, const QString &message) = 0;
};

class ClientRegister : public QObject
{
public:
    // clientName is the name to be used 
    ClientRegister(const QString &clientName, bool unique = false,
            QObject *parent = 0);
    ~ClientRegister();

    QString clientName() const;

    bool addObserverClient(ObserverClient *client);
    bool addApproverClient(ApproverClient *client);
    bool addHandlerClient(HandlerClient *client);

    bool registerClients();
    // unregister all clients
    void unregisterClients();
    // unregister a given client if the client is registered
    bool unregisterClient(BaseClient *client);
};

void MyHandler : public BaseHandlerClient
{
public:
    MyHandler(const QVariantMap &filters, QObject *parent = 0);
    ~MyHandler();

    void handleChannels(OperationHandle operationHandle,
            const AccountPtr &account,
            const ConnectionPtr &connection,
            const QList<ChannelPtr> &channels,
            const QStringList &requestsSatisfiedObjectPaths,
            const QDateTime &userActionTime)
    {
        foreach (const ChannelPtr &channel, channels) {
            MyHandlerUI *handlerUI = lookupHandlerUIByChannel(channel);
            if (!handlerUI) {
                // create handler UI to handle channel
                ...
            }
            handlerUI->show();
        }
        setOperationFinished(operationHandle);
    }

    virtual void addRequest(const QString &requestObjectPath,
            const QVariantMap &requestProperties)
    {
        ...
        setOperationFinished(operationHandle);
    }

    virtual void removeFailedRequest(OperationHandle operationHandle,
            const QString &requestObjectPath,
            const QString &error, const QString &message)
    {
        ...
        setOperationFinished(operationHandle);
    }
};

ClientRegister *r = new ClientRegister("myclient");
QVariantMap map;
map.insert("org.freedesktop.Telepathy.Channel.ChannelType",
           "org.freedesktop.Telepathy.Channel.Type.Text");
map.insert("org.freedesktop.Telepathy.Channel.TargetHandleType",
           Telepathy::HandleTypeContact);
MyHandler *h = new MyHandler(filters, r);
r->addHandlerClient(h);
r->registerClients();
_______________________________________________
telepathy mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/telepathy

Reply via email to