diff options
author | Niels De Graef <nielsdegraef@gmail.com> | 2022-07-24 13:33:04 +0200 |
---|---|---|
committer | Niels De Graef <nielsdegraef@gmail.com> | 2022-07-24 13:57:25 +0200 |
commit | f677414715d5a79c0d88a9833690e5b8f6e5254a (patch) | |
tree | ff0df4f115c8be4f318d36d6d36bd6575e4a1f4b | |
parent | 200bc934b6938cabd97f7a90624b5e0fd9d9307c (diff) | |
download | gnome-contacts-f677414715d5a79c0d88a9833690e5b8f6e5254a.tar.gz |
Add a preferences window
This allows us to simplify the main menu, as well as having an easy
way in the future to add extra options.
-rw-r--r-- | data/contacts.gresource.xml | 2 | ||||
-rw-r--r-- | data/icons/scalable/actions/external-link-symbolic.svg | 72 | ||||
-rw-r--r-- | data/ui/contacts-accounts-list.ui | 16 | ||||
-rw-r--r-- | data/ui/contacts-main-window.ui | 11 | ||||
-rw-r--r-- | data/ui/contacts-preferences-window.ui | 10 | ||||
-rw-r--r-- | po/POTFILES.in | 2 | ||||
-rw-r--r-- | po/POTFILES.skip | 1 | ||||
-rw-r--r-- | src/contacts-accounts-list.vala | 47 | ||||
-rw-r--r-- | src/contacts-addressbook-dialog.vala | 7 | ||||
-rw-r--r-- | src/contacts-app.vala | 38 | ||||
-rw-r--r-- | src/contacts-preferences-window.vala | 78 | ||||
-rw-r--r-- | src/contacts-utils.vala | 6 | ||||
-rw-r--r-- | src/meson.build | 1 |
13 files changed, 196 insertions, 95 deletions
diff --git a/data/contacts.gresource.xml b/data/contacts.gresource.xml index 533e3d0..89c8052 100644 --- a/data/contacts.gresource.xml +++ b/data/contacts.gresource.xml @@ -14,7 +14,6 @@ <file preprocess="xml-stripblanks">icons/scalable/actions/website-symbolic.svg</file> <file compressed="true" preprocess="xml-stripblanks">gtk/help-overlay.ui</file> - <file compressed="true" preprocess="xml-stripblanks">ui/contacts-accounts-list.ui</file> <file compressed="true" preprocess="xml-stripblanks">ui/contacts-avatar-selector.ui</file> <file compressed="true" preprocess="xml-stripblanks">ui/contacts-contact-pane.ui</file> <file compressed="true" preprocess="xml-stripblanks">ui/contacts-crop-dialog.ui</file> @@ -22,6 +21,7 @@ <file compressed="true" preprocess="xml-stripblanks">ui/contacts-link-suggestion-grid.ui</file> <file compressed="true" preprocess="xml-stripblanks">ui/contacts-linked-personas-dialog.ui</file> <file compressed="true" preprocess="xml-stripblanks">ui/contacts-main-window.ui</file> + <file compressed="true" preprocess="xml-stripblanks">ui/contacts-preferences-window.ui</file> <file compressed="true" preprocess="xml-stripblanks">ui/contacts-setup-window.ui</file> </gresource> </gresources> diff --git a/data/icons/scalable/actions/external-link-symbolic.svg b/data/icons/scalable/actions/external-link-symbolic.svg index 1ac7ee7..74f85c3 100644 --- a/data/icons/scalable/actions/external-link-symbolic.svg +++ b/data/icons/scalable/actions/external-link-symbolic.svg @@ -1,11 +1,61 @@ -<?xml version="1.0" encoding="UTF-8"?> -<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg"> - <g fill="#2e3436"> - <path d="m 2 3 v 11 h 11 v -4 h -2 v 2 h -7 v -7 h 2 v -2 z m 0 0"/> - <path d="m 9 2 c -0.550781 0 -1 0.449219 -1 1 s 0.449219 1 1 1 h 3 v 3 c 0 0.550781 0.449219 1 1 1 s 1 -0.449219 1 -1 v -4 c 0 -0.550781 -0.449219 -1 -1 -1 z m 0 0"/> - <path d="m 13 2 h 1 v 1 h -1 z m 0 0"/> - <path d="m 12.292969 2.289062 l -4.5 4.46875 c -0.390625 0.390626 -0.390625 1.027344 0 1.414063 c 0.390625 0.394531 1.023437 0.394531 1.414062 0.007813 l 4.5 -4.46875 c 0.390625 -0.390626 0.390625 -1.027344 0 -1.414063 c -0.386719 -0.394531 -1.019531 -0.394531 -1.414062 -0.007813 z m 0 0"/> - <path d="m 13 7 h 1 v 1 h -1 z m 0 0"/> - <path d="m 8 2 h 1 v 1 h -1 z m 0 0"/> - </g> -</svg> +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg height="16px" viewBox="0 0 16 16" width="16px" version="1.1" id="svg89887" sodipodi:docname="external-link-symbolic.svg" inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"> + <defs id="defs89891"/> + <sodipodi:namedview id="namedview89889" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:showpageshadow="2" inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" showgrid="true" inkscape:zoom="14.75" inkscape:cx="4.4067797" inkscape:cy="6.2372881" inkscape:current-layer="svg89887"> + <inkscape:grid type="xygrid" id="grid90073"/> + </sodipodi:namedview> + <filter id="a" height="1" width="1" x="0" y="0"> + <feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0" id="feColorMatrix89780"/> + </filter> + <mask id="b"> + <g filter="url(#a)" id="g89785"> + <rect fill-opacity="0.55" height="16" width="16" id="rect89783"/> + </g> + </mask> + <clipPath id="c"> + <rect height="152" width="192" id="rect89788"/> + </clipPath> + <mask id="d"> + <g filter="url(#a)" id="g89793"> + <rect fill-opacity="0.55" height="16" width="16" id="rect89791"/> + </g> + </mask> + <clipPath id="e"> + <rect height="152" width="192" id="rect89796"/> + </clipPath> + <mask id="f"> + <g filter="url(#a)" id="g89801"> + <rect fill-opacity="0.55" height="16" width="16" id="rect89799"/> + </g> + </mask> + <clipPath id="g"> + <rect height="152" width="192" id="rect89804"/> + </clipPath> + <mask id="h"> + <g filter="url(#a)" id="g89809"> + <rect fill-opacity="0.3" height="16" width="16" id="rect89807"/> + </g> + </mask> + <clipPath id="i"> + <rect height="152" width="192" id="rect89812"/> + </clipPath> + <mask id="j"> + <g filter="url(#a)" id="g89817"> + <rect fill-opacity="0.3" height="16" width="16" id="rect89815"/> + </g> + </mask> + <clipPath id="k"> + <rect height="152" width="192" id="rect89820"/> + </clipPath> + <mask id="l"> + <g filter="url(#a)" id="g89825"> + <rect fill-opacity="0.3" height="16" width="16" id="rect89823"/> + </g> + </mask> + <clipPath id="m"> + <rect height="152" width="192" id="rect89828"/> + </clipPath> + <path id="path193961" style="fill:#222222;fill-opacity:1" d="M 3,2 C 1.338,2 0,3.338 0,5 v 8 c 0,1.662 1.338,3 3,3 h 8 c 1.662,0 3,-1.338 3,-3 V 9 C 13.9998,8.4477 13.5522,8 13,8 12.4478,8 12.0002,8.4477 12,9 v 4 c 0,0.554 -0.446,1 -1,1 H 3 C 2.446,14 2,13.554 2,13 V 5 C 2,4.446 2.446,4 3,4 H 7 C 7.5523,4 8,3.5523 8,3 8,2.4477 7.5523,2 7,2 Z M 10,0 C 9.4477,0 9,0.4477 9,1 9,1.5523 9.4477,2 10,2 h 2.584 L 7.293,7.291 c -0.3917,0.3907 -0.3917,1.0253 0,1.416 0.3905,0.3904 1.0236,0.3904 1.4141,0 L 14,3.4141 V 6 c 0,0.5523 0.4477,1 1,1 0.5523,0 1,-0.4477 1,-1 V 1 C 15.9996,0.913 15.988,0.8262 15.965,0.7422 15.942,0.6572 15.909,0.576 15.865,0.5 15.822,0.424 15.768,0.3548 15.7068,0.293 15.6918,0.281 15.6758,0.269 15.6598,0.258 15.6048,0.208 15.5433,0.165 15.4782,0.1291 c -0.037,-0.019 -0.076,-0.035 -0.1152,-0.049 -0.051,-0.021 -0.1029,-0.037 -0.1563,-0.049 -0.04,-0.01 -0.08,-0.014 -0.1211,-0.018 -0.029,-0.01 -0.057,-0.01 -0.086,-0.012 z" sodipodi:nodetypes="sssssscscsssssssssscsscccccsssccscccccccc" inkscape:label="arrow box link external web http diagonal"> + <title id="title8267">external-link</title> + </path> +</svg>
\ No newline at end of file diff --git a/data/ui/contacts-accounts-list.ui b/data/ui/contacts-accounts-list.ui deleted file mode 100644 index b95ce63..0000000 --- a/data/ui/contacts-accounts-list.ui +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<interface> - <template class="ContactsAccountsList" parent="AdwBin"> - <style> - <class name="contacts-accounts-list"/> - </style> - <child> - <object class="GtkListBox" id="listbox"> - <property name="selection_mode">none</property> - <style> - <class name="boxed-list"/> - </style> - </object> - </child> - </template> -</interface> diff --git a/data/ui/contacts-main-window.ui b/data/ui/contacts-main-window.ui index 2e20f97..289c56c 100644 --- a/data/ui/contacts-main-window.ui +++ b/data/ui/contacts-main-window.ui @@ -16,17 +16,10 @@ </section> <section> <item> - <attribute name="label" translatable="yes">Change Address Book…</attribute> - <attribute name="action">app.change-book</attribute> + <attribute name="label" translatable="yes">Preferences</attribute> + <attribute name="action">app.show-preferences</attribute> </item> <item> - <attribute name="label" translatable="yes">Online Accounts <sup>↗</sup></attribute> - <attribute name="action">app.online-accounts</attribute> - <attribute name="use-markup">True</attribute> - </item> - </section> - <section> - <item> <attribute name="label" translatable="yes">Keyboard Shortcuts</attribute> <attribute name="action">win.show-help-overlay</attribute> </item> diff --git a/data/ui/contacts-preferences-window.ui b/data/ui/contacts-preferences-window.ui new file mode 100644 index 0000000..fc4d2b4 --- /dev/null +++ b/data/ui/contacts-preferences-window.ui @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <template class="ContactsPreferencesWindow" parent="AdwPreferencesWindow"> + <child> + <object class="AdwPreferencesPage" id="address_books_page"> + <property name="title" translatable="yes">Address Books</property> + </object> + </child> + </template> +</interface> diff --git a/po/POTFILES.in b/po/POTFILES.in index 36e9a36..4ce720e 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -11,6 +11,7 @@ data/ui/contacts-editor-menu.ui data/ui/contacts-link-suggestion-grid.ui data/ui/contacts-linked-personas-dialog.ui data/ui/contacts-main-window.ui +data/ui/contacts-preferences-window.ui data/ui/contacts-setup-window.ui src/contacts-accounts-list.vala src/contacts-addressbook-dialog.vala @@ -32,6 +33,7 @@ src/contacts-link-suggestion-grid.vala src/contacts-linked-personas-dialog.vala src/contacts-main-window.vala src/contacts-operation.vala +src/contacts-preferences-window.vala src/contacts-settings.vala src/contacts-setup-window.vala src/contacts-type-combo.vala diff --git a/po/POTFILES.skip b/po/POTFILES.skip index f5fcf7a..627134e 100644 --- a/po/POTFILES.skip +++ b/po/POTFILES.skip @@ -22,6 +22,7 @@ src/contacts-link-suggestion-grid.c src/contacts-linked-personas-dialog.c src/contacts-main-window.c src/contacts-operation.c +src/contacts-preferences-window.c src/contacts-settings.c src/contacts-setup-window.c src/contacts-type-combo.c diff --git a/src/contacts-accounts-list.vala b/src/contacts-accounts-list.vala index 202c160..db04cc9 100644 --- a/src/contacts-accounts-list.vala +++ b/src/contacts-accounts-list.vala @@ -25,14 +25,12 @@ using Folks; * * Internally, each "address book" is a {@link Folks.PersonaStore}. */ -[GtkTemplate (ui = "/org/gnome/Contacts/ui/contacts-accounts-list.ui")] -public class Contacts.AccountsList : Adw.Bin { - - [GtkChild] - private unowned Gtk.ListBox listbox; +public class Contacts.AccountsList : Adw.PreferencesGroup { private Gtk.SingleSelection selection; + private GenericArray<AddressbookRow> rows = new GenericArray<AddressbookRow> (); + /** The selected PersonaStore (or null if none) */ public PersonaStore? selected_store { get { return (PersonaStore) this.selection.selected_item; } @@ -47,32 +45,20 @@ public class Contacts.AccountsList : Adw.Bin { var model = new Gtk.FilterListModel (contacts_store.address_books, (owned) filter); + model.items_changed.connect (on_model_items_changed); + on_model_items_changed (model, 0, 0, model.get_n_items ()); + // Setup the selection model this.selection = new Gtk.SingleSelection (model); // Update the row when the selection model changes this.selection.selection_changed.connect ((sel, pos, n_items) => { for (uint i = pos; i < pos + n_items; i++) { - var row = (AddressbookRow?) this.listbox.get_row_at_index ((int) i); - if (row != null) - row.selected = this.selection.is_selected (i); + this.rows[i].selected = this.selection.is_selected (i); } notify_property ("selected-store"); }); - // Now bind the listbox to it - this.listbox.bind_model (model, (item) => { - unowned var persona_store = (PersonaStore) item; - var row = new AddressbookRow (persona_store); - - // Update the selection model when the row is activated - row.activated.connect ((row) => { - this.selection.set_selected ((uint) row.get_index ()); - }); - - return row; - }); - // Initially, the primary store (if set) is selected for (uint i = 0; i < model.get_n_items (); i++) { var persona_store = (PersonaStore) model.get_item (i); @@ -81,6 +67,25 @@ public class Contacts.AccountsList : Adw.Bin { } } + private void on_model_items_changed (ListModel model, uint pos, uint removed, uint added) { + for (uint i = pos; i < pos + removed; i++) { + remove (this.rows[i]); + this.rows.remove_index (i); + } + + for (uint i = pos; i < pos + added; i++) { + var persona_store = (PersonaStore) model.get_item(i); + var row = new AddressbookRow (persona_store); + add (row); + this.rows.add (row); + + // Update the selection model when the row is activated + row.activated.connect ((row) => { + this.selection.set_selected ((uint) row.get_index ()); + }); + } + } + private class AddressbookRow : Adw.ActionRow { public PersonaStore persona_store { get; construct set; } diff --git a/src/contacts-addressbook-dialog.vala b/src/contacts-addressbook-dialog.vala index 03b13b0..14d7153 100644 --- a/src/contacts-addressbook-dialog.vala +++ b/src/contacts-addressbook-dialog.vala @@ -74,10 +74,7 @@ public class Contacts.AddressbookDialog : Gtk.Dialog { return; unowned var e_store = (Edsf.PersonaStore) this.accounts_list.selected_store; - if (e_store != null) { - eds_source_registry.set_default_address_book (e_store.source); - var settings = new GLib.Settings ("org.freedesktop.folks"); - settings.set_string ("primary-store", "eds:%s".printf (e_store.id)); - } + if (e_store != null) + Utils.set_primary_store (e_store); } } diff --git a/src/contacts-app.vala b/src/contacts-app.vala index dcf3e6e..b127554 100644 --- a/src/contacts-app.vala +++ b/src/contacts-app.vala @@ -36,8 +36,7 @@ public class Contacts.App : Adw.Application { { "quit", quit_action }, { "help", show_help }, { "about", show_about }, - { "change-book", change_address_book }, - { "online-accounts", online_accounts }, + { "show-preferences", show_preferences }, { "show-contact", on_show_contact, "s"} }; @@ -121,30 +120,9 @@ public class Contacts.App : Adw.Application { dialog.show (); } - public void online_accounts () { - try { - var proxy = new DBusProxy.for_bus_sync (BusType.SESSION, - DBusProxyFlags.NONE, - null, - "org.gnome.Settings", - "/org/gnome/Settings", - "org.gtk.Actions"); - - var builder = new VariantBuilder (new VariantType ("av")); - builder.add ("v", new Variant.string ("")); - var param = new Variant.tuple ({ - new Variant.string ("launch-panel"), - new Variant.array (new VariantType ("v"), { - new Variant ("v", new Variant ("(sav)", "online-accounts", builder)) - }), - new Variant.array (new VariantType ("{sv}"), {}) - }); - - proxy.call_sync ("Activate", param, DBusCallFlags.NONE, -1); - } catch (Error e) { - // TODO: Show error dialog - warning ("Couldn't open online-accounts: %s", e.message); - } + public void show_preferences () { + var prefs_window = new PreferencesWindow (this.contacts_store, this.window); + prefs_window.show (); } public void show_help () { @@ -278,19 +256,15 @@ public class Contacts.App : Adw.Application { private void run_setup () { debug ("Running initial setup"); - // Disable change-book action (don't want the user to do that during setup) - unowned var change_book_action = lookup_action ("change-book") as SimpleAction; - change_book_action.set_enabled (false); - // Create and show the setup window var setup_window = new SetupWindow (this, this.contacts_store); setup_window.setup_done.connect ((selected_store) => { setup_window.destroy (); - eds_source_registry.set_default_address_book (selected_store.source); + unowned var edsf_store = (Edsf.PersonaStore) selected_store; + Utils.set_primary_store (edsf_store); this.settings.did_initial_setup = true; - change_book_action.set_enabled (true); // re-enable change-book action create_window (); }); setup_window.show (); diff --git a/src/contacts-preferences-window.vala b/src/contacts-preferences-window.vala new file mode 100644 index 0000000..e6abbd2 --- /dev/null +++ b/src/contacts-preferences-window.vala @@ -0,0 +1,78 @@ +/* + * 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; + +[GtkTemplate (ui = "/org/gnome/Contacts/ui/contacts-preferences-window.ui")] +public class Contacts.PreferencesWindow : Adw.PreferencesWindow { + + [GtkChild] + private unowned Adw.PreferencesPage address_books_page; + + public PreferencesWindow (Store contacts_store, Gtk.Window? transient_for) { + Object (transient_for: transient_for, search_enabled: false); + + var acc_list = new AccountsList (contacts_store); + acc_list.title = _("Primary Address Book"); + acc_list.description = _("New contacts will be added to the selected address book. You are able to view and edit contacts from other address books."); + this.address_books_page.add (acc_list); + + acc_list.notify["selected-store"].connect ((obj, pspec) => { + var edsf_store = (Edsf.PersonaStore) acc_list.selected_store; + Utils.set_primary_store (edsf_store); + }); + + var goa_button_content = new Adw.ButtonContent (); + goa_button_content.label = _("_Online Accounts"); + goa_button_content.use_underline = true; + goa_button_content.icon_name = "external-link-symbolic"; + var goa_button = new Gtk.Button (); + goa_button.set_child (goa_button_content); + goa_button.tooltip_text = _("Opens the Online Accounts panel in GNOME Settings"); + goa_button.margin_top = 36; + goa_button.halign = Gtk.Align.CENTER; + goa_button.add_css_class ("pill"); + goa_button.clicked.connect (on_goa_button_clicked); + acc_list.add (goa_button); + } + + private void on_goa_button_clicked (Gtk.Button goa_button) { + try { + var proxy = new DBusProxy.for_bus_sync (BusType.SESSION, + DBusProxyFlags.NONE, + null, + "org.gnome.Settings", + "/org/gnome/Settings", + "org.gtk.Actions"); + + var builder = new VariantBuilder (new VariantType ("av")); + builder.add ("v", new Variant.string ("")); + var param = new Variant.tuple ({ + new Variant.string ("launch-panel"), + new Variant.array (new VariantType ("v"), { + new Variant ("v", new Variant ("(sav)", "online-accounts", builder)) + }), + new Variant.array (new VariantType ("{sv}"), {}) + }); + + proxy.call_sync ("Activate", param, DBusCallFlags.NONE, -1); + } catch (Error e) { + // TODO: Show error dialog + warning ("Couldn't open online-accounts: %s", e.message); + } + } +} diff --git a/src/contacts-utils.vala b/src/contacts-utils.vala index a5c28c0..f5d6a66 100644 --- a/src/contacts-utils.vala +++ b/src/contacts-utils.vala @@ -29,6 +29,12 @@ namespace Contacts { namespace Contacts.Utils { + public void set_primary_store (Edsf.PersonaStore e_store) { + eds_source_registry.set_default_address_book (e_store.source); + var settings = new GLib.Settings ("org.freedesktop.folks"); + settings.set_string ("primary-store", "eds:%s".printf (e_store.id)); + } + public void compose_mail (string email) { var mailto_uri = "mailto:" + Uri.escape_string (email, "@" , false); Gtk.show_uri (null, mailto_uri, 0); diff --git a/src/meson.build b/src/meson.build index 1f3890e..c246b61 100644 --- a/src/meson.build +++ b/src/meson.build @@ -87,6 +87,7 @@ contacts_vala_sources = files( 'contacts-link-suggestion-grid.vala', 'contacts-linked-personas-dialog.vala', 'contacts-main-window.vala', + 'contacts-preferences-window.vala', 'contacts-settings.vala', 'contacts-setup-window.vala', 'contacts-type-combo.vala', |