diff options
-rw-r--r-- | data/ui/contacts-window.ui | 91 | ||||
-rw-r--r-- | src/contacts-app.vala | 2 | ||||
-rw-r--r-- | src/contacts-contact-list.vala | 22 | ||||
-rw-r--r-- | src/contacts-list-pane.vala | 4 | ||||
-rw-r--r-- | src/contacts-settings.vala | 14 | ||||
-rw-r--r-- | src/contacts-window.vala | 17 | ||||
-rw-r--r-- | src/org.gnome.Contacts.gschema.xml | 8 |
7 files changed, 143 insertions, 15 deletions
diff --git a/data/ui/contacts-window.ui b/data/ui/contacts-window.ui index cef3289..e88721c 100644 --- a/data/ui/contacts-window.ui +++ b/data/ui/contacts-window.ui @@ -1,7 +1,76 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.15.2 on Thu Aug 15 15:33:02 2013 --> <interface> - <!-- interface-requires gtk+ 3.10 --> + <!-- interface-requires gtk+ 3.22 --> + <object class="GtkPopover" id="hamburger_menu_popover"> + <child> + <object class="GtkGrid"> + <property name="visible">True</property> + <property name="row_spacing">6</property> + <property name="margin">18</property> + <property name="width_request">200</property> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="halign">start</property> + <property name="label" translatable="yes">List contacts by:</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="top_attach">0</property> + <property name="width">2</property> + </packing> + </child> + <child> + <object class="GtkRadioButton" id="sort_on_firstname_button"> + <property name="visible">True</property> + <property name="group">sort_on_firstname_button</property> + </object> + <packing> + <property name="top_attach">1</property> + <property name="left_attach">1</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="halign">start</property> + <property name="hexpand">True</property> + <property name="label" translatable="yes">First name</property> + <property name="mnemonic_widget">sort_on_firstname_button</property> + </object> + <packing> + <property name="top_attach">1</property> + <property name="left_attach">0</property> + </packing> + </child> + <child> + <object class="GtkRadioButton" id="sort_on_surname_button"> + <property name="visible">True</property> + <property name="group">sort_on_firstname_button</property> + </object> + <packing> + <property name="top_attach">2</property> + <property name="left_attach">1</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="halign">start</property> + <property name="hexpand">True</property> + <property name="label" translatable="yes">Surname</property> + <property name="mnemonic_widget">sort_on_surname_button</property> + </object> + <packing> + <property name="top_attach">2</property> + <property name="left_attach">0</property> + </packing> + </child> + </object> + </child> + </object> <template class="ContactsWindow" parent="GtkApplicationWindow"> <property name="can_focus">False</property> <property name="default_width">800</property> @@ -51,6 +120,24 @@ </packing> </child> <child> + <object class="GtkMenuButton" id="hamburger_menu_button"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="focus_on_click">False</property> + <property name="popover">hamburger_menu_popover</property> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="icon_name">open-menu-symbolic</property> + </object> + </child> + </object> + <packing> + <property name="pack_type">end</property> + </packing> + </child> + <child> <object class="GtkButton" id="select_cancel_button"> <property name="visible">False</property> <property name="can_focus">True</property> diff --git a/src/contacts-app.vala b/src/contacts-app.vala index 3b0224b..b2a0e58 100644 --- a/src/contacts-app.vala +++ b/src/contacts-app.vala @@ -226,7 +226,7 @@ public class Contacts.App : Gtk.Application { } private void create_window () { - this.window = new Contacts.Window (this, this.contacts_store); + this.window = new Contacts.Window (this.settings, this, this.contacts_store); } private void schedule_window_creation () { diff --git a/src/contacts-contact-list.vala b/src/contacts-contact-list.vala index fd51d06..2696002 100644 --- a/src/contacts-contact-list.vala +++ b/src/contacts-contact-list.vala @@ -102,9 +102,11 @@ public class Contacts.ContactList : ListBox { private Store store; + private Settings settings; + public UiState state { get; set; } - public ContactList (Store store, Query query) { + public ContactList (Settings settings, Store store, Query query) { this.selection_mode = Gtk.SelectionMode.BROWSE; this.store = store; this.filter_query = query; @@ -113,6 +115,9 @@ public class Contacts.ContactList : ListBox { this.notify["state"].connect (on_ui_state_changed); + this.settings = settings; + this.settings.changed["sort-on-surname"].connect(invalidate_sort); + this.store.added.connect (contact_added_cb); this.store.removed.connect (contact_removed_cb); foreach (var c in this.store.get_contacts ()) @@ -146,8 +151,19 @@ public class Contacts.ContactList : ListBox { if (a.is_favourite != b.is_favourite) return a.is_favourite? -1 : 1; - // Both are (non-)favourites: sort by name - return a.display_name.collate (b.display_name); + // Both are (non-)favourites: sort by either first name or surname (user preference) + unowned string? a_name = this.settings.sort_on_surname? try_get_surname(a) : a.display_name; + unowned string? b_name = this.settings.sort_on_surname? try_get_surname(b) : b.display_name; + + return a_name.collate (b_name); + } + + private unowned string try_get_surname (Individual indiv) { + if (indiv.structured_name != null && indiv.structured_name.family_name != "") + return indiv.structured_name.family_name; + + // Fall back to the display_name + return indiv.display_name; } private void update_header (ListBoxRow row, ListBoxRow? before) { diff --git a/src/contacts-list-pane.vala b/src/contacts-list-pane.vala index 2c60e15..9f4d3f1 100644 --- a/src/contacts-list-pane.vala +++ b/src/contacts-list-pane.vala @@ -48,7 +48,7 @@ public class Contacts.ListPane : Frame { public signal void delete_contacts (LinkedList<Contact> contacts); public signal void contacts_marked (int contacts_marked); - public ListPane (Store contacts_store) { + public ListPane (Settings settings, Store contacts_store) { this.store = contacts_store; this.notify["state"].connect (on_ui_state_changed); @@ -60,7 +60,7 @@ public class Contacts.ListPane : Frame { // Load the ContactsView and connect the necessary signals - this.contacts_list = new ContactList (contacts_store, this.filter_query); + this.contacts_list = new ContactList (settings, contacts_store, this.filter_query); bind_property ("state", this.contacts_list, "state", BindingFlags.BIDIRECTIONAL | BindingFlags.SYNC_CREATE); this.contacts_list_container.add (this.contacts_list); diff --git a/src/contacts-settings.vala b/src/contacts-settings.vala index bfb11b8..1327f2d 100644 --- a/src/contacts-settings.vala +++ b/src/contacts-settings.vala @@ -18,15 +18,19 @@ /** * Provides a convenient interface to deal with the settings. */ -public class Contacts.Settings { - private GLib.Settings settings; +public class Contacts.Settings : GLib.Settings { public bool did_initial_setup { - get { return settings.get_boolean ("did-initial-setup"); } - set { settings.set_boolean ("did-initial-setup", value); } + get { return get_boolean ("did-initial-setup"); } + set { set_boolean ("did-initial-setup", value); } + } + + public bool sort_on_surname { + get { return get_boolean ("sort-on-surname"); } + set { set_boolean ("sort-on-surname", value); } } public Settings (App app) { - this.settings = new GLib.Settings (app.application_id); + Object (schema_id: app.application_id); } } diff --git a/src/contacts-window.vala b/src/contacts-window.vala index 1b25885..a43a268 100644 --- a/src/contacts-window.vala +++ b/src/contacts-window.vala @@ -40,6 +40,10 @@ public class Contacts.Window : Gtk.ApplicationWindow { [GtkChild] private Button select_cancel_button; [GtkChild] + private MenuButton hamburger_menu_button; + [GtkChild] + private RadioButton sort_on_surname_button; + [GtkChild] private ToggleButton favorite_button; private bool ignore_favorite_button_toggled; [GtkChild] @@ -55,17 +59,25 @@ public class Contacts.Window : Gtk.ApplicationWindow { public UiState state { get; set; default = UiState.NORMAL; } + private Settings settings; + public Store store { get; construct set; } - public Window (App app, Store contacts_store) { + public Window (Settings settings, App app, Store contacts_store) { Object ( application: app, show_menubar: false, store: contacts_store ); + this.settings = settings; + this.sort_on_surname_button.active = this.settings.sort_on_surname; + this.sort_on_surname_button.toggled.connect (() => { + this.settings.sort_on_surname = this.sort_on_surname_button.active; + }); + this.notify["state"].connect (on_ui_state_changed); create_contact_pane (); @@ -90,7 +102,7 @@ public class Contacts.Window : Gtk.ApplicationWindow { if (list_pane != null) return; - list_pane = new ListPane (store); + list_pane = new ListPane (this.settings, store); bind_property ("state", this.list_pane, "state", BindingFlags.BIDIRECTIONAL | BindingFlags.SYNC_CREATE); list_pane.selection_changed.connect (list_pane_selection_changed_cb); list_pane.link_contacts.connect (list_pane_link_contacts_cb); @@ -117,6 +129,7 @@ public class Contacts.Window : Gtk.ApplicationWindow { private void on_ui_state_changed (Object obj, ParamSpec pspec) { // UI when we're not editing of selecting stuff this.add_button.visible + = this.hamburger_menu_button.visible = this.right_header.show_close_button = (this.state == UiState.NORMAL || this.state == UiState.SHOWING); diff --git a/src/org.gnome.Contacts.gschema.xml b/src/org.gnome.Contacts.gschema.xml index 568e6ce..98d2f4e 100644 --- a/src/org.gnome.Contacts.gschema.xml +++ b/src/org.gnome.Contacts.gschema.xml @@ -5,5 +5,13 @@ <summary>First-time setup done.</summary> <description>Set to true after the user has run the first-time setup wizard.</description> </key> + <key name="sort-on-surname" type="b"> + <default>false</default> + <summary>Sort contacts on surname.</summary> + <description> + If this is set to true, the list of contacts will be sorted on their surnames. + Otherwise, it will be sorted on the first names of the contacts. + </description> + </key> </schema> </schemalist> |