[gnome-contacts/wip/nielsdg/vcard-import: 263/263] WIP




commit d6985892e6d689b8e135b50c259356f3949dc109
Author: Niels De Graef <nielsdegraef gmail com>
Date:   Thu Mar 31 09:30:40 2022 +0200

    WIP

 data/ui/contacts-list-pane.ui          |  6 ++++
 src/contacts-list-pane.vala            | 10 +++++-
 src/contacts-main-window.vala          |  8 +++++
 src/io/contacts-io-exporter.vala       | 31 +++++++++++++++++
 src/io/contacts-io-vcard-exporter.vala | 61 ++++++++++++++++++++++++++++++++++
 src/io/meson.build                     |  3 ++
 6 files changed, 118 insertions(+), 1 deletion(-)
---
diff --git a/data/ui/contacts-list-pane.ui b/data/ui/contacts-list-pane.ui
index e67fa216..f236d40c 100644
--- a/data/ui/contacts-list-pane.ui
+++ b/data/ui/contacts-list-pane.ui
@@ -22,6 +22,12 @@
         <child>
           <object class="GtkActionBar" id="actions_bar">
             <property name="revealed">False</property>
+            <child>
+              <object class="GtkButton" id="export_button">
+                <property name="label" translatable="yes">Export</property>
+                <signal name="clicked" handler="on_export_button_clicked"/>
+              </object>
+            </child>
             <child>
               <object class="GtkButton" id="link_button">
                 <property name="focus_on_click">False</property>
diff --git a/src/contacts-list-pane.vala b/src/contacts-list-pane.vala
index c30a8938..e9cd6bba 100644
--- a/src/contacts-list-pane.vala
+++ b/src/contacts-list-pane.vala
@@ -31,7 +31,8 @@ public class Contacts.ListPane : Adw.Bin {
 
   [GtkChild]
   private unowned Gtk.Button link_button;
-
+  [GtkChild]
+  private unowned Gtk.Button export_button;
   [GtkChild]
   private unowned Gtk.Button delete_button;
 
@@ -42,6 +43,7 @@ public class Contacts.ListPane : Adw.Bin {
 
   public signal void selection_changed (Individual? individual);
   public signal void link_contacts (Gee.LinkedList<Individual> individual);
+  public signal void export_contacts (Gee.LinkedList<Individual> individual);
   public signal void delete_contacts (Gee.LinkedList<Individual> individual);
   public signal void contacts_marked (int contacts_marked);
 
@@ -69,6 +71,7 @@ public class Contacts.ListPane : Adw.Bin {
 
     this.contacts_list.contacts_marked.connect ((nr_contacts_marked) => {
         this.delete_button.sensitive = (nr_contacts_marked > 0);
+        this.export_button.sensitive = (nr_contacts_marked > 0);
         this.link_button.sensitive = (nr_contacts_marked > 1);
         contacts_marked (nr_contacts_marked);
     });
@@ -105,6 +108,11 @@ public class Contacts.ListPane : Adw.Bin {
     link_contacts (this.contacts_list.get_marked_contacts ());
   }
 
+  [GtkCallback]
+  private void on_export_button_clicked (Gtk.Button export_button) {
+    export_contacts (this.contacts_list.get_marked_contacts ());
+  }
+
   [GtkCallback]
   private void on_delete_button_clicked (Gtk.Button delete_button) {
     delete_contacts (this.contacts_list.get_marked_contacts_and_hide ());
diff --git a/src/contacts-main-window.vala b/src/contacts-main-window.vala
index 4750f538..821cedde 100644
--- a/src/contacts-main-window.vala
+++ b/src/contacts-main-window.vala
@@ -148,6 +148,7 @@ public class Contacts.MainWindow : Adw.ApplicationWindow {
     bind_property ("state", this.list_pane, "state", BindingFlags.BIDIRECTIONAL | BindingFlags.SYNC_CREATE);
     this.list_pane.selection_changed.connect (list_pane_selection_changed_cb);
     this.list_pane.link_contacts.connect (list_pane_link_contacts_cb);
+    this.list_pane.export_contacts.connect (export_contacts);
     this.list_pane.delete_contacts.connect (delete_contacts);
 
     this.list_pane.contacts_marked.connect ((nr_contacts) => {
@@ -447,6 +448,13 @@ public class Contacts.MainWindow : Adw.ApplicationWindow {
     this.toast_overlay.add_toast (toast);
   }
 
+  private void export_contacts (Gee.List<Individual> individuals) {
+    var exporter = new Io.VCardExporter ();
+
+    var ret = exporter.export_to_string (individuals.to_array ());
+    warning ("===============VCARD===============\n%s\n==============", ret);
+  }
+
   private void delete_contacts (Gee.List<Individual> individuals) {
     set_shown_contact (null);
     this.state = UiState.NORMAL;
diff --git a/src/io/contacts-io-exporter.vala b/src/io/contacts-io-exporter.vala
new file mode 100644
index 00000000..18cfc7ab
--- /dev/null
+++ b/src/io/contacts-io-exporter.vala
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 Niels De Graef <nielsdegraef gmail com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+using Folks;
+
+/**
+ * An Io.Exporter is an object that can deal with exporting one or more
+ * contacts into a serialized format (VCard is the most common example, but
+ * there exist also CSV based formats and others).
+ *
+ * Note that unlike a Io.Importer, we can skip the whole {@link GLib.HashTable}
+ * dance, since we aren't dealing with untrusted data anymore.
+ */
+public abstract class Contacts.Io.Exporter {
+
+  public abstract string export_to_string (Individual[] individuals) throws GLib.Error;
+}
diff --git a/src/io/contacts-io-vcard-exporter.vala b/src/io/contacts-io-vcard-exporter.vala
new file mode 100644
index 00000000..52c19f46
--- /dev/null
+++ b/src/io/contacts-io-vcard-exporter.vala
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 Niels De Graef <nielsdegraef gmail com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+using Folks;
+
+/**
+ * a {@link Contacts.Io.Exporter} that specifically deals with exporting
+ * contacts to VCard files/strings.
+ */
+public class Contacts.Io.VCardExporter : Contacts.Io.Exporter {
+
+  // XXX find our own enum
+  private E.VCardFormat vcard_format = E.VCardFormat.@30;
+
+  public VCardExporter () {
+  }
+
+  public override string export_to_string (Individual[] individuals) throws GLib.Error {
+    StringBuilder result = new StringBuilder ();
+
+    foreach (unowned var individual in individuals) {
+      // XXX at a certain point, we should aggregate personas, but that
+      // requires more thinking through
+
+      foreach (var persona in individual.personas) {
+        string vcard_str = persona_to_vcard (result, persona);
+        result.append (vcard_str);
+        result.append_c ('\n');
+      }
+    }
+
+    return result.str;
+  }
+
+  private string append_persona_vcard (Persona persona) {
+    // We try to take a shortcut in case we have an Edsf.Persona, since
+    // that's an E.VCard already
+    if (persona is Edsf.Persona) {
+      unowned var contact = ((Edsf.Persona) persona).contact;
+      return contact.to_string (this.vcard_format);
+    }
+
+    warning ("NOT EDSF FRO %s", individual.display_name);
+    var vcard = new E.VCard ();
+    result.append (vcard.to_string (this.vcard_format));
+  }
+}
diff --git a/src/io/meson.build b/src/io/meson.build
index 7bbead4b..08b21182 100644
--- a/src/io/meson.build
+++ b/src/io/meson.build
@@ -1,7 +1,9 @@
 # Common library
 contacts_io_sources = files(
   'contacts-io.vala',
+  'contacts-io-exporter.vala',
   'contacts-io-importer.vala',
+  'contacts-io-vcard-exporter.vala',
   'contacts-io-vcard-importer.vala',
 )
 
@@ -19,6 +21,7 @@ contacts_c_args = [
 
 contacts_io_deps = [
   folks,
+  folks_eds,
   gee,
   gio_unix,
   glib,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]