summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiels De Graef <nielsdegraef@gmail.com>2017-12-25 14:50:54 +0100
committerNiels De Graef <nielsdegraef@gmail.com>2018-01-17 10:08:35 +0100
commit4294cd7cfec747d888e323ef5a029ef09cc6dc74 (patch)
tree2d0bb67ad71ff56593ef817f660da9905d13c82b
parentc54d1bc9055d4a6109c26745d807a3dabfba1934 (diff)
downloadgnome-contacts-4294cd7cfec747d888e323ef5a029ef09cc6dc74.tar.gz
Port contacts-esd-setup to Vala.
-rw-r--r--meson.build1
-rw-r--r--po/POTFILES.in2
-rw-r--r--src/contacts-contact.vala8
-rw-r--r--src/contacts-esd-setup.c323
-rw-r--r--src/contacts-esd-setup.h11
-rw-r--r--src/contacts-esd-setup.vala193
-rw-r--r--src/meson.build14
-rw-r--r--vapi/custom.vapi18
8 files changed, 202 insertions, 368 deletions
diff --git a/meson.build b/meson.build
index 8cd97db..2746fec 100644
--- a/meson.build
+++ b/meson.build
@@ -81,6 +81,7 @@ conf.set_quoted('PACKAGE_VERSION', meson.project_version())
conf.set_quoted('PKGDATADIR', pkgdatadir)
conf.set_quoted('PKGLIBDIR', pkglibdir)
conf.set_quoted('VERSION', meson.project_version())
+conf.set('GOA_API_IS_SUBJECT_TO_CHANGE', true)
configure_file(output: 'config.h', configuration: conf)
# Post-install scripts
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 778d939..1ac14a4 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -22,7 +22,7 @@ src/contacts-contact-list.vala
src/contacts-contact-pane.vala
src/contacts-contact-sheet.vala
src/contacts-contact.vala
-src/contacts-esd-setup.c
+src/contacts-esd-setup.vala
src/contacts-linked-accounts-dialog.vala
src/contacts-link-suggestion-grid.vala
src/contacts-settings.vala
diff --git a/src/contacts-contact.vala b/src/contacts-contact.vala
index e7180ee..08dcc12 100644
--- a/src/contacts-contact.vala
+++ b/src/contacts-contact.vala
@@ -655,9 +655,9 @@ public class Contacts.Contact : GLib.Object {
public static string format_persona_store_name (PersonaStore store) {
if (store.type_id == "eds") {
- unowned string? eds_name = lookup_esource_name_by_uid (store.id);
+ string? eds_name = lookup_esource_name_by_uid (store.id);
if (eds_name != null)
- return eds_name;
+ return eds_name;
}
#if HAVE_TELEPATHY
if (store.type_id == "telepathy") {
@@ -750,9 +750,9 @@ public class Contacts.Contact : GLib.Object {
else if (persona_is_google_other (persona))
return _("Google");
- unowned string? eds_name = lookup_esource_name_by_uid_for_contact (store.id);
+ string? eds_name = lookup_esource_name_by_uid_for_contact (store.id);
if (eds_name != null)
- return eds_name;
+ return eds_name;
}
#if HAVE_TELEPATHY
if (store.type_id == "telepathy") {
diff --git a/src/contacts-esd-setup.c b/src/contacts-esd-setup.c
deleted file mode 100644
index 936be16..0000000
--- a/src/contacts-esd-setup.c
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * This code is from evolution with this license:
- *
- * This program 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 of the License, or (at your option) version 3.
- *
- * This program 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 the program; if not, see <http://www.gnu.org/licenses/>
- *
- */
-
-#include "config.h"
-#include <libebook/libebook.h>
-#include <libedataserverui/libedataserverui.h>
-#include <glib/gi18n-lib.h>
-
-#define GOA_API_IS_SUBJECT_TO_CHANGE
-#include <goa/goa.h>
-#include <gtk/gtk.h>
-
-static void
-eds_show_source_error (const gchar *where,
- const gchar *what,
- ESource *source,
- const GError *error)
-{
- if (!error || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
- return;
-
- /* TODO Show the error in UI, somehow */
- g_warning ("%s: %s '%s': %s", where, what, e_source_get_display_name (source), error->message);
-}
-
-static void
-eds_source_invoke_authenticate_cb (GObject *source_object,
- GAsyncResult *result,
- gpointer user_data)
-{
- ESource *source = E_SOURCE (source_object);
- GError *error = NULL;
-
- if (!e_source_invoke_authenticate_finish (source, result, &error) &&
- !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
- eds_show_source_error (G_STRFUNC, "Failed to invoke authenticate", source, error);
- }
-
- g_clear_error (&error);
-}
-
-static void
-eds_source_trust_prompt_done_cb (GObject *source_object,
- GAsyncResult *result,
- gpointer user_data)
-{
- ETrustPromptResponse response = E_TRUST_PROMPT_RESPONSE_UNKNOWN;
- ESource *source = E_SOURCE (source_object);
- GError *error = NULL;
-
- if (!e_trust_prompt_run_for_source_finish (source, result, &response, &error)) {
- eds_show_source_error (G_STRFUNC, "Failed to prompt for trust for", source, error);
- } else if (response == E_TRUST_PROMPT_RESPONSE_ACCEPT || response == E_TRUST_PROMPT_RESPONSE_ACCEPT_TEMPORARILY) {
- /* Use NULL credentials to reuse those from the last time. */
- e_source_invoke_authenticate (source, NULL, NULL /* cancellable */, eds_source_invoke_authenticate_cb, NULL);
- }
-
- g_clear_error (&error);
-}
-
-static void
-eds_source_credentials_required_cb (ESourceRegistry *registry,
- ESource *source,
- ESourceCredentialsReason reason,
- const gchar *certificate_pem,
- GTlsCertificateFlags certificate_errors,
- const GError *op_error,
- ECredentialsPrompter *credentials_prompter)
-{
- if (e_credentials_prompter_get_auto_prompt_disabled_for (credentials_prompter, source))
- return;
-
- if (reason == E_SOURCE_CREDENTIALS_REASON_SSL_FAILED) {
- e_trust_prompt_run_for_source (e_credentials_prompter_get_dialog_parent (credentials_prompter),
- source, certificate_pem, certificate_errors, op_error ? op_error->message : NULL,
- TRUE /* allow_source_save */, NULL /* cancellable */, eds_source_trust_prompt_done_cb, NULL);
- } else if (reason == E_SOURCE_CREDENTIALS_REASON_ERROR && op_error) {
- eds_show_source_error (G_STRFUNC, "Failed to authenticate", source, op_error);
- }
-}
-
-ESourceRegistry *eds_source_registry = NULL;
-static ECredentialsPrompter *eds_credentials_prompter = NULL;
-
-gboolean contacts_ensure_eds_accounts (gboolean allow_interaction)
-{
- ESourceCredentialsProvider *credentials_provider;
- GList *list, *link;
- GError *error = NULL;
-
- if (eds_source_registry)
- return TRUE;
-
- /* XXX This blocks while connecting to the D-Bus service.
- * Maybe it should be created in the Contacts class
- * and passed in as needed? */
-
- eds_source_registry = e_source_registry_new_sync (NULL, &error);
-
- /* If this fails it's game over. */
- if (error != NULL)
- {
- g_warning ("%s: %s", G_STRFUNC, error->message);
- return FALSE;
- }
-
- eds_credentials_prompter = e_credentials_prompter_new (eds_source_registry);
-
- if (!allow_interaction)
- e_credentials_prompter_set_auto_prompt (eds_credentials_prompter, FALSE);
-
- /* First disable credentials prompt for all but addressbook sources... */
- list = e_source_registry_list_sources (eds_source_registry, NULL);
-
- for (link = list; link != NULL; link = g_list_next (link)) {
- ESource *source = E_SOURCE (link->data);
-
- /* Mark for skip also currently disabled sources */
- if (!e_source_has_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK))
- e_credentials_prompter_set_auto_prompt_disabled_for (eds_credentials_prompter, source, TRUE);
- }
-
- g_list_free_full (list, g_object_unref);
-
- credentials_provider = e_credentials_prompter_get_provider (eds_credentials_prompter);
-
- /* ...then enable credentials prompt for credential source of the addressbook sources,
- which can be a collection source. */
- list = e_source_registry_list_sources (eds_source_registry, E_SOURCE_EXTENSION_ADDRESS_BOOK);
-
- for (link = list; link != NULL; link = g_list_next (link)) {
- ESource *source = E_SOURCE (link->data), *cred_source;
-
- cred_source = e_source_credentials_provider_ref_credentials_source (credentials_provider, source);
- if (cred_source && !e_source_equal (source, cred_source))
- e_credentials_prompter_set_auto_prompt_disabled_for (eds_credentials_prompter, cred_source, FALSE);
- g_clear_object (&cred_source);
- }
-
- g_list_free_full (list, g_object_unref);
-
- /* The eds_credentials_prompter responses to REQUIRED and REJECTED reasons,
- the SSL_FAILED should be handled elsewhere. */
- g_signal_connect (eds_source_registry, "credentials-required",
- G_CALLBACK (eds_source_credentials_required_cb), eds_credentials_prompter);
-
- e_credentials_prompter_process_awaiting_credentials (eds_credentials_prompter);
-
- return TRUE;
-}
-
-gboolean contacts_has_goa_account (void)
-{
- GList *list, *link;
- gboolean has_goa_contacts = FALSE;
-
- list = e_source_registry_list_sources (eds_source_registry, E_SOURCE_EXTENSION_GOA);
-
- for (link = list; link != NULL; link = g_list_next (link)) {
- ESource *source = E_SOURCE (link->data);
- ESourceCollection *extension;
-
- /* Ignore disabled accounts. */
- if (!e_source_get_enabled (source))
- continue;
-
- /* All ESources with a [GNOME Online Accounts] extension
- * should also have a [Collection] extension. Verify it. */
- if (!e_source_has_extension (source, E_SOURCE_EXTENSION_COLLECTION))
- continue;
-
- extension = e_source_get_extension (source, E_SOURCE_EXTENSION_COLLECTION);
-
- /* This corresponds to the Contacts ON/OFF switch in GOA. */
- if (e_source_collection_get_contacts_enabled (extension)) {
- has_goa_contacts = TRUE;
- break;
- }
- }
-
- g_list_free_full (list, (GDestroyNotify) g_object_unref);
-
- return has_goa_contacts;
-}
-
-gboolean
-contacts_esource_uid_is_google (const char *uid)
-{
- ESource *source;
- gboolean uid_is_google = FALSE;
-
- source = e_source_registry_ref_source (eds_source_registry, uid);
- if (source == NULL)
- return FALSE;
-
- /* Make sure it's really an address book. */
- if (e_source_has_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK)) {
- ESourceBackend *extension;
- const gchar *backend_name;
-
- extension = e_source_get_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK);
- backend_name = e_source_backend_get_backend_name (extension);
-
- uid_is_google = (g_strcmp0 (backend_name, "google") == 0);
- }
-
- g_object_unref (source);
-
- return uid_is_google;
-}
-
-const char *
-contacts_lookup_esource_name_by_uid (const char *uid)
-{
- ESource *source;
- ESource *builtin_address_book;
- const gchar *display_name;
-
- source = e_source_registry_ref_source (eds_source_registry, uid);
- if (source == NULL)
- return NULL;
-
- builtin_address_book = e_source_registry_ref_builtin_address_book (eds_source_registry);
-
- if (e_source_equal (source, builtin_address_book))
- display_name = _("Local Address Book");
-
- else if (contacts_esource_uid_is_google (uid))
- display_name = _("Google");
-
- else
- display_name = e_source_get_display_name (source);
-
- g_object_unref (builtin_address_book);
- g_object_unref (source);
-
- return display_name;
-}
-
-const char *
-contacts_lookup_esource_name_by_uid_for_contact (const char *uid)
-{
- ESource *source;
- ESource *builtin_address_book;
- const gchar *display_name;
-
- source = e_source_registry_ref_source (eds_source_registry, uid);
- if (source == NULL)
- return NULL;
-
- builtin_address_book = e_source_registry_ref_builtin_address_book (eds_source_registry);
-
- if (e_source_equal (source, builtin_address_book))
- return _("Local Contact");
-
- else if (contacts_esource_uid_is_google (uid))
- display_name = _("Google");
-
- else
- display_name = e_source_get_display_name (source);
-
- g_object_unref (builtin_address_book);
- g_object_unref (source);
-
- return display_name;
-}
-
-GtkWidget*
-contacts_get_icon_for_goa_account (const char* goa_id)
-{
- GoaClient *client;
- GoaObject *goa_object;
- GoaAccount *goa_account;
- GError *error;
-
- const gchar* icon_data;
- GIcon *provider_icon;
- GtkWidget *image_icon;
-
- error = NULL;
- client = goa_client_new_sync (NULL, &error);
- if (client == NULL)
- {
- g_error_free (error);
- return NULL;
- }
-
- goa_object = goa_client_lookup_by_id (client, goa_id);
- goa_account = goa_object_get_account (goa_object);
-
- icon_data = goa_account_get_provider_icon (goa_account);
-
- error = NULL;
- provider_icon = g_icon_new_for_string (icon_data, &error);
- if (provider_icon == NULL)
- {
- g_debug ("Error obtaining provider_icon");
- g_error_free (error);
- }
- image_icon = gtk_image_new_from_gicon (provider_icon, GTK_ICON_SIZE_DIALOG);
-
- g_object_unref (goa_account);
- g_object_unref (goa_object);
-
- g_clear_object (&client);
-
- return image_icon;
-}
diff --git a/src/contacts-esd-setup.h b/src/contacts-esd-setup.h
deleted file mode 100644
index 0096618..0000000
--- a/src/contacts-esd-setup.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#include <libebook/libebook.h>
-#include <gtk/gtk.h>
-
-gboolean contacts_ensure_eds_accounts (gboolean allow_interaction);
-const char *contacts_lookup_esource_name_by_uid (const char *uid);
-const char *contacts_lookup_esource_name_by_uid_for_contact (const char *uid);
-gboolean contacts_esource_uid_is_google (const char *uid);
-gboolean contacts_has_goa_account (void);
-extern ESourceRegistry *eds_source_registry;
-extern gboolean contacts_avoid_goa_workaround;
-GtkWidget* contacts_get_icon_for_goa_account (const char* goa_id);
diff --git a/src/contacts-esd-setup.vala b/src/contacts-esd-setup.vala
new file mode 100644
index 0000000..51ba791
--- /dev/null
+++ b/src/contacts-esd-setup.vala
@@ -0,0 +1,193 @@
+/*
+ * This code is ported to Vala from evolution with this license:
+ *
+ * This program 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 of the License, or (at your option) version 3.
+ *
+ * This program 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 the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+// FIXME: the async bindings seem to be broken for this function.
+extern void e_trust_prompt_run_for_source (Gtk.Window parent, E.Source source, string certificate_pem, GLib.TlsCertificateFlags certificate_errors, string? error_text, bool allow_source_save, GLib.Cancellable? cancellable, AsyncReadyCallback callback);
+extern bool e_trust_prompt_run_for_source_finish (E.Source source, AsyncResult result, out E.TrustPromptResponse response) throws GLib.Error;
+
+namespace Contacts {
+
+public E.SourceRegistry? eds_source_registry = null;
+private E.CredentialsPrompter? eds_credentials_prompter = null;
+
+public bool ensure_eds_accounts (bool allow_interaction) {
+ if (eds_source_registry != null)
+ return true;
+
+ // XXX This blocks while connecting to the D-Bus service.
+ // Maybe it should be created in the Contacts class and passed in as needed?
+
+ try {
+ eds_source_registry = new E.SourceRegistry.sync (null);
+ } catch (Error e) { // If this fails it's game over.
+ warning ("Couldn't load EDS SourceRegistry: %s", e.message);
+ return false;
+ }
+
+ eds_credentials_prompter = new E.CredentialsPrompter (eds_source_registry);
+
+ if (!allow_interaction)
+ eds_credentials_prompter.set_auto_prompt (false);
+
+ var credentials_provider = eds_credentials_prompter.get_provider ();
+
+ // First disable credentials prompt for all but addressbook sources...
+ foreach (var source in eds_source_registry.list_sources (null)) {
+ // Mark for skip also currently disabled sources
+ if (!source.has_extension (E.SOURCE_EXTENSION_ADDRESS_BOOK))
+ eds_credentials_prompter.set_auto_prompt_disabled_for (source, true);
+ }
+
+ // ...then enable credentials prompt for credential source of the addressbook sources,
+ // which can be a collection source.
+ foreach (var source in eds_source_registry.list_sources (E.SOURCE_EXTENSION_ADDRESS_BOOK)) {
+ var cred_source = credentials_provider.ref_credentials_source (source);
+ if (cred_source != null && !source.equal (cred_source))
+ eds_credentials_prompter.set_auto_prompt_disabled_for (cred_source, false);
+ }
+
+ // The eds_credentials_prompter responses to REQUIRED and REJECTED reasons,
+ // the SSL_FAILED should be handled elsewhere.
+ eds_source_registry.credentials_required.connect((src, reason, cert_pem, cert_err, err) => {
+ on_credentials_required.begin (src, reason, cert_pem, cert_err, err);
+ });
+
+ eds_credentials_prompter.process_awaiting_credentials ();
+
+ return true;
+}
+
+private async void on_credentials_required (E.Source source, E.SourceCredentialsReason reason, string cert_pem, TlsCertificateFlags cert_errors, Error err) {
+ if (eds_credentials_prompter.get_auto_prompt_disabled_for (source))
+ return;
+
+ if (reason == E.SourceCredentialsReason.ERROR && err != null) {
+ warning ("Failed to autheticate for source \"%s\": %s", source.display_name, err.message);
+ return;
+ }
+
+ if (reason == E.SourceCredentialsReason.SSL_FAILED) {
+ e_trust_prompt_run_for_source (eds_credentials_prompter.get_dialog_parent (),
+ source, cert_pem, cert_errors, (err != null)? err.message : null, true,
+ null, (obj, res) => on_source_trust_prompt_has_run.begin (source, res));
+ }
+}
+
+private async void on_source_trust_prompt_has_run (E.Source source, AsyncResult res) {
+ try {
+ e_trust_prompt_run_for_source_finish (source, res, null);
+ } catch (Error e) {
+ warning ("Failed to prompt for trust for source \"%s\": %s", source.display_name, e.message);
+ return;
+ }
+
+ try {
+ // Use null credentials to reuse those from the last time.
+ yield source.invoke_authenticate (null, null);
+ } catch (Error e) {
+ warning ("Failed to invoke authenticate() for source \"%s\": %s", source.display_name, e.message);
+ }
+}
+
+public bool has_goa_account () {
+ foreach (var source in eds_source_registry.list_sources (E.SOURCE_EXTENSION_GOA)) {
+ // Ignore disabled accounts.
+ if (!source.enabled)
+ continue;
+
+ // All ESources with a [GNOME Online Accounts] extension
+ // should also have a [Collection] extension. Verify it.
+ if (!source.has_extension (E.SOURCE_EXTENSION_COLLECTION))
+ continue;
+
+ // This corresponds to the Contacts ON/OFF switch in GOA. */
+ if (((E.SourceCollection) source.get_extension (E.SOURCE_EXTENSION_COLLECTION)).contacts_enabled) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+public bool esource_uid_is_google (string uid) {
+ var source = eds_source_registry.ref_source (uid);
+ if (source == null)
+ return false;
+
+ /* Make sure it's really an address book. */
+ if (source.has_extension (E.SOURCE_EXTENSION_ADDRESS_BOOK)) {
+ var extension = source.get_extension (E.SOURCE_EXTENSION_ADDRESS_BOOK);
+ return ((E.SourceBackend) extension).backend_name == "google";
+ }
+
+ return false;
+}
+
+public string? lookup_esource_name_by_uid (string uid) {
+ var source = eds_source_registry.ref_source (uid);
+ if (source == null)
+ return null;
+
+ var builtin_address_book = eds_source_registry.ref_builtin_address_book ();
+
+ if (source.equal (builtin_address_book))
+ return _("Local Address Book");
+
+ if (esource_uid_is_google (uid))
+ return _("Google");
+
+ return source.display_name;
+}
+
+public string? lookup_esource_name_by_uid_for_contact (string uid) {
+ var source = eds_source_registry.ref_source (uid);
+ if (source == null)
+ return null;
+
+ var builtin_address_book = eds_source_registry.ref_builtin_address_book ();
+ if (source.equal (builtin_address_book))
+ return _("Local Contact");
+
+ if (esource_uid_is_google (uid))
+ return _("Google");
+
+ return source.display_name;
+}
+
+public Gtk.Image? get_icon_for_goa_account (string goa_id) {
+ Goa.Client client;
+ try {
+ client = new Goa.Client.sync (null);
+ } catch (Error e) {
+ debug ("Couldn't load GOA client \"%s\": %s", goa_id, e.message);
+ return null;
+ }
+
+ var goa_object = client.lookup_by_id (goa_id);
+
+ Icon provider_icon;
+ try {
+ provider_icon = Icon.new_for_string (goa_object.account.provider_icon);
+ } catch (Error e) {
+ debug ("Couldn't load icon for GOA provider \"%s\"", goa_id);
+ return null;
+ }
+
+ return new Gtk.Image.from_gicon (provider_icon, Gtk.IconSize.DIALOG);
+}
+}
diff --git a/src/meson.build b/src/meson.build
index b072ad0..14f2604 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -15,6 +15,7 @@ contacts_vala_sources = [
'contacts-contact-pane.vala',
'contacts-contact-sheet.vala',
'contacts-contact.vala',
+ 'contacts-esd-setup.vala',
'contacts-in-app-notification.vala',
'contacts-link-suggestion-grid.vala',
'contacts-linked-accounts-dialog.vala',
@@ -38,7 +39,6 @@ contacts_vala_args = [
contacts_c_sources = [
'cc-crop-area.c',
- 'contacts-esd-setup.c',
]
contacts_c_args = [
@@ -96,23 +96,15 @@ executable('gnome-contacts', contacts_sources,
)
# The search provider
-contact_search_provider_vala_sources = [
+contact_search_provider_sources = [
'contacts-contact.vala',
+ 'contacts-esd-setup.vala',
'contacts-shell-search-provider.vala',
'contacts-store.vala',
'contacts-types.vala',
'contacts-utils.vala',
]
-contact_search_provider_c_sources = [
- 'contacts-esd-setup.c',
-]
-
-contact_search_provider_sources = [
- contact_search_provider_vala_sources,
- contact_search_provider_c_sources,
-]
-
executable('gnome-contacts-search-provider', contact_search_provider_sources,
include_directories: config_h_dir,
vala_args: contacts_vala_args,
diff --git a/vapi/custom.vapi b/vapi/custom.vapi
index 5fe3561..c48e3e8 100644
--- a/vapi/custom.vapi
+++ b/vapi/custom.vapi
@@ -1,21 +1,3 @@
-[CCode (cprefix = "Contacts", lower_case_cprefix = "contacts_", cheader_filename = "contacts-esd-setup.h")]
-namespace Contacts {
- [CCode (cname = "contacts_ensure_eds_accounts")]
- public static bool ensure_eds_accounts (bool allow_interaction);
- [CCode (cname = "contacts_lookup_esource_name_by_uid")]
- public static unowned string? lookup_esource_name_by_uid (string uid);
- [CCode (cname = "contacts_lookup_esource_name_by_uid_for_contact")]
- public static unowned string? lookup_esource_name_by_uid_for_contact (string uid);
- [CCode (cname = "contacts_esource_uid_is_google")]
- public static bool esource_uid_is_google (string uid);
- [CCode (cname = "contacts_has_goa_account")]
- public static bool has_goa_account ();
- [CCode (cname = "eds_source_registry")]
- public static E.SourceRegistry eds_source_registry;
- [CCode (cname = "contacts_get_icon_for_goa_account")]
- public static unowned Gtk.Widget get_icon_for_goa_account (string goa_id);
-}
-
[CCode (cprefix = "Cc", lower_case_cprefix = "cc_", cheader_filename = "cc-crop-area.h")]
namespace Cc {
public class CropArea : Gtk.DrawingArea {