diff options
author | Niels De Graef <nielsdegraef@gmail.com> | 2022-09-07 10:14:23 +0200 |
---|---|---|
committer | Niels De Graef <nielsdegraef@gmail.com> | 2022-09-08 07:16:50 +0200 |
commit | 4ec2456f9fbc43ff8403e244a22d40a0aa514af5 (patch) | |
tree | 60a9cfb4ba17ba19090ee6666cb3ff6518123e98 | |
parent | 1a16aafe01704ee4a5d5f9099e392983b2566f3a (diff) | |
download | gnome-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.vala | 75 | ||||
-rw-r--r-- | src/core/contacts-bin-chunk.vala | 51 | ||||
-rw-r--r-- | src/meson.build | 1 |
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', |