/*
* Copyright (C) 2010 Collabora Ltd.
*
* 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, see .
*
* Authors:
* Travis Reitter
* Philip Withnall
* Marco Barisione
*/
using GLib;
using Folks;
using SocialWebClient;
extern const string BACKEND_NAME;
/**
* A persona store which is associated with a single libsocialweb service.
* It will create {@link Persona}s for each of the contacts known to that
* service.
*/
public class Swf.PersonaStore : Folks.PersonaStore
{
private HashTable _personas;
private bool _is_prepared = false;
private ClientService _service;
private ClientContactView _contact_view;
/**
* The type of persona store this is.
*
* See {@link Folks.PersonaStore.type_id}.
*/
public override string type_id { get { return BACKEND_NAME; } }
/**
* Whether this PersonaStore can add {@link Folks.Persona}s.
*
* See {@link Folks.PersonaStore.can_add_personas}.
*
* @since 0.5.0
*/
public override MaybeBool can_add_personas
{
get { return MaybeBool.FALSE; }
}
/**
* Whether this PersonaStore can set the alias of {@link Folks.Persona}s.
*
* See {@link Folks.PersonaStore.can_alias_personas}.
*
* @since 0.5.0
*/
public override MaybeBool can_alias_personas
{
get { return MaybeBool.FALSE; }
}
/**
* Whether this PersonaStore can set the groups of {@link Folks.Persona}s.
*
* See {@link Folks.PersonaStore.can_group_personas}.
*
* @since 0.5.0
*/
public override MaybeBool can_group_personas
{
get { return MaybeBool.FALSE; }
}
/**
* Whether this PersonaStore can remove {@link Folks.Persona}s.
*
* See {@link Folks.PersonaStore.can_remove_personas}.
*
* @since 0.5.0
*/
public override MaybeBool can_remove_personas
{
get { return MaybeBool.FALSE; }
}
/**
* Whether this PersonaStore has been prepared.
*
* See {@link Folks.PersonaStore.is_prepared}.
*
* @since 0.5.0
*/
public override bool is_prepared
{
get { return this._is_prepared; }
}
/**
* The {@link Persona}s exposed by this PersonaStore.
*
* See {@link Folks.PersonaStore.personas}.
*/
public override HashTable personas
{
get { return this._personas; }
}
/**
* Create a new PersonaStore.
*
* Create a new persona store to store the {@link Persona}s for the contacts
* provided by the `service`.
*/
public PersonaStore (ClientService service)
{
Object (display_name: service.get_display_name(),
id: service.get_name ());
this.trust_level = PersonaStoreTrust.PARTIAL;
this._service = service;
this._personas = new HashTable (str_hash, str_equal);
}
~PersonaStore ()
{
this._contact_view.contacts_added.disconnect (this.contacts_added_cb);
this._contact_view.contacts_changed.disconnect (this.contacts_changed_cb);
this._contact_view.contacts_removed.disconnect (this.contacts_removed_cb);
}
/**
* Add a new {@link Persona} to the PersonaStore.
*
* See {@link Folks.PersonaStore.add_persona_from_details}.
*/
public override async Folks.Persona? add_persona_from_details (
HashTable details) throws Folks.PersonaStoreError
{
throw new PersonaStoreError.READ_ONLY (
"Personas cannot be added to this store.");
}
/**
* Remove a {@link Persona} from the PersonaStore.
*
* See {@link Folks.PersonaStore.remove_persona}.
*/
public override async void remove_persona (Folks.Persona persona)
throws Folks.PersonaStoreError
{
throw new PersonaStoreError.READ_ONLY (
"Personas cannot be removed from this store.");
}
/**
* Prepare the PersonaStore for use.
*
* See {@link Folks.PersonaStore.prepare}.
*/
public override async void prepare ()
{
lock (this._is_prepared)
{
if (!this._is_prepared)
{
this._service.get_static_capabilities (
(service, caps, error) =>
{
if (caps == null)
return;
bool has_contacts = ClientService.has_cap (caps,
"has-contacts-query-iface");
if (!has_contacts)
return;
var parameters = new HashTable
(str_hash, str_equal);
this._service.contacts_query_open_view
("people", parameters, (query, contact_view) =>
{
/* The D-Bus call could return an error. In this
* case, contact_view is null */
if (contact_view == null)
return;
contact_view.contacts_added.connect
(this.contacts_added_cb);
contact_view.contacts_changed.connect
(this.contacts_changed_cb);
contact_view.contacts_removed.connect
(this.contacts_removed_cb);
this._contact_view = contact_view;
this._is_prepared = true;
this.notify_property ("is-prepared");
this._contact_view.start ();
});
});
}
}
}
private void contacts_added_cb (List contacts)
{
var added_personas = new Queue ();
foreach (var contact in contacts)
{
var persona = new Persona(this, contact);
_personas.insert(persona.iid, persona);
added_personas.push_tail(persona);
}
if (added_personas.length > 0)
this.personas_changed (added_personas.head, null, null, null, 0);
}
private void contacts_changed_cb (List contacts)
{
foreach (var contact in contacts)
{
if (this._service.get_name () != contact.service)
{
continue;
}
var iid = Swf.Persona._build_iid(contact.service, Persona.get_contact_id (contact));
var persona = _personas.lookup(iid);
if (persona != null)
persona.update (contact);
}
}
private void contacts_removed_cb (List contacts)
{
var removed_personas = new Queue ();
foreach (var contact in contacts)
{
if (this._service.get_name () != contact.service)
{
continue;
}
var iid = Swf.Persona._build_iid(contact.service, Persona.get_contact_id (contact));
var persona = _personas.lookup(iid);
if (persona != null)
{
removed_personas.push_tail(persona);
_personas.remove(persona.iid);
}
}
if (removed_personas.length > 0)
this.personas_changed (null, removed_personas.head, null, null, 0);
}
}