File Add-DBus-API-for-adding-contact-with-preset-properties.patch of Package gnome-contacts-42.0-1.25
From: Julian Sparber <julian@sparber.net>
Date: Thu, 24 Oct 2019 10:30:09 +0200
Subject: Add DBus API for adding contact with preset properties
The API takes an array of (key, value) pairs.
Supported keys:
These can be specified multiple times:
"email-addresses", "notes", "phone-numbers"
Only the last will be stored (because this properies are unique):
"alias", "full-name", "nickname"
Not all properites are supported for now because they can't be easily
set via DBus because they arn't a string
Example DBus usage:
gdbus call --session --dest org.gnome.Contacts --object-path /org/gnome/Contacts --method org.gtk.Actions.Activate 'new-contact-data' '[<[("email-addresses", "julian@sparber.net"), ("phone-numbers", "+39333333"), ("email-addresses", "secondo@example.com")]>]' '{}'
Upstream: https://gitlab.gnome.org/GNOME/gnome-contacts/-/merge_requests/95
---
data/ui/contacts-main-window.ui | 4 +--
src/contacts-app.vala | 65 +++++++++++++++++++++++++++++++++++++++++
src/contacts-contact-pane.vala | 3 +-
src/contacts-main-window.vala | 6 ++--
4 files changed, 71 insertions(+), 7 deletions(-)
diff --git a/data/ui/contacts-main-window.ui b/data/ui/contacts-main-window.ui
index 41b99e8..17709e1 100644
--- a/data/ui/contacts-main-window.ui
+++ b/data/ui/contacts-main-window.ui
@@ -52,7 +52,7 @@
<child>
<object class="GtkShortcut">
<property name="trigger"><Control>n</property>
- <property name="action">action(window.new-contact)</property>
+ <property name="action">action(app.new-contact)</property>
</object>
</child>
</object>
@@ -81,7 +81,7 @@
<object class="GtkButton" id="add_button">
<property name="tooltip-text" translatable="yes">Create new contact</property>
<property name="icon-name">list-add-symbolic</property>
- <property name="action-name">window.new-contact</property>
+ <property name="action-name">app.new-contact</property>
</object>
</child>
diff --git a/src/contacts-app.vala b/src/contacts-app.vala
index d241830..019241f 100644
--- a/src/contacts-app.vala
+++ b/src/contacts-app.vala
@@ -15,6 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+using Gee;
using Folks;
public class Contacts.App : Adw.Application {
@@ -30,6 +31,8 @@ public class Contacts.App : Adw.Application {
{ "about", show_about },
{ "change-book", change_address_book },
{ "online-accounts", online_accounts },
+ { "new-contact", on_new_contact },
+ { "new-contact-data", on_new_contact, "a(ss)" },
{ "show-contact", on_show_contact, "s"}
};
@@ -290,6 +293,68 @@ public class Contacts.App : Adw.Application {
setup_window.show ();
}
+ private void on_new_contact (SimpleAction action, Variant? param) {
+ HashTable<string, Value?> details = null;
+ if (param != null)
+ details = array_to_details (param);
+
+ if (window == null)
+ create_window ();
+
+ window.present ();
+ window.new_contact (details);
+ }
+
+ private void add_field_details<T> (HashTable<string, Value?> details, string key, string value) {
+ var val = details.get(key);
+ Set<T> current = (val != null) ? (Set<T>) details.get(key): null;
+
+ if (current == null) {
+ current = new HashSet<T> ();
+ details.set (key, current);
+ }
+ // WORKAROUND: This is a workaround for https://gitlab.gnome.org/GNOME/vala/issues/871
+ var obj = Object.new (typeof (T),
+ "t-type", typeof(string),
+ "t-dup-func", string.dup,
+ "t-destroy-func", free,
+ "value", value);
+ current.add (obj);
+ }
+
+ /* This converts a array of (key, value) to HashTable details expected by folks */
+ /* Todo: implement all property, currently only a couple of properties can be set via dbus */
+ private HashTable<string, Value?> array_to_details (Variant param) {
+ var details = new HashTable<string, Value?> (str_hash, str_equal);
+ foreach (Variant item in param) {
+ string? key = item.get_child_value(0) as string;
+ string? value = item.get_child_value(1) as string;
+ if (key == null || value == null)
+ continue;
+
+ switch (key) {
+ case "alias":
+ case "full-name":
+ case "nickname":
+ details.set (key, value);
+ break;
+ case "email-addresses":
+ add_field_details<EmailFieldDetails> (details, key, value);
+ break;
+ case "notes":
+ add_field_details<NoteFieldDetails> (details, key, value);
+ break;
+ case "phone-numbers":
+ add_field_details<PhoneFieldDetails> (details, key, value);
+ break;
+ default:
+ warning ("Not implemented or unknown property '%s'", key);
+ break;
+ }
+ }
+ return details;
+ }
+
private void on_show_contact(SimpleAction action, Variant? param) {
activate();
diff --git a/src/contacts-contact-pane.vala b/src/contacts-contact-pane.vala
index 9726216..f1e2d12 100644
--- a/src/contacts-contact-pane.vala
+++ b/src/contacts-contact-pane.vala
@@ -204,8 +204,7 @@ public class Contacts.ContactPane : Adw.Bin {
start_editing ();
}
- public void new_contact () {
- var details = new HashTable<string, Value?> (str_hash, str_equal);
+ public void new_contact (HashTable<string, Value?> details) {
string[] writeable_properties;
// TODO: make sure we have a primary_store
if (this.store.aggregator.primary_store != null) {
diff --git a/src/contacts-main-window.vala b/src/contacts-main-window.vala
index 4750f53..ce54571 100644
--- a/src/contacts-main-window.vala
+++ b/src/contacts-main-window.vala
@@ -22,7 +22,6 @@ using Folks;
public class Contacts.MainWindow : Adw.ApplicationWindow {
private const GLib.ActionEntry[] ACTION_ENTRIES = {
- { "new-contact", new_contact },
{ "edit-contact", edit_contact },
// { "share-contact", share_contact },
{ "unlink-contact", unlink_contact },
@@ -333,7 +332,7 @@ public class Contacts.MainWindow : Adw.ApplicationWindow {
}
}
- public void new_contact (GLib.SimpleAction action, GLib.Variant? parameter) {
+ public void new_contact (HashTable<string, Value?>? details = null) {
if (this.state == UiState.UPDATING || this.state == UiState.CREATING)
return;
@@ -343,7 +342,8 @@ public class Contacts.MainWindow : Adw.ApplicationWindow {
this.right_header.title_widget = new Adw.WindowTitle (_("New Contact"), "");
- this.contact_pane.new_contact ();
+ this.contact_pane.new_contact (
+ (details != null) ? details: new HashTable<string, Value?> (str_hash, str_equal));
show_contact_pane ();
}