summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiels De Graef <nielsdegraef@gmail.com>2022-09-07 10:14:23 +0200
committerNiels De Graef <nielsdegraef@gmail.com>2022-09-08 07:16:50 +0200
commit4ec2456f9fbc43ff8403e244a22d40a0aa514af5 (patch)
tree60a9cfb4ba17ba19090ee6666cb3ff6518123e98
parent1a16aafe01704ee4a5d5f9099e392983b2566f3a (diff)
downloadgnome-contacts-4ec2456f9fbc43ff8403e244a22d40a0aa514af5.tar.gz
Make sure `BinChunkChild`ren are sorted
Certain child properties should be sorted differently from others, namely the ones tagged as the "preferred" value (like the vCard PREF attribute) and any empty ones (which we would like to keep at the bottom). This means we can also remove the `AbstractFieldSorter` class, as that stopped being used when we ported everything to use the `Chunk` class (but we did forget to port its logic, which is now done with this commit)
-rw-r--r--src/contacts-abstract-field-details-sorter.vala75
-rw-r--r--src/core/contacts-bin-chunk.vala51
-rw-r--r--src/meson.build1
3 files changed, 48 insertions, 79 deletions
diff --git a/src/contacts-abstract-field-details-sorter.vala b/src/contacts-abstract-field-details-sorter.vala
deleted file mode 100644
index 430cac5..0000000
--- a/src/contacts-abstract-field-details-sorter.vala
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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 custom sorter that provides a consistent way of sorting
- * {@link Folks.AbstractFieldDetails} within the whole application.
- */
-public class Contacts.AbstractFieldDetailsSorter : Gtk.Sorter {
-
- public override Gtk.SorterOrder get_order () {
- return Gtk.SorterOrder.PARTIAL;
- }
-
- public override Gtk.Ordering compare (Object? item1, Object? item2) {
- unowned var a = (AbstractFieldDetails) item1;
- unowned var b = (AbstractFieldDetails) item2;
-
- // Fields with a PREF hint always go first (see VCard PREF attribute)
- var a_has_pref = has_pref (a);
- if (a_has_pref != has_pref (b))
- return (a_has_pref)? Gtk.Ordering.SMALLER : Gtk.Ordering.LARGER;
-
- // sort by field type first (e.g. "Home", "Work")
- unowned var type_set = select_typeset_from_fielddetails (a);
- var result = type_set.format_type (a).ascii_casecmp (type_set.format_type (b));
- if (result != 0)
- return Gtk.Ordering.from_cmpfunc (result);
-
- // Try to compare by value if types are equal
- unowned var aa = a as AbstractFieldDetails<string>;
- unowned var bb = b as AbstractFieldDetails<string>;
- if (aa != null && bb != null)
- return Gtk.Ordering.from_cmpfunc (strcmp (aa.value, bb.value));
-
- // No heuristics to fall back to.
- warning ("Unsupported AbstractFieldDetails value type");
- return Gtk.Ordering.EQUAL;
- }
-
- private bool has_pref (AbstractFieldDetails details) {
- var evolution_pref = details.get_parameter_values ("x-evolution-ui-slot");
- if (evolution_pref != null && Utils.get_first (evolution_pref) == "1")
- return true;
-
- foreach (var param in details.parameters["type"]) {
- if (param.ascii_casecmp ("PREF") == 0)
- return true;
- }
- return false;
- }
-
- private unowned TypeSet select_typeset_from_fielddetails (AbstractFieldDetails a) {
- if (a is EmailFieldDetails)
- return TypeSet.email;
- if (a is PhoneFieldDetails)
- return TypeSet.phone;
- return TypeSet.general;
- }
-}
diff --git a/src/core/contacts-bin-chunk.vala b/src/core/contacts-bin-chunk.vala
index 3229ddd..24b2f04 100644
--- a/src/core/contacts-bin-chunk.vala
+++ b/src/core/contacts-bin-chunk.vala
@@ -45,7 +45,9 @@ public abstract class Contacts.BinChunk : Chunk, GLib.ListModel {
/**
* Should be called by subclasses when they add a child.
- * It will make sure to attach the emptines check is appropriately applied.
+ *
+ * It will make sure to add the child in the appropriate position and that
+ * the emptines check is appropriately applied.
*/
protected void add_child (BinChunkChild child) {
if (child.is_empty && has_empty_child ())
@@ -55,8 +57,16 @@ public abstract class Contacts.BinChunk : Chunk, GLib.ListModel {
debug ("Child 'is-empty' changed, doing emptiness check");
emptiness_check ();
});
- this.elements.add (child);
- items_changed (this.elements.length - 1, 0, 1);
+
+ // Add in a sorted manner
+ int i = 0;
+ while (i < this.elements.length) {
+ if (child.compare (this.elements[i]) < 0)
+ break;
+ i++;
+ }
+ this.elements.insert (i, child);
+ items_changed (i, 0, 1);
}
/**
@@ -168,4 +178,39 @@ public abstract class Contacts.BinChunkChild : GLib.Object {
if (notify_empty)
notify_property ("is-empty");
}
+
+ /**
+ * Compares 2 children in an intuitive manner, so that preferred children go
+ * first and empty children are last
+ */
+ public int compare (BinChunkChild other) {
+ // Fields with a PREF hint always go first (see vCard PREF attribute)
+ var has_pref = has_pref_marker ();
+ if (has_pref != other.has_pref_marker ())
+ return has_pref? -1 : 1;
+
+ // Empty fields go last
+ var empty = this.is_empty;
+ if (empty != other.is_empty)
+ return empty? 1 : -1;
+
+ // FIXME: maybe also compare the types? (e.g. put HOME before WORK)
+ return 0;
+ }
+
+ /**
+ * Returns whether this child is marked as the "preferred" child, similar to
+ * the vCard PREF attribute
+ */
+ public bool has_pref_marker () {
+ var evolution_pref = this.parameters["x-evolution-ui-slot"];
+ if (evolution_pref != null && Utils.get_first (evolution_pref) == "1")
+ return true;
+
+ foreach (var param in this.parameters["type"]) {
+ if (param.ascii_casecmp ("PREF") == 0)
+ return true;
+ }
+ return false;
+ }
}
diff --git a/src/meson.build b/src/meson.build
index 5c2ef5d..b29028e 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -28,7 +28,6 @@ libcontacts_sources = files(
'core/contacts-urls-chunk.vala',
'core/contacts-vcard-type-mapping.vala',
- 'contacts-abstract-field-details-sorter.vala',
'contacts-chunk-filter.vala',
'contacts-chunk-empty-filter.vala',
'contacts-chunk-property-filter.vala',