[gnome-shell] search: Allow searching for people in overview mode
- From: Owen Taylor <otaylor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] search: Allow searching for people in overview mode
- Date: Mon, 29 Aug 2011 21:44:42 +0000 (UTC)
commit 352fb7b8337a6d9a0fc954e9c123a7e1ac10d643
Author: Morten Mjelva <morten mjelva gmail com>
Date: Fri Aug 26 16:15:38 2011 +0200
search: Allow searching for people in overview mode
This adds contacts search to shell, powered by libfolks.
Changes:
- Add Folks and Gee to the build system
- ShellContactSystem, a backend in C
- ContactDisplay, search frontend in JS
https://bugzilla.gnome.org/show_bug.cgi?id=643018
configure.ac | 2 +
data/theme/gnome-shell.css | 52 ++++++
js/Makefile.am | 1 +
js/ui/contactDisplay.js | 179 ++++++++++++++++++++
js/ui/overview.js | 2 +
src/Makefile.am | 4 +-
src/shell-contact-system.c | 350 +++++++++++++++++++++++++++++++++++++++
src/shell-contact-system.h | 50 ++++++
tools/build/gnome-shell.modules | 34 ++++
9 files changed, 673 insertions(+), 1 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 87e1e90..8a335a4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -68,6 +68,7 @@ CLUTTER_MIN_VERSION=1.7.5
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
GJS_MIN_VERSION=1.29.15
MUTTER_MIN_VERSION=3.0.0
+FOLKS_MIN_VERSION=0.5.2
GTK_MIN_VERSION=3.0.0
GIO_MIN_VERSION=2.29.10
LIBECAL_MIN_VERSION=2.32.0
@@ -82,6 +83,7 @@ STARTUP_NOTIFICATION_MIN_VERSION=0.11
PKG_CHECK_MODULES(GNOME_SHELL, gio-2.0 >= $GIO_MIN_VERSION
gio-unix-2.0 dbus-glib-1 libxml-2.0
gtk+-3.0 >= $GTK_MIN_VERSION
+ folks >= $FOLKS_MIN_VERSION
libmutter >= $MUTTER_MIN_VERSION
gjs-internals-1.0 >= $GJS_MIN_VERSION
libgnome-menu-3.0 $recorder_modules gconf-2.0
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index 313d0b2..fbf9a58 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -673,6 +673,11 @@ StTooltip StLabel {
-shell-grid-item-size: 118px;
}
+.contact-grid {
+ spacing: 36px;
+ -shell-grid-item-size: 272px; /* 2 * -shell-grid-item-size + spacing */
+}
+
.icon-grid .overview-icon {
icon-size: 96px;
}
@@ -739,11 +744,57 @@ StTooltip StLabel {
text-align: center;
}
+.contact {
+ width: 272px; /* Same width as two normal results + spacing */
+ height: 118px; /* Aspect ratio = 1.75. Normal US business card ratio */
+ border-radius: 4px;
+ padding: 3px;
+ border: 1px rgba(0,0,0,0);
+ transition-duration: 100;
+}
+
+.contact-content {
+ border-radius: 2px;
+ padding: 8px;
+ width: 232px;
+ height: 84px;
+ background-color: white;
+ color: black;
+ text-align: center;
+}
+
+.contact-icon {
+ border-radius: 4px;
+}
+
+.contact-details {
+ padding: 6px 8px 11px 8px;
+}
+
+.contact-details-alias {
+ font-size: 16px;
+ padding-bottom: 11px;
+}
+
+.contact-details-status {
+ font-size: 11pt;
+}
+
+.contact-details-status-icon {
+ padding-right: 2px;
+}
+
+.contact:hover {
+ background-color: rgba(255,255,255,0.1);
+ transition-duration: 100;
+}
+
.app-well-app.running > .overview-icon {
text-shadow: black 0px 2px 2px;
background-image: url("running-indicator.svg");
}
+.contact:selected,
.app-well-app:selected > .overview-icon,
.search-result-content:selected > .overview-icon {
background-color: rgba(255,255,255,0.33);
@@ -757,6 +808,7 @@ StTooltip StLabel {
transition-duration: 100;
}
+.contact:focus,
.app-well-app:focus > .overview-icon,
.search-result-content:focus > .overview-icon {
border: 1px solid #cccccc;
diff --git a/js/Makefile.am b/js/Makefile.am
index 25af725..0351f82 100644
--- a/js/Makefile.am
+++ b/js/Makefile.am
@@ -22,6 +22,7 @@ nobase_dist_js_DATA = \
ui/autorunManager.js \
ui/boxpointer.js \
ui/calendar.js \
+ ui/contactDisplay.js \
ui/ctrlAltTab.js \
ui/dash.js \
ui/dateMenu.js \
diff --git a/js/ui/contactDisplay.js b/js/ui/contactDisplay.js
new file mode 100644
index 0000000..10048af
--- /dev/null
+++ b/js/ui/contactDisplay.js
@@ -0,0 +1,179 @@
+/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
+
+const Folks = imports.gi.Folks
+const Lang = imports.lang;
+const Meta = imports.gi.Meta;
+const Shell = imports.gi.Shell;
+const St = imports.gi.St;
+
+const Util = imports.misc.util;
+const IconGrid = imports.ui.iconGrid;
+const Search = imports.ui.search;
+const SearchDisplay = imports.ui.searchDisplay;
+
+const MAX_SEARCH_RESULTS_ROWS = 1;
+const ICON_SIZE = 81;
+
+function launchContact(id) {
+ Util.spawn(['gnome-contacts', '-i', id]);
+}
+
+
+/* This class represents a shown contact search result in the overview */
+function Contact(id) {
+ this._init(id);
+}
+
+Contact.prototype = {
+ _init: function(id) {
+ this.individual = Shell.ContactSystem.get_default().get_individual(id);
+
+ this.actor = new St.Bin({ style_class: 'contact',
+ reactive: true,
+ track_hover: true });
+
+ let content = new St.BoxLayout( { style_class: 'contact-content',
+ vertical: false });
+ this.actor.set_child(content);
+
+ let icon = new St.Icon({ icon_type: St.IconType.FULLCOLOR,
+ icon_size: ICON_SIZE,
+ style_class: 'contact-icon' });
+ if (this.individual.avatar != null)
+ icon.gicon = this.individual.avatar;
+ else
+ icon.icon_name = 'avatar-default';
+
+ content.add(icon, { x_fill: true,
+ y_fill: false,
+ x_align: St.Align.START,
+ y_align: St.Align.MIDDLE });
+
+ let details = new St.BoxLayout({ style_class: 'contact-details',
+ vertical: true });
+ content.add(details, { x_fill: true,
+ y_fill: false,
+ x_align: St.Align.START,
+ y_align: St.Align.MIDDLE });
+
+ let aliasText = this.individual.alias || _("Unknown");
+ let aliasLabel = new St.Label({ text: aliasText,
+ style_class: 'contact-details-alias' });
+ details.add(aliasLabel, { x_fill: true,
+ y_fill: false,
+ x_align: St.Align.START,
+ y_align: St.Align.START });
+
+ let presence = this._createPresence(this.individual.presence_type);
+ details.add(presence, { x_fill: false,
+ y_fill: true,
+ x_align: St.Align.START,
+ y_align: St.Align.END });
+ },
+
+ _createPresence: function(presence) {
+ let text;
+ let iconName;
+
+ switch(presence) {
+ case Folks.PresenceType.AVAILABLE:
+ text = _("Available");
+ iconName = 'user-available';
+ break;
+ case Folks.PresenceType.AWAY:
+ case Folks.PresenceType.EXTENDED_AWAY:
+ text = _("Away");
+ iconName = 'user-away';
+ break;
+ case Folks.PresenceType.BUSY:
+ text = _("Busy");
+ iconName = 'user-busy';
+ break;
+ default:
+ text = _("Offline");
+ iconName = 'user-offline';
+ }
+
+ let icon = new St.Icon({ icon_name: iconName,
+ icon_type: St.IconType.FULLCOLOR,
+ icon_size: 16,
+ style_class: 'contact-details-status-icon' });
+ let label = new St.Label({ text: text });
+
+ let box = new St.BoxLayout({ vertical: false,
+ style_class: 'contact-details-status' });
+ box.add(icon, { x_fill: true,
+ y_fill: false,
+ x_align: St.Align.START,
+ y_align: St.Align.START });
+
+ box.add(label, { x_fill: true,
+ y_fill: false,
+ x_align: St.Align.END,
+ y_align: St.Align.START });
+
+ return box;
+ },
+
+ createIcon: function(size) {
+ let tc = St.TextureCache.get_default();
+ let icon = this.individual.avatar;
+
+ if (icon != null) {
+ return tc.load_gicon(null, icon, size);
+ } else {
+ return tc.load_icon_name(null, 'avatar-default', St.IconType.FULLCOLOR, size);
+ }
+ },
+};
+
+
+/* Searches for and returns contacts */
+function ContactSearchProvider() {
+ this._init();
+}
+
+ContactSearchProvider.prototype = {
+ __proto__: Search.SearchProvider.prototype,
+
+ _init: function() {
+ Search.SearchProvider.prototype._init.call(this, _("CONTACTS"));
+ this._contactSys = Shell.ContactSystem.get_default();
+ },
+
+ getResultMeta: function(id) {
+ let contact = new Contact(id);
+ return { 'id': id,
+ 'name': contact.alias,
+ 'createIcon': function(size) {
+ return contact.createIcon(size);
+ }
+ };
+ },
+
+ getInitialResultSet: function(terms) {
+ return this._contactSys.initial_search(terms);
+ },
+
+ getSubsearchResultSet: function(previousResults, terms) {
+ return this._contactSys.subsearch(previousResults, terms);
+ },
+
+ createResultActor: function(resultMeta, terms) {
+ let contact = new Contact(resultMeta.id);
+ return contact.actor;
+ },
+
+ createResultContainerActor: function() {
+ let grid = new IconGrid.IconGrid({ rowLimit: MAX_SEARCH_RESULTS_ROWS,
+ xAlign: St.Align.START });
+ grid.actor.style_class = 'contact-grid';
+
+ let actor = new SearchDisplay.GridSearchResults(this, grid);
+ return actor;
+ },
+
+ activateResult: function(id, params) {
+ launchContact(id);
+ }
+};
diff --git a/js/ui/overview.js b/js/ui/overview.js
index 9da431a..9555a71 100644
--- a/js/ui/overview.js
+++ b/js/ui/overview.js
@@ -11,6 +11,7 @@ const Shell = imports.gi.Shell;
const Gdk = imports.gi.Gdk;
const AppDisplay = imports.ui.appDisplay;
+const ContactDisplay = imports.ui.contactDisplay;
const Dash = imports.ui.dash;
const DND = imports.ui.dnd;
const DocDisplay = imports.ui.docDisplay;
@@ -211,6 +212,7 @@ Overview.prototype = {
this._viewSelector.addSearchProvider(new AppDisplay.SettingsSearchProvider());
this._viewSelector.addSearchProvider(new PlaceDisplay.PlaceSearchProvider());
this._viewSelector.addSearchProvider(new DocDisplay.DocSearchProvider());
+ this._viewSelector.addSearchProvider(new ContactDisplay.ContactSearchProvider());
// TODO - recalculate everything when desktop size changes
this._dash = new Dash.Dash();
diff --git a/src/Makefile.am b/src/Makefile.am
index 73e56df..3ff043f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -102,6 +102,7 @@ shell_public_headers_h = \
shell-app-system.h \
shell-app-usage.h \
shell-arrow.h \
+ shell-contact-system.h \
shell-doc-system.h \
shell-embedded-window.h \
shell-generic-container.h \
@@ -137,6 +138,7 @@ libgnome_shell_la_SOURCES = \
shell-app-system.c \
shell-app-usage.c \
shell-arrow.c \
+ shell-contact-system.c \
shell-doc-system.c \
shell-embedded-window.c \
shell-generic-container.c \
@@ -269,7 +271,7 @@ libgnome_shell_la_LIBADD = \
libgnome_shell_la_CPPFLAGS = $(gnome_shell_cflags)
Shell-0.1.gir: libgnome-shell.la St-1.0.gir
-Shell_0_1_gir_INCLUDES = Clutter-1.0 ClutterX11-1.0 Meta-3.0 TelepathyGLib-0.12 TelepathyLogger-0.2 Soup-2.4 GMenu-3.0 NetworkManager-1.0 NMClient-1.0
+Shell_0_1_gir_INCLUDES = Clutter-1.0 ClutterX11-1.0 Meta-3.0 TelepathyGLib-0.12 TelepathyLogger-0.2 Soup-2.4 GMenu-3.0 NetworkManager-1.0 NMClient-1.0 Folks-0.6
Shell_0_1_gir_CFLAGS = $(libgnome_shell_la_CPPFLAGS) -I $(srcdir)
Shell_0_1_gir_LIBS = libgnome-shell.la
Shell_0_1_gir_FILES = $(libgnome_shell_la_gir_sources)
diff --git a/src/shell-contact-system.c b/src/shell-contact-system.c
new file mode 100644
index 0000000..971a164
--- /dev/null
+++ b/src/shell-contact-system.c
@@ -0,0 +1,350 @@
+/* This implements a complete suite for caching and searching contacts in the
+ * Shell. We retrieve contacts from libfolks asynchronously and we search
+ * these for display to the user. */
+
+#include "shell-contact-system.h"
+
+#include <glib.h>
+#include <glib/gprintf.h>
+#include <gee.h>
+#include <clutter/clutter.h>
+#include <folks/folks.h>
+
+#include "shell-global.h"
+#include "shell-util.h"
+#include "st.h"
+
+G_DEFINE_TYPE (ShellContactSystem, shell_contact_system, G_TYPE_OBJECT);
+
+#define ALIAS_PREFIX_MATCH_WEIGHT 100
+#define ALIAS_SUBSTRING_MATCH_WEIGHT 90
+#define IM_PREFIX_MATCH_WEIGHT 10
+#define IM_SUBSTRING_MATCH_WEIGHT 5
+
+
+/* Callbacks */
+
+static void
+prepare_individual_aggregator_cb (GObject *obj,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ FolksIndividualAggregator *aggregator = FOLKS_INDIVIDUAL_AGGREGATOR (obj);
+
+ folks_individual_aggregator_prepare_finish (aggregator, res, NULL);
+}
+
+
+/* Internal stuff */
+
+typedef struct {
+ gchar *key;
+ guint weight;
+} ContactSearchResult;
+
+struct _ShellContactSystemPrivate {
+ FolksIndividualAggregator *aggregator;
+};
+
+static void
+shell_contact_system_constructed (GObject *obj)
+{
+ ShellContactSystem *self = SHELL_CONTACT_SYSTEM (obj);
+
+ G_OBJECT_CLASS (shell_contact_system_parent_class)->constructed (obj);
+
+ /* We intentionally do not care about the "individuals-changed" signal, as
+ * we don't intend to update searches after they've been performed.
+ * Therefore, we will simply retrieve the "individuals" property which
+ * represents a snapshot of the individuals in the aggregator.
+ */
+ self->priv->aggregator = folks_individual_aggregator_new ();
+ folks_individual_aggregator_prepare (self->priv->aggregator, prepare_individual_aggregator_cb, NULL);
+}
+
+static void
+shell_contact_system_finalize (GObject *obj)
+{
+ ShellContactSystem *self = SHELL_CONTACT_SYSTEM (obj);
+
+ g_object_unref (self->priv->aggregator);
+
+ G_OBJECT_CLASS (shell_contact_system_parent_class)->finalize (obj);
+}
+
+static void
+shell_contact_system_init (ShellContactSystem *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, SHELL_TYPE_CONTACT_SYSTEM, ShellContactSystemPrivate);
+}
+
+static void
+shell_contact_system_class_init (ShellContactSystemClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->constructed = shell_contact_system_constructed;
+ object_class->finalize = shell_contact_system_finalize;
+
+ g_type_class_add_private (object_class, sizeof (ShellContactSystemPrivate));
+}
+
+/**
+ * normalize_terms:
+ * @terms: (element-type utf8): Input search terms
+ *
+ * Returns: (element-type utf8) (transfer full): Unicode-normalized and lowercased terms
+ */
+static GSList *
+normalize_terms (GSList *terms)
+{
+ GSList *normalized_terms = NULL;
+ GSList *iter;
+ for (iter = terms; iter; iter = iter->next)
+ {
+ const char *term = iter->data;
+ normalized_terms = g_slist_prepend (normalized_terms, shell_util_normalize_and_casefold (term));
+ }
+ return normalized_terms;
+}
+
+static guint
+do_match (ShellContactSystem *self,
+ FolksIndividual *individual,
+ GSList *terms)
+{
+ GSList *term_iter;
+ guint weight = 0;
+
+ char *alias = shell_util_normalize_and_casefold (folks_alias_details_get_alias (FOLKS_ALIAS_DETAILS (individual)));
+
+ GeeMultiMap *im_addr_map = folks_im_details_get_im_addresses (FOLKS_IM_DETAILS (individual));
+ GeeCollection *im_addrs = gee_multi_map_get_values (im_addr_map);
+ GeeIterator *im_addrs_iter;
+
+ gboolean have_alias_prefix = FALSE;
+ gboolean have_alias_substring = FALSE;
+
+ gboolean have_im_prefix = FALSE;
+ gboolean have_im_substring = FALSE;
+
+ for (term_iter = terms; term_iter; term_iter = term_iter->next)
+ {
+ const char *term = term_iter->data;
+ const char *p;
+
+ /* Match on alias */
+ p = strstr (alias, term);
+ if (p == alias)
+ have_alias_prefix = TRUE;
+ else if (p != NULL)
+ have_alias_substring = TRUE;
+
+ /* Match on one or more IM addresses */
+ im_addrs_iter = gee_iterable_iterator (GEE_ITERABLE (im_addrs));
+
+ while (gee_iterator_next (im_addrs_iter))
+ {
+ const gchar *addr = gee_iterator_get (im_addrs_iter);
+
+ p = strstr (addr, term);
+ if (p == addr)
+ have_im_prefix = TRUE;
+ else if (p != NULL)
+ have_im_substring = TRUE;
+ }
+
+ g_object_unref (im_addrs_iter);
+ }
+
+ if (have_alias_prefix)
+ weight += ALIAS_PREFIX_MATCH_WEIGHT;
+ else if (have_alias_substring)
+ weight += ALIAS_SUBSTRING_MATCH_WEIGHT;
+
+ if (have_im_prefix)
+ weight += IM_PREFIX_MATCH_WEIGHT;
+ else if (have_im_substring)
+ weight += IM_SUBSTRING_MATCH_WEIGHT;
+
+ g_free (alias);
+ g_object_unref (im_addrs);
+
+ return weight;
+}
+
+static gint
+compare_results (gconstpointer a,
+ gconstpointer b)
+{
+ ContactSearchResult *first = (ContactSearchResult *) a;
+ ContactSearchResult *second = (ContactSearchResult *) b;
+
+ if (first->weight > second->weight)
+ return 1;
+ else if (first->weight < second->weight)
+ return -1;
+ else
+ return 0;
+}
+
+static void
+free_result (gpointer data,
+ gpointer user_data)
+{
+ g_slice_free (ContactSearchResult, data);
+}
+
+/* modifies and frees @results */
+static GSList *
+sort_and_prepare_results (GSList *results)
+{
+ GSList *iter;
+ GSList *sorted_results = NULL;
+
+ results = g_slist_sort (results, compare_results);
+
+ for (iter = results; iter; iter = iter->next)
+ {
+ ContactSearchResult *result = iter->data;
+ gchar *id = result->key;
+ sorted_results = g_slist_prepend (sorted_results, id);
+ }
+
+ g_slist_foreach (results, (GFunc) free_result, NULL);
+
+ return sorted_results;
+}
+
+
+/* Methods */
+
+/**
+ * shell_contact_system_get_default:
+ *
+ * Return Value: (transfer none): The global #ShellContactSystem singleton
+ */
+ShellContactSystem *
+shell_contact_system_get_default (void)
+{
+ static ShellContactSystem *instance = NULL;
+
+ if (instance == NULL)
+ instance = g_object_new (SHELL_TYPE_CONTACT_SYSTEM, NULL);
+
+ return instance;
+}
+
+/**
+ * shell_contact_system_get_all:
+ * @self: A #ShellContactSystem
+ *
+ * Returns: (transfer none): All individuals
+ */
+GeeMap *
+shell_contact_system_get_all (ShellContactSystem *self)
+{
+ GeeMap *individuals;
+
+ g_return_val_if_fail (SHELL_IS_CONTACT_SYSTEM (self), NULL);
+
+ individuals = folks_individual_aggregator_get_individuals (self->priv->aggregator);
+
+ return individuals;
+}
+
+/**
+ * shell_contact_system_get_individual:
+ * @self: A #ShellContactSystem
+ * @id: A #gchar with the ID of the FolksIndividual to be returned.
+ *
+ * Returns: (transfer full): A #FolksIndividual or NULL if @id could not be found.
+ */
+FolksIndividual *
+shell_contact_system_get_individual (ShellContactSystem *self,
+ gchar *id)
+{
+ GeeMap *individuals;
+ gpointer key, value;
+
+ key = (gpointer) id;
+
+ g_return_val_if_fail (SHELL_IS_CONTACT_SYSTEM (self), NULL);
+
+ individuals = folks_individual_aggregator_get_individuals (self->priv->aggregator);
+
+ value = gee_map_get (individuals, key);
+
+ return FOLKS_INDIVIDUAL (value);
+}
+
+/**
+ * shell_contact_system_initial_search:
+ * @shell: A #ShellContactSystem
+ * @terms: (element-type utf8): List of terms, logical AND
+ *
+ * Search through contacts for the given search terms.
+ *
+ * Returns: (transfer container) (element-type utf8): List of contact
+ * identifiers
+ */
+GSList *
+shell_contact_system_initial_search (ShellContactSystem *self,
+ GSList *terms)
+{
+ FolksIndividual *individual;
+ GSList *results = NULL;
+ GeeMap *individuals = NULL;
+ ContactSearchResult *result;
+ GeeMapIterator *iter;
+ gpointer key;
+ guint weight;
+ GSList *normalized_terms = normalize_terms (terms);
+
+ g_return_val_if_fail (SHELL_IS_CONTACT_SYSTEM (self), NULL);
+
+ individuals = folks_individual_aggregator_get_individuals (self->priv->aggregator);
+
+ iter = gee_map_map_iterator (individuals);
+
+ while (gee_map_iterator_next (iter))
+ {
+ individual = gee_map_iterator_get_value (iter);
+ weight = do_match (self, individual, normalized_terms);
+
+ if (weight != 0)
+ {
+ key = gee_map_iterator_get_key (iter);
+
+ result = g_slice_new (ContactSearchResult);
+ result->key = (gchar *) key;
+ result->weight = weight;
+
+ results = g_slist_append (results, result);
+ }
+
+ g_object_unref (individual);
+ }
+
+ return sort_and_prepare_results (results);
+}
+
+/**
+ * shell_contact_system_subsearch:
+ * @shell: A #ShellContactSystem
+ * @previous_results: (element-type utf8): List of previous results
+ * @terms: (element-type utf8): List of terms, logical AND
+ *
+ * Search through a previous result set; for more information see
+ * js/ui/search.js.
+ *
+ * Returns: (transfer container) (element-type utf8): List of contact
+ * identifiers
+ */
+GSList *
+shell_contact_system_subsearch (ShellContactSystem *self,
+ GSList *previous_results,
+ GSList *terms)
+{
+ return shell_contact_system_initial_search (self, terms);
+}
diff --git a/src/shell-contact-system.h b/src/shell-contact-system.h
new file mode 100644
index 0000000..def382d
--- /dev/null
+++ b/src/shell-contact-system.h
@@ -0,0 +1,50 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+#ifndef __SHELL_CONTACT_SYSTEM_H__
+#define __SHELL_CONTACT_SYSTEM_H__
+
+#include <clutter/clutter.h>
+#include <gio/gio.h>
+#include <folks/folks.h>
+
+#define SHELL_TYPE_CONTACT_SYSTEM (shell_contact_system_get_type ())
+#define SHELL_CONTACT_SYSTEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SHELL_TYPE_CONTACT_SYSTEM, ShellContactSystem))
+#define SHELL_CONTACT_SYSTEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_CONTACT_SYSTEM, ShellContactSystemClass))
+#define SHELL_IS_CONTACT_SYSTEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SHELL_TYPE_CONTACT_SYSTEM))
+#define SHELL_IS_CONTACT_SYSTEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SHELL_TYPE_CONTACT_SYSTEM))
+#define SHELL_CONTACT_SYSTEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SHELL_TYPE_CONTACT_SYSTEM, ShellContactSystemClass))
+
+typedef struct _ShellContactSystem ShellContactSystem;
+typedef struct _ShellContactSystemClass ShellContactSystemClass;
+typedef struct _ShellContactSystemPrivate ShellContactSystemPrivate;
+
+struct _ShellContactSystem
+{
+ GObject parent;
+
+ ShellContactSystemPrivate *priv;
+};
+
+struct _ShellContactSystemClass
+{
+ GObjectClass parent_class;
+};
+
+GType shell_contact_system_get_type (void) G_GNUC_CONST;
+
+/* Methods */
+
+ShellContactSystem * shell_contact_system_get_default (void);
+
+GeeMap *shell_contact_system_get_all (ShellContactSystem *self);
+
+FolksIndividual *shell_contact_system_get_individual (ShellContactSystem *self,
+ gchar *id);
+
+GSList * shell_contact_system_initial_search (ShellContactSystem *shell,
+ GSList *terms);
+
+GSList * shell_contact_system_subsearch (ShellContactSystem *shell,
+ GSList *previous_results,
+ GSList *terms);
+
+#endif /* __SHELL_CONTACT_SYSTEM_H__ */
diff --git a/tools/build/gnome-shell.modules b/tools/build/gnome-shell.modules
index 91b79b2..51cef32 100644
--- a/tools/build/gnome-shell.modules
+++ b/tools/build/gnome-shell.modules
@@ -16,6 +16,38 @@
<repository type="git" name="colord.gitorious.org"
href="git://gitorious.org/colord/master.git"/>
+ <tarball id="libgee" version="0.6.0">
+ <pkg-config/>
+ <source hash="sha256:e586678d0a88637abeaaf850b62231000772e79ea6d9c4b45dc3cea99f778a7a" href="http://download.gnome.org/sources/libgee/0.6/libgee-0.6.0.tar.bz2" md5sum="4eb513b23ab6ea78884989518a4acf6f" size="477609"/>
+ <dependencies>
+ <dep package="glib"/>
+ </dependencies>
+ <suggests>
+ <dep package="gobject-introspection"/>
+ </suggests>
+ </tarball>
+
+ <tarball id="folks" version="0.6.0">
+ <source hash="sha256:50539da0b42564887bbce67d3a4107f3a7dbd8c6ae3b5d3a2d422b4f75a2b519" href="http://ftp.gnome.org/pub/GNOME/sources/folks/0.6/folks-0.6.0.tar.bz2" md5sum="4d5a3619c8b6e0714d02941c92826160" size="1261916"/>
+ <dependencies>
+ <dep package="libgee"/>
+ <dep package="vala"/>
+ <dep package="gobject-introspection"/>
+ <dep package="telepathy-glib"/>
+ <dep package="evolution-data-server"/>
+ </dependencies>
+ </tarball>
+
+ <tarball id="gnome-contacts">
+ <source hash="sha256:db52d4521e5d3335b5bf77ce5d1a7ec2cdea9ebf37ce12ddadda0503a2968cf9" href="http://ftp.gnome.org/pub/GNOME/sources/gnome-contacts/0.1/gnome-contacts-0.1.2.tar.bz2" size="377930"/>
+ <dependencies>
+ <dep package="folks"/>
+ <dep package="glib"/>
+ <dep package="gtk3"/>
+ <dep package="vala"/>
+ </dependencies>
+ </tarball>
+
<autotools id="gobject-introspection">
<branch repo="git.gnome.org" module="gobject-introspection"/>
<dependencies>
@@ -320,8 +352,10 @@
<dep package="gjs"/>
<dep package="caribou"/>
<dep package="dconf"/>
+ <dep package="folks"/>
<dep package="gconf"/>
<dep package="glib"/>
+ <dep package="gnome-contacts"/>
<dep package="gnome-menus"/>
<dep package="gnome-desktop-3"/>
<dep package="gsettings-desktop-schemas"/>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]